diff --git a/driver-examples/mss-can/Jenkinsfile b/driver-examples/mss-can/Jenkinsfile
new file mode 100644
index 00000000..e98230e7
--- /dev/null
+++ b/driver-examples/mss-can/Jenkinsfile
@@ -0,0 +1,2 @@
+@Library('automated-testing-library') _
+pipelineBareMetalDriverExamples()
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-basic/.cproject b/driver-examples/mss-can/mpfs-can-basic/.cproject
new file mode 100644
index 00000000..01b27e9a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/.cproject
@@ -0,0 +1,1136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/.gitignore b/driver-examples/mss-can/mpfs-can-basic/.gitignore
new file mode 100644
index 00000000..65d718f0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/.gitignore
@@ -0,0 +1,8 @@
+/Debug*/
+/Release*/
+/core
+/LIM-Debug/
+/LIM-Release/
+/eNVM-Scratchpad-Release/
+/DDR-Release/
+/.settings/
diff --git a/driver-examples/mss-can/mpfs-can-basic/.project b/driver-examples/mss-can/mpfs-can-basic/.project
new file mode 100644
index 00000000..c4a92096
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/.project
@@ -0,0 +1,26 @@
+
+
+ mpfs-can-basic
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/README.md b/driver-examples/mss-can/mpfs-can-basic/README.md
new file mode 100644
index 00000000..613fca0c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/README.md
@@ -0,0 +1,84 @@
+# PolarFire SoC MSS Basic CAN example
+
+This example project demonstrates using the MSS CAN peripheral to perform CAN
+message transmission and reception. The MSS CAN driver has APIs for BasicCAN and
+FullCAN Configurations. This project is configured for BasicCAN communication.
+
+The operation of the MSS CAN is controlled via a serial console.
+
+## How to use this example
+
+On connecting Icicle kit J11 to the host PC, you should see 4 COM port interfaces.
+To use this project, configure the COM port **interface1** as below:
+ - 115200 baud
+ - 8 data bits
+ - 1 stop bit
+ - no parity
+ - no flow control
+
+This is a self contained example project. A greeting message is displayed
+over the UART terminal. On startup, the example project requests the user to
+enter the data to be send via the CAN Bus. You can enter up to 32 pairs of hex
+digits (no separating spaces) and the data will be sent out in chunks of 8
+bytes at a time in up to 4 CAN packets. You can send less than 32 bytes of
+data by pressing return to terminate the data early.
+
+The test program then enters a loop looking for user input to select the next
+action to perform. Whilst in this loop, the data portion of any CAN Bus packets
+received into the rx buffers is displayed on the console. The following menu
+options are available:
+
+ 0 - Perform a hardware reset of the MSS CAN peripheral via SYSREG. This
+ shuts down all CAN communications.
+ 5 - Reinitailze the MSS CAN peripheral then get data from user and send via
+ CAN Bus.
+ 7 - Get data from user and send via CAN Bus.
+
+The following macros modify the behaviour of the program:
+
+ CAN_TX_EXTENDED_ID - Defining this macro causes CAN messages with
+ with extended 29 bit IDs to be sent instead of
+ the standard 11 bit IDs.
+ CAN_TARGET_COCO_PC_ACTIVE - Defining this macro adjusts the baud rate to
+ enable reliable operation with the Kromschroder
+ CoCo PC Active CAN Bus interface.
+
+Note: Because the BasicCAN example program provides an ISR for the CAN_IRQ, the
+ following macros need to be defined in the project settings to ensure
+ interrupts are fully enabled and the default ISR in mss_can.c is disabled:
+
+ MSS_CAN_ENABLE_INTERRUPTS
+ MSS_CAN_USER_ISR
+
+Jumper settings:
+Connect CAN-0 and PCAN as mentioned below:
+
+ | CAN-0 J27 | PCAN | Description |
+ |---------------|--------- |--------------|
+ | 1 | 7 | CAN_H |
+ | 2 | 2 | CAN_L |
+ | 3 | 6 | GND |
+
+## Test CAN Message Transmission
+ 1. Enter the data on UART terminal, which will be received through MSSUART1.
+ 2. Based on received data bytes, segregate as CAN messages of maximum 8
+ bytes length.
+ 3. Send the received data in terms of CAN messages.
+ 4. Observe the CAN messages on CAN Analyzer with message identifier as 0x78.
+ 5. Compare the data received on CAN Analyzer with the data sent from the
+ UART terminal data should be same.
+
+## Test CAN Message Reception
+ 1. Send the 8 bytes of CAN message from CAN Analyzer with message identifier
+ as 0x200.
+ 2. Read the data using CAN APIs and store it in to RAM buffer.
+ 3. Transmit the data using MSSUART1 on to UART terminal.
+ 4. Observe the data received on UART terminal.
+ 5. Compare the data sent from CAN Analyzer with the data received on
+ UART terminal data should be same.
+
+This project provides build configurations and debug launchers as exaplained
+[here](https://github.com/polarfire-soc/polarfire-soc-bare-metal-examples/blob/main/README.md)
+
+The design description file with this clock setting is available at ./src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
+This project can be tested with standard Libero reference design. However, please make sure that the input clock to MSS CAN block is set to 8MHz in xml.
diff --git a/driver-examples/mss-can/mpfs-can-basic/mpfs-can-basic hw all-harts attach.launch b/driver-examples/mss-can/mpfs-can-basic/mpfs-can-basic hw all-harts attach.launch
new file mode 100644
index 00000000..7e8f7906
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/mpfs-can-basic hw all-harts attach.launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/mpfs-can-basic hw all-harts debug.launch b/driver-examples/mss-can/mpfs-can-basic/mpfs-can-basic hw all-harts debug.launch
new file mode 100644
index 00000000..4ec3efe6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/mpfs-can-basic hw all-harts debug.launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/application/hart0/e51.c b/driver-examples/mss-can/mpfs-can-basic/src/application/hart0/e51.c
new file mode 100644
index 00000000..a14b792a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/application/hart0/e51.c
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on E51.
+ *
+ * Please refer to README.md file for more details
+ */
+
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h0 = 0U;
+
+/* Main function for the hart0(E51 processor).
+ * Application code running on hart1 is placed here
+ *
+ * The hart1 is in WFI while booting, hart0 brings it out of WFI when it raises
+ * the first Software interrupt.
+ */
+void e51(void)
+{
+ uint8_t flag = 0u;
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ (void)mss_config_clk_rst(MSS_PERIPH_MMUART0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+
+ MSS_UART_init( &g_mss_uart0_lo,
+ MSS_UART_115200_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx_string(&g_mss_uart0_lo ,
+ (const uint8_t*)"\r\nPlease observe UART-1 for application messages\r\n");
+
+ /* Raise software interrupt to wake hart 1 */
+ raise_soft_interrupt(1U);
+
+ __enable_irq();
+
+ while (1U)
+ {
+ icount++;
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ }
+ }
+ /* never return */
+}
+
+/* hart0 Software interrupt handler */
+void Software_h0_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h0++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/application/hart1/u54_1.c b/driver-examples/mss-can/mpfs-can-basic/src/application/hart1/u54_1.c
new file mode 100644
index 00000000..126fac1b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/application/hart1/u54_1.c
@@ -0,0 +1,590 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_1
+ *
+ * PolarFire SoC MSS CAN example demonstrating the data transmission and
+ * reception using MSSCAN.
+ * For Transmission: Get data from UART terminal using
+ * MSS UART1 --> Form as CAN packets --> Send to CAN Analyzer.
+ * For Reception: Send the CAN Message from
+ * CAN Analyzer --> Read the Message --> Send to UART terminal using MSS UART1.
+ * To know more about how to use this project, please refer README.md in this
+ * project's folder.
+ *
+ */
+
+/*----------------------------------------------------------------------------
+ * Include files
+ */
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "drivers/mss/mss_can/mss_can.h"
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+/*------------------------------------------------------------------------------
+ * Macros.
+ */
+#define ENTER 0x0DU
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ */
+static void display_greeting(void);
+static uint8_t get_data_frm_uart(void);
+static void display_hex_values(const uint8_t *, uint32_t);
+static void ascii_to_hex(uint8_t *, uint32_t );
+static void display_option(void);
+static void check_rx_buffer(void);
+
+/*------------------------------------------------------------------------------
+ * Static Variables.
+ */
+static uint8_t g_uart_to_can[32];
+static uint8_t g_temp[64];
+static uint8_t g_can_to_uart[8];
+
+/*------------------------------------------------------------------------------
+ * Global Variables.
+ */
+mss_can_filterobject pfilter;
+mss_can_msgobject pmsg;
+mss_can_msgobject rx_buf;
+mss_can_rxmsgobject rx_msg;
+
+/*------------------------------------------------------------------------------
+ * MSS UART instance for UART1
+ */
+mss_uart_instance_t *g_uart= &g_mss_uart1_lo;
+mss_can_instance_t* g_mss_can_0 = &g_mss_can_0_lo;
+
+/* Main function for the HART1(U54_1 processor).
+ * Application code running on HART1 is placed here
+ *
+ * The HART1 goes into WFI. HART0 brings it out of WFI when it raises the first
+ * Software interrupt to this HART
+ */
+void u54_1(void)
+{
+ volatile uint8_t ret_status = 0xFFU;
+ volatile uint8_t count = 0u;
+ int32_t error_flag;
+ int8_t rx_bytes = 0u;
+ uint8_t no_of_msgs = 0u;
+ size_t rx_size;
+ uint8_t rx_char;
+ uint8_t loop_count;
+ uint32_t msg_len;
+ uint32_t chunk_size;
+ uint8_t init_return_value = 0u;
+
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+#endif
+
+ /* The hart is out of WFI, clear the SW interrupt. Here onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ (void)mss_config_clk_rst(MSS_PERIPH_MMUART1, (uint8_t) 1, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_CAN0, (uint8_t) 1, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_CAN1, (uint8_t) 1, PERIPHERAL_ON);
+
+ PLIC_DisableIRQ(CAN0_PLIC);
+ PLIC_DisableIRQ(CAN1_PLIC);
+
+ PLIC_init();
+ __enable_irq();
+
+ MSS_UART_init(g_uart,
+ MSS_UART_115200_BAUD,
+ (MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY |
+ MSS_UART_ONE_STOP_BIT));
+
+ /*--------------------------------------------------------------------------
+ * Performs CAN Initialization and Message Buffer Configuration
+ */
+ /* ----------------------- CAN - 0 Initialization ----------------- */
+ init_return_value = MSS_CAN_init(g_mss_can_0, CAN_SPEED_8M_1M,
+ (pmss_can_config_reg)0, 6u, 6u);
+ MSS_CAN_set_mode(g_mss_can_0, CANOP_MODE_NORMAL);
+ MSS_CAN_start(g_mss_can_0);
+
+ pmsg.ID = 120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+#ifdef CAN_TX_EXTENDED_ID
+ pmsg.L =(CAN_TX_INT_EBL| CAN_EXT_IDE| 0x00080000 | CAN_TX_WPNL_EBL);
+#else
+ pmsg.L =(CAN_TX_INT_EBL| 0x00080000 | CAN_TX_WPNL_EBL);
+#endif
+ /* Configure for receive */
+ pfilter.ACR.L = 0x00000000 ;
+ pfilter.AMR.L = 0xFFFFFFFF;
+ pfilter.AMCR_D.MASK = 0xFFFF;
+ pfilter.AMCR_D.CODE = 0x00;
+
+ MSS_CAN_config_buffer(g_mss_can_0, &pfilter);
+
+ /* Display greeting message */
+ display_greeting();
+
+ /*
+ * Enable Interrupts for CAN
+ */
+ MSS_CAN_set_int_ebl(g_mss_can_0,
+ (CAN_INT_ACK_ERR | CAN_INT_TX_MSG | CAN_INT_GLOBAL
+ | CAN_INT_RX_MSG | CAN_INT_BUS_OFF | CAN_INT_BIT_ERR
+ | CAN_INT_OVR_LOAD | CAN_INT_FORM_ERR | CAN_INT_CRC_ERR
+ | CAN_INT_RX_MSG_LOST | CAN_INT_RTR_MSG |
+ CAN_INT_STUCK_AT_0 | CAN_INT_STUFF_ERR |
+ CAN_INT_SST_FAILURE | CAN_INT_ARB_LOSS));
+
+ while (1)
+ {
+ /*----------------------------------------------------------------------
+ * Read the Data from UART and Transmit using CAN
+ */
+ rx_bytes = get_data_frm_uart();
+
+ /* Convert ASCII values to Hex */
+ ascii_to_hex(g_temp, rx_bytes);
+
+ for (loop_count = 0u; loop_count < rx_bytes / 2u; loop_count++)
+ {
+ g_uart_to_can[loop_count] = g_temp[loop_count * 2u];
+ g_uart_to_can[loop_count] = g_uart_to_can[loop_count] << 4u;
+ g_uart_to_can[loop_count] |= g_temp[(loop_count * 2u) + 1u];
+ }
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\rData transmitted as CAN Message ");
+ display_hex_values(g_uart_to_can, loop_count);
+
+ /*------------------------------------------------------------------
+ * Identify the number of messages to transmit based on rx_bytes
+ */
+ no_of_msgs = rx_bytes / 16u;
+ if ((rx_bytes % 16u) != 0u)
+ {
+ no_of_msgs = no_of_msgs + 1u;
+ }
+
+ if (0u == loop_count) /* Allow sending an empty packet */
+ {
+ no_of_msgs = 1u;
+ }
+
+ count = 0u;
+
+ msg_len = loop_count;
+ error_flag = 0u;
+ while ((no_of_msgs != 0u) && (0u == error_flag))
+ {
+ /* Pack up to 8 bytes into this packet in 2 x 32bit chunks */
+ if (msg_len >= 8u)
+ {
+ chunk_size = 8u;
+ }
+ else
+ {
+ chunk_size = msg_len;
+ }
+
+ for (loop_count = 0u; loop_count < chunk_size; loop_count++)
+ {
+ if (loop_count < 4u)
+ {
+ pmsg.DATA[3u - loop_count] = \
+ g_uart_to_can[loop_count +(count * 8u)];
+ }
+ else
+ {
+ pmsg.DATA[11u - loop_count] = \
+ g_uart_to_can[loop_count +(count * 8u)];
+ }
+ }
+
+ pmsg.DLC = chunk_size;
+ ret_status = MSS_CAN_send_message(g_mss_can_0, &pmsg);
+ if (CAN_VALID_MSG != ret_status)
+ {
+ error_flag = 1u; /* Didn't succeed in sending packet... */
+ }
+ else
+ {
+ no_of_msgs--;
+ msg_len -= chunk_size;
+ count++;
+ }
+ }
+
+ if (0u == count) /* Nothing sent */
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rUnable to send data via CAN Bus");
+ }
+ else
+ {
+ if (0u == error_flag) /* Everything sent */
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rObserve the data received on CAN Analyzer");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rIt should be same as the data transmitted from UART terminal");
+ }
+ else /* Some error occurred */
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rObserve the data Received on CAN Analyzer");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rSome transmission error(s) were detected.");
+ }
+ }
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r------------------------------------------------------------------------------");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\rPress any key to continue...");
+
+ do {
+ rx_size = MSS_UART_get_rx(g_uart, &rx_char, sizeof(rx_char));
+ } while (rx_size == 0u);
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+
+ /*----------------------------------------------------------------------
+ * Display options
+ */
+ display_option();
+ }
+
+}
+
+
+static void check_rx_buffer(void)
+{
+ uint8_t loop_count;
+
+ /*----------------------------------------------------------------------
+ * Read the Data from CAN channel and transmit through UART
+ */
+ if (CAN_VALID_MSG == MSS_CAN_get_message_av(g_mss_can_0))
+ {
+ MSS_CAN_get_message(g_mss_can_0, &rx_buf);
+ for (loop_count = 0u; loop_count < rx_buf.DLC; loop_count++)
+ {
+ if (loop_count < 4u)
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[3u - loop_count];
+ }
+ else
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[11u - loop_count];
+ }
+ }
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************************************************************************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rData Received as CAN Message is ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+
+ /* Send to UART */
+ display_hex_values(g_can_to_uart, rx_buf.DLC);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rObserve the message sent from the CAN Analyzer ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rIt should be same as message Received on UART terminal");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************************************************************************\n\r");
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Receive data from UART terminal.
+ */
+static uint8_t get_data_frm_uart(void)
+{
+ uint8_t complete = 0;
+ uint8_t rx_buff[1];
+ uint8_t count = 0;
+ uint8_t rx_size = 0;
+
+ for (count = 0u; count < 32u; count++)
+ {
+ g_uart_to_can[count] = 0u;
+ }
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rEnter the data to transmit through the CAN Channel:\n\r");
+
+ count = 0u;
+ while (!complete)
+ {
+ rx_size = MSS_UART_get_rx(g_uart, rx_buff, sizeof(rx_buff));
+ if (rx_size > 0u)
+ {
+ MSS_UART_polled_tx(g_uart, rx_buff, sizeof(rx_buff));
+
+ if (ENTER == rx_buff[0])
+ {
+ complete = 1u;
+ }
+ else
+ {
+ if (count % 2u == 0u)
+ {
+ g_temp[count] = rx_buff[0];
+ }
+ else
+ {
+ g_temp[count] = rx_buff[0];
+ }
+ count++;
+ }
+
+ if (64u == count)
+ {
+ complete = 1u;
+ }
+ }
+ }
+ return(count);
+}
+
+/*------------------------------------------------------------------------------
+ * Display greeting message when application is started.
+ */
+static void display_greeting(void)
+{
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************************************************************************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"********** PolarFire SoC MSS CAN Driver Example (BasicCAN Mode) **************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"******************************************************************************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Example project Demonstrates the using of MSS CAN Transmission and Reception \n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"------------------------------------------------------------------------------\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Read data from the UART1 and Transmit as CAN message using MSS CAN\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"------------------------------------------------------------------------------\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Receive the CAN Message from MSS CAN channel and send this to UART1\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"******************************************************************************\n\r");
+}
+
+/*------------------------------------------------------------------------------
+ * Display content of buffer passed as parameter as hex values.
+ */
+static void display_hex_values
+(
+ const uint8_t * in_buffer,
+ uint32_t byte_length
+)
+{
+ uint8_t display_buffer[128];
+ uint32_t inc;
+
+ if (0u == byte_length)
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+ }
+ else
+ {
+ if (byte_length > 16u)
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+ }
+
+ for (inc = 0u; inc < byte_length; ++inc)
+ {
+ if ((inc > 1u) && (0u == (inc % 16u)))
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+ }
+ snprintf((char *)display_buffer, sizeof(display_buffer), "%02x ", in_buffer[inc]);
+ MSS_UART_polled_tx_string(g_uart, display_buffer);
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Converts ASCII values to HEX values
+ */
+static void ascii_to_hex
+(
+ uint8_t * in_buffer,
+ uint32_t byte_length
+)
+{
+ uint32_t inc;
+
+ for (inc = 0u; inc < byte_length; inc++)
+ {
+ if ((in_buffer[inc] <= 0x39u) && (in_buffer[inc] >= 0x30u))
+ {
+ in_buffer[inc] = in_buffer[inc] - 0x30u;
+ }
+ else if ((in_buffer[inc] <= 0x5Au) && (in_buffer[inc] >= 0x41u))
+ {
+ in_buffer[inc] = 0x0Au + in_buffer[inc] - 0x41u;
+ }
+ else if ((in_buffer[inc] <= 0x7Au) && (in_buffer[inc] >= 0x61u))
+ {
+ in_buffer[inc] = 0x0au + (in_buffer[inc] - 0x61u);
+ }
+ else
+ {
+ ;/* Do Nothing. */
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Display the Option to continue or exit.
+ */
+static void display_option(void)
+{
+ uint8_t rx_size=0;
+ uint8_t rx_buff[1];
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************* Select the Option to proceed further *********************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Press Key '7' to send data.\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Press Key '5' to reinitalize MSS CAN device.\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Press Key '0' to reset the MSS CAN device using SYSREG.\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"******************************************************************************\n\r");
+ do
+ {
+ /* Start command line interface if any key is pressed. */
+ rx_size = MSS_UART_get_rx(g_uart, rx_buff, sizeof(rx_buff));
+ if (rx_size > 0u)
+ {
+ switch(rx_buff[0])
+ {
+ case '7':
+ break;
+
+ case '5':
+ MSS_CAN_init(g_mss_can_0, CAN_SPEED_16M_1M, (pmss_can_config_reg)0, 6u, 6u);
+ MSS_CAN_set_mode(g_mss_can_0, CANOP_MODE_NORMAL);
+ MSS_CAN_start(g_mss_can_0);
+ MSS_CAN_config_buffer(g_mss_can_0, &pfilter);
+ break;
+
+ case '0':
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rCAN Controller has been reset: \n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rNo more Data transfer through CAN: \n\r");
+ MSS_CAN_set_mode(g_mss_can_0, CANOP_SW_RESET);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rPress Key '5' to re-initialize the CAN Controller \n\r");
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ * Read the Data from CAN channel and Transmit Through UART1
+ */
+ check_rx_buffer();
+
+ }while ((rx_buff[0]!= '7') & (rx_buff[0]!= '5'));
+}
+
+/*------------------------------------------------------------------------------
+ * CAN interrupt service routine.
+ * This function will be called as a result of an CAN event occuring.
+ */
+#if defined(__GNUC__)
+__attribute__((__interrupt__)) void CAN_IRQHandler(void)
+#else
+void CAN_IRQHandler(void)
+#endif
+{
+ volatile uint32_t read_irq_state = 0u;
+
+ /* Read the status of Interrupt */
+ read_irq_state = MSS_CAN_get_int_status(g_mss_can_0);
+
+ if (0u != (read_irq_state | CAN_INT_ARB_LOSS))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_ARB_LOSS);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_OVR_LOAD))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_OVR_LOAD);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_BIT_ERR))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_BIT_ERR);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_STUFF_ERR))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_STUFF_ERR);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_ACK_ERR))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_ACK_ERR);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_FORM_ERR))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_FORM_ERR);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_CRC_ERR))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_CRC_ERR);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_BUS_OFF))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_BUS_OFF);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_RX_MSG_LOST))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_RX_MSG_LOST);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_TX_MSG))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_TX_MSG);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_RX_MSG))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_RX_MSG);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_RTR_MSG))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_RTR_MSG);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_STUCK_AT_0))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_STUCK_AT_0);
+ /* Application specific implementation */
+ }
+
+ else if (0u != (read_irq_state | CAN_INT_SST_FAILURE))
+ {
+ MSS_CAN_clear_int_status(g_mss_can_0, CAN_INT_SST_FAILURE);
+ /* Application specific implementation */
+ }
+ else
+ {
+ ;/* No Error. */
+ }
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/application/hart2/u54_2.c b/driver-examples/mss-can/mpfs-can-basic/src/application/hart2/u54_2.c
new file mode 100644
index 00000000..2e8c0501
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/application/hart2/u54_2.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_2
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h2 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart2(U54_2 processor).
+ * Application code running on hart2 is placed here
+ *
+ * The hart2 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart
+ */
+void u54_2(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart2 Software interrupt handler */
+void Software_h2_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h2++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/application/hart3/u54_3.c b/driver-examples/mss-can/mpfs-can-basic/src/application/hart3/u54_3.c
new file mode 100644
index 00000000..2ec3349a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/application/hart3/u54_3.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_3
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h3 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart3(U54_3 processor).
+ * Application code running on hart3 is placed here
+ *
+ * The hart3 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart.
+ */
+void u54_3(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ }while(0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart3 software interrupt handler */
+void Software_h3_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h3++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/application/hart4/u54_4.c b/driver-examples/mss-can/mpfs-can-basic/src/application/hart4/u54_4.c
new file mode 100644
index 00000000..d70724e8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/application/hart4/u54_4.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_4
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h4 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart4(U54_4 processor).
+ * Application code running on hart4 is placed here
+ *
+ * The hart4 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart.
+ */
+void u54_4(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart4 software interrupt handler */
+void Software_h4_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h4++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/application/inc/common.h b/driver-examples/mss-can/mpfs-can-basic/src/application/inc/common.h
new file mode 100644
index 00000000..80c76203
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/application/inc/common.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef COMMON_H_
+#define COMMON_H_
+
+#include
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+typedef enum COMMAND_TYPE_
+{
+ CLEAR_COMMANDS = 0x00, /*!< 0 default behavior */
+ START_HART1_U_MODE = 0x01, /*!< 1 u mode */
+ START_HART2_S_MODE = 0x02, /*!< 2 s mode */
+} COMMAND_TYPE;
+
+
+typedef enum MODE_CHOICE_
+{
+ M_MODE = 0x00, /*!< 0 m mode */
+ S_MODE = 0x01, /*!< s mode */
+} MODE_CHOICE;
+
+
+typedef struct HART_SHARED_DATA_
+{
+ uint64_t init_marker;
+ volatile long mutex_uart0;
+ mss_uart_instance_t *g_mss_uart0_lo;
+} HART_SHARED_DATA;
+
+/**
+ * extern variables
+ */
+
+/**
+ * functions
+ */
+void jump_to_application(HLS_DATA* hls, MODE_CHOICE mode_choice, uint64_t next_addr);
+void
+uart_tx_with_mutex
+(
+ mss_uart_instance_t * this_uart,
+ uint64_t mutex_addr,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+void
+uart_tx_string_with_mutex
+(
+ mss_uart_instance_t * this_uart,
+ uint64_t mutex_addr,
+ const uint8_t * pbuff
+);
+
+#endif /* COMMON_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
new file mode 100644
index 00000000..7e0a4bc5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
@@ -0,0 +1,4024 @@
+
+
+ 2021.1
+ ICICLE_MSS
+ MPFS250T_ES
+ FCVG484
+ 06-22-2021_18:26:34
+ 0.5.3
+
+
+
+
+
+
+ 0x1
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0xB
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x4
+
+
+
+
+
+
+ 0x00
+ 0x0
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+
+
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0
+
+
+ 220
+
+
+ 0
+
+
+ 511
+
+
+
+
+
+
+
+
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0xF
+ 0xF
+
+
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+
+
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0xC
+ 0xC
+ 0x8
+ 0x8
+
+
+ 0x2
+ 0x2
+ 0x2
+ 0x2
+ 0x7
+ 0x7
+ 0x7
+ 0xF
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xD
+ 0x00
+ 0xA
+ 0x0
+ 0x4
+ 0x0
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x7
+ 0x00
+ 0x9
+ 0x0
+ 0x8
+ 0x0
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x3F
+ 0x00
+ 0x3F
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x3F
+ 0x00
+ 0x3F
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x2
+ 0x9
+ 0x1
+ 0x1
+ 0x00
+ 0x1
+ 0x1
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x14
+ 0x0
+ 0x2
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x7
+ 0x7
+ 0x7
+ 0x0
+ 0x0
+ 0x0
+ 0x4
+ 0x7
+ 0x7
+ 0x3
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x7
+ 0x7
+ 0x7
+ 0x0
+ 0x0
+ 0x0
+ 0x4
+ 0x7
+ 0x7
+ 0x3
+ 0x0
+
+
+ 0x8
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x0
+
+
+
+
+
+
+
+
+
+
+ 0x0
+ 0x3
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0xf000
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x0
+ 0x0
+
+
+ 0xFF000000
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x2
+ 0x5
+ 0x0
+ 0x7F
+ 0x1F
+
+
+ 0x02
+
+
+
+
+
+
+ 0x2
+ 0x2
+ 0x1
+ 0x0
+ 0xC
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x6
+
+
+ 0x6
+
+
+ 0x2
+
+
+ 0x2
+
+
+ 0x5
+
+
+ 0x5
+
+
+ 0x7
+
+
+ 0x7
+
+
+ 0x7
+
+
+ 0x3
+
+
+ 0x4
+
+
+ 0x3
+
+
+ 0x4
+
+
+ 0x8000
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+
+
+
+
+ 0x4
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x2
+ 0x2
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x4
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x7F80
+ 0x0
+ 0x1
+
+
+ 0x7030
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x7FB0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x1
+
+
+ 0x7FA0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+
+
+ 0x00001D
+
+
+ 0x00000000
+
+
+ 0x00000004
+
+
+ 0x0000000A
+
+
+ 0x00C2CA
+
+
+ 0x0
+
+
+ 0x9140F38D
+
+
+ 0x75955134
+
+
+ 0x71B69961
+
+
+ 0x000
+
+
+ 0x440C2040
+
+
+ 0x02481C61
+
+
+ 0x00000000
+
+
+ 0x00000140
+
+
+ 0x000000A0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x6
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x00000001
+
+
+ 0x00000016
+
+
+ 0x00000016
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000005
+
+
+ 0x00000006
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000004
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000006
+
+
+ 0x00000036
+
+
+ 0x00000036
+
+
+ 0x00000036
+
+
+ 0x0
+
+
+ 0x81881881
+
+
+ 0x00008818
+
+
+ 0xa92a92a9
+
+
+ 0x00002a92
+
+
+ 0xc28c28c2
+
+
+ 0x00008c28
+
+
+ 0xea2ea2ea
+
+
+ 0x00002ea2
+
+
+ 0x03903903
+
+
+ 0x00009039
+
+
+ 0x2b32b32b
+
+
+ 0x000032b3
+
+
+ 0x44944944
+
+
+ 0x00009449
+
+
+ 0x6c36c36c
+
+
+ 0x000036c3
+
+
+ 0x85985985
+
+
+ 0x00009859
+
+
+ 0xad3ad3ad
+
+
+ 0x00003ad3
+
+
+ 0xc69c69c6
+
+
+ 0x00009c69
+
+
+ 0xee3ee3ee
+
+
+ 0x00003ee3
+
+
+ 0x07a07a07
+
+
+ 0x0000a07a
+
+
+ 0x2f42f42f
+
+
+ 0x000042f4
+
+
+ 0x48a48a48
+
+
+ 0x0000a48a
+
+
+ 0x70470470
+
+
+ 0x00004704
+
+
+ 0x00000000
+
+
+ 0x00000048
+
+
+ 0x0000002C
+
+
+ 0x00000020
+
+
+ 0x00000004
+
+
+ 0x00000010
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x22
+
+
+ 0xF
+
+
+ 0x8
+
+
+ 0x11
+
+
+ 0x33
+
+
+ 0x20
+
+
+ 0x130
+
+
+ 0x8
+
+
+ 0x10
+
+
+ 0x8
+
+
+ 0x0
+
+
+ 0x6
+
+
+ 0x1F
+
+
+ 0x5
+
+
+ 0xF
+
+
+ 0xF
+
+
+ 0xF
+
+
+ 0x1F
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x7
+
+
+ 0xC
+
+
+ 0x0
+
+
+ 0x6
+
+
+ 0x0
+
+
+ 0x2
+
+
+ 0x0
+
+
+ 0xC34
+
+
+ 0x27100
+
+
+ 0xA
+
+
+ 0x10
+
+
+ 0x3
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0xC
+
+
+ 0x5
+
+
+ 0x00000200
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x27100
+
+
+ 0x0
+
+
+ 0x400
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x640
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x28
+
+
+ 0x8
+
+
+ 0xA
+
+
+ 0x00000000
+
+
+ 0x8
+
+
+ 0xE
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x2
+
+
+ 0x4
+
+
+ 0x18
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x320
+
+
+ 0x12
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000008
+
+
+ 0x0000000b
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x000000FF
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x15
+
+
+ 0x6
+
+
+ 0x3
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x7FFFFFFF
+
+
+ 0x0
+
+
+ 0x7FFFFFFF
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x8001
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x3F
+
+
+ 0x3F
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x18
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+
+
+
+
+
+
+ 125000000
+
+
+ 600000000
+
+
+ 600000000
+
+
+ 1000000
+
+
+ 300000000
+
+
+ 150000000
+
+
+
+
+
+
+ 0x0
+ 0x1
+ 0x2
+
+
+ 0x7D
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x40
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x5
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x4B
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x60
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x2
+ 0x4
+ 0x6
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x14
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ DDR3
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x5
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x80
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x8
+ 0x10
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x0
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+ 0x3
+ 0x0
+ 0x7
+ 0x0
+ 0xF
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt
new file mode 100644
index 00000000..d05a6a92
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt
@@ -0,0 +1,5 @@
+contains user configuration of the drivers.
+drivers config should follow the following format:
+platform/config/drivers//_sw_cfg.h
+e.g
+platform/config/drivers/ddr/ddr_sw_cfg.h
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld
new file mode 100644
index 00000000..2ab464f3
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-ddr-loaded-by-boot-loader.ld
+ * Use this linker script when the program is fully located in DDR. The
+ * assumption is DDR has already been initialized by another program.
+ * This linker script can be used with a debugger or when compiled and loaded
+ * by a boot-loader.
+ * Please see the project mpfs-hal-run-from-ddr-1 located in the Bare Metal
+ * library under examples/mpfs-hal for an example of it use.
+ * https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+HEAP_SIZE = 0k; /* needs to be calculated for your application if using */
+
+/*
+ * Stack size for our single hart U54 application.
+ */
+STACK_SIZE_U54_APPLICATION = 8k;
+
+/*
+ * A small amount of unitialised memory used to store information
+ * obtained from the boot-loader on start-up
+ */
+UNITITALISED_MEM = 16B;
+
+/* reset address 0xC0000000 */
+SECTION_START_ADDRESS = 0x80000000;
+
+
+SECTIONS
+{
+
+ /* text: test code section */
+ . = SECTION_START_ADDRESS;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > ddr_cached_32bit
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> ddr_cached_32bit
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > ddr_cached_32bit
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > ddr_cached_32bit
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > ddr_cached_32bit
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__app_stack_bottom = .);
+ . += STACK_SIZE_U54_APPLICATION;
+ PROVIDE(__app_stack_top = .);
+ } > ddr_cached_32bit
+
+ /*
+ * used by a program loaded by a bootloader to store information passed
+ * from boot-loader
+ * a0 holds the hart ID
+ * a1 hold pointer to device data, which includes pointer to shared memory
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .no_init : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ . += UNITITALISED_MEM;
+ PROVIDE(__uninit_top_h$ = .);
+ /*
+ * following not used but need to be provided for compilation
+ */
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__stack_top_h0$ = .);
+ PROVIDE(__stack_top_h1$ = .);
+ PROVIDE(__stack_top_h2$ = .);
+ PROVIDE(__stack_top_h3$ = .);
+ PROVIDE(__stack_top_h4$ = .);
+ } > ddr_cached_32bit
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..45b2bba6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma-envm.ld
+ * Code starts from eNVM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * The startup stack size is used on start-up.
+ * The application stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >envm
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> envm /* On the MPFS for startup code use, >switch_code AT>envm */
+}
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld
new file mode 100644
index 00000000..cf28ec03
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_envm.ld
+ * Use with Bare metal startup code.
+ * Startup code runs from envm on MSS reset
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+STACK_SIZE_PER_HART = 8k;
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ /* *entry.o(.text); */
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > envm
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> envm
+
+ /*
+ * The .ram_code section will contain the code that is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code_dtim AT>envm
+
+ /*
+ * The .ddr_code section will contain the code that is run from DDR.
+ * This is to verify DDR working as expeted
+ */
+ .ddr_code :
+ {
+ . = ALIGN (4);
+ __ddr_load = LOADADDR (.ram_code);
+ __ddr_start = .;
+ *(.ddr_codetext) /* .ram_codetext sections (code) */
+ *(.ddr_codetext*) /* .ram_codetext* sections (code) */
+ *(.ddr_coderodata) /* read-only data (constants) */
+ *(.ddr_coderodata*)
+ . = ALIGN (4);
+ __ddr_end = .;
+ } >ddr_cached_32bit AT>envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set
+ point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing.
+ Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim AT > envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim AT > envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary (0x1000) - corresponds to page size, when using
+ memory mem */
+ /* protection */
+ /* .stack : ALIGN(0x1000) */
+ .stack : ALIGN(0x10)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ /* place __start_of_free_lim$ after last allocation of l2_lim */
+ . = ALIGN(0x10);
+ PROVIDE(__start_of_free_lim$ = .);
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..98a7dace
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld
@@ -0,0 +1,388 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ * Code starts from LIM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * The startup stack size is used on start-up.
+ * The application stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __l2lim_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >l2lim
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> l2lim
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>envm */
+
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld
new file mode 100644
index 00000000..fd4ed76a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_lim.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+/* STACK_SIZE_PER_HART = 8k; */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+ /* text: text code section */
+ . = __l2lim_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ . = ALIGN(0x10);
+ } > l2lim
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ . = ALIGN (0x10);
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> l2lim
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including eNVM clock.
+ * This can not be done when running from eNVM
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>eNVM */
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h
new file mode 100644
index 00000000..fdf65956
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * Platform definitions
+ * Version based on requirements of MPFS MSS
+ *
+ */
+ /*========================================================================*//**
+ @mainpage Sample file detailing how mss_sw_config.h should be constructed for
+ the MPFS MSS
+
+ @section intro_sec Introduction
+ The mss_sw_config.h has the default software configuration settings for the
+ MPFS HAL and will be located at
+ /src/platform/platform_config_reference folder of the bare
+ metal SoftConsole project. The platform_config_reference is provided as a
+ default reference configuration.
+ When you want to configure the MPFS HAL with required configuration for
+ your project, the mss_sw_config.h must be edited and be placed in the
+ following project directory:
+ /src/boards//platform_config/mpfs_hal_config/
+
+ @section
+
+*//*==========================================================================*/
+
+
+#ifndef MSS_SW_CONFIG_H_
+#define MSS_SW_CONFIG_H_
+
+/*
+ * MPFS_HAL_FIRST_HART and MPFS_HAL_LAST_HART defines are used to specify which
+ * harts to actually start. The value and the actual hart it represents are
+ * listed below:
+ * value hart
+ * 0 E51
+ * 1 U54_1
+ * 2 U54_2
+ * 3 U54_3
+ * 4 U54_4
+ * Set MPFS_HAL_FIRST_HART to a value greater than 0 if you do not want your
+ * application to start and execute code on the harts represented by smaller
+ * value numbers.
+ * Set MPFS_HAL_LAST_HART to a value smaller than 4 if you do not wish to use
+ * all U54_x harts.
+ * Harts that are not started will remain in an infinite WFI loop unless used
+ * through some other method.
+ * The value of MPFS_HAL_FIRST_HART must always be less than MPFS_HAL_LAST_HART.
+ * The value of MPFS_HAL_LAST_HART must never be greater than 4.
+ * A typical use-case where you set MPFS_HAL_FIRST_HART = 1 and
+ * MPFS_HAL_LAST_HART = 1 is when
+ * your application is running on U54_1 and a bootloader running on E51 loads
+ * your application to the target memory and kicks-off U54_1 to run it.
+ */
+#ifndef MPFS_HAL_FIRST_HART
+#define MPFS_HAL_FIRST_HART 1
+#endif
+
+#ifndef MPFS_HAL_LAST_HART
+#define MPFS_HAL_LAST_HART 1
+#endif
+
+/*
+ * IMAGE_LOADED_BY_BOOTLOADER
+ * We set IMAGE_LOADED_BY_BOOTLOADER = 0 if the application image runs from
+ * non-volatile memory after reset. (No previous stage bootloader is used.)
+ * Set IMAGE_LOADED_BY_BOOTLOADER = 1 if the application image is loaded by a
+ * previous stage bootloader.
+ *
+ * MPFS_HAL_HW_CONFIG is defined if we are a boot-loader. This is a
+ * conditional compile switch is used to determine if MPFS HAL will perform the
+ * hardware configurations or not.
+ * Defined => This program acts as a First stage bootloader and performs
+ * hardware configurations.
+ * Not defined => This program assumes that the hardware configurations are
+ * already performed (Typically by a previous boot stage)
+ *
+ * List of items initialised when MPFS_HAL_HW_CONFIG is enabled
+ * - load virtual rom (see load_virtual_rom(void) in system_startup.c)
+ * - l2 cache config
+ * - Bus error unit config
+ * - MPU config
+ * - pmp config
+ * - I/O, clock and clock mux's, DDR and SGMII
+ * - will start other harts, see text describing MPFS_HAL_FIRST_HART,
+ * MPFS_HAL_LAST_HART above
+ *
+ */
+#define IMAGE_LOADED_BY_BOOTLOADER 1
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+#define MPFS_HAL_HW_CONFIG
+#endif
+
+
+/*
+ * If you are using common memory for sharing across harts,
+ * uncomment #define MPFS_HAL_SHARED_MEM_ENABLED
+ * make sure common memory is allocated in the linker script
+ * See app_hart_common mem section in the example platform
+ * linker scripts.
+ */
+
+#define MPFS_HAL_SHARED_MEM_ENABLED
+
+
+/* define the required tick rate in Milliseconds */
+/* if this program is running on one hart only, only that particular hart value
+ * will be used */
+#define HART0_TICK_RATE_MS 5UL
+#define HART1_TICK_RATE_MS 5UL
+#define HART2_TICK_RATE_MS 5UL
+#define HART3_TICK_RATE_MS 5UL
+#define HART4_TICK_RATE_MS 5UL
+
+/*
+ * Define the size of the Hart Local Storage (HLS).
+ * In the MPFS HAL, we are using HLS for debug data storage during the initial
+ * boot phase.
+ * This includes the flags which indicate the hart state regarding boot state.
+ * The HLS will take memory from top of each stack allocated at boot time.
+ *
+ */
+#define HLS_DEBUG_AREA_SIZE 64
+
+/*
+ * Bus Error Unit (BEU) configurations
+ * BEU_ENABLE => Configures the events that the BEU can report. bit value
+ * 1= enabled, 0 = disabled.
+ * BEU_PLIC_INT => Configures which accrued events should generate an
+ * interrupt to the PLIC.
+ * BEU_LOCAL_INT => Configures which accrued events should generate a
+ * local interrupt to the hart on which the event accrued.
+ */
+#define BEU_ENABLE 0x0ULL
+#define BEU_PLIC_INT 0x0ULL
+#define BEU_LOCAL_INT 0x0ULL
+
+/*
+ * Clear memory on startup
+ * 0 => do not clear DTIM and L2
+ * 1 => Clears memory
+ * Note: If you are the zero stage bootloader, set this to one.
+ */
+#ifndef MPFS_HAL_CLEAR_MEMORY
+#define MPFS_HAL_CLEAR_MEMORY 1
+#endif
+
+/*
+ * Comment out the lines to disable the corresponding hardware support not required
+ * in your application.
+ * This is not necessary from an operational point of view as operation dictated
+ * by MSS configurator settings, and items are enabled/disabled by this method.
+ * The reason you may want to use below is to save code space.
+ */
+#define SGMII_SUPPORT
+#define DDR_SUPPORT
+#define MSSIO_SUPPORT
+
+/*
+ * DDR software options
+ */
+
+/*
+ * Debug DDR startup through a UART
+ * Comment out in normal operation. May be useful for debug purposes in bring-up
+ * of a new board design.
+ * See the weakly linked function setup_ddr_debug_port(mss_uart_instance_t * uart)
+ * If you need to edit this function, make another copy of the function in your
+ * application without the weak linking attribute. This copy will then get linked.
+ * */
+//#define DEBUG_DDR_INIT
+//#define DEBUG_DDR_RD_RW_FAIL
+//#define DEBUG_DDR_RD_RW_PASS
+//#define DEBUG_DDR_CFG_DDR_SGMII_PHY
+//#define DEBUG_DDR_DDRCFG
+
+
+/*
+ * The hardware configuration settings imported from Libero project get generated
+ * into /src/boards// folder.
+ * If you need to overwrite them for testing purposes, you can do so here.
+ * e.g. If you want change the default SEG registers configuration defined by
+ * LIBERO_SETTING_SEG0_0, define it here and it will take precedence.
+ * #define LIBERO_SETTING_SEG0_0 0x80007F80UL
+ *
+ */
+
+#endif /* USER_CONFIG_MSS_USER_CONFIG_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt
new file mode 100644
index 00000000..086c9f12
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt
@@ -0,0 +1,2 @@
+contains user configuration of the platform
+e.g. division of memory between harts etc.
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/middleware/config/readme.txt b/driver-examples/mss-can/mpfs-can-basic/src/middleware/config/readme.txt
new file mode 100644
index 00000000..95f6cb21
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/middleware/config/readme.txt
@@ -0,0 +1 @@
+contains files relating to configuration of third party modules
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/middleware/readme.txt b/driver-examples/mss-can/mpfs-can-basic/src/middleware/readme.txt
new file mode 100644
index 00000000..0ffaed97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/middleware/readme.txt
@@ -0,0 +1 @@
+contains files relating to third party modules
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_can/mss_can.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_can/mss_can.c
new file mode 100644
index 00000000..fb59df0a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_can/mss_can.c
@@ -0,0 +1,1049 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * PolarFire SoC Microprocessor Subsystem(MSS) CAN bare metal software driver
+ * implementation.
+ */
+
+
+/*******************************************************************************
+ * Include files
+ */
+#include "mpfs_hal/mss_hal.h"
+#include "mss_can.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * Macros
+ */
+#define CAN_ID_SHIFT 18u
+#define CAN_ERROR_STATUS_SHIFT 16u
+#define CAN_ERROR_STATUS_MASK 0x03u
+#define CAN_RX_GTE96_SHIFT 19u
+#define CAN_FLAG_MASK 0x01u
+#define CAN_ERROR_COUNT_SHIFT 8u
+#define CAN_ERROR_COUNT_MASK 0xFFu
+#define CAN_TXGTE96_SHIFT 18u
+#define CAN_INT_MASK 0xFFFFFFFCu
+#define ENABLE 1u
+#define DISABLE 0u
+#define SYSREG_CAN_SOFTRESET_MASK (uint32_t)(3 << 14u)
+
+/*******************************************************************************
+ * Instance definition
+ */
+mss_can_instance_t g_mss_can_0_lo;
+mss_can_instance_t g_mss_can_1_lo;
+mss_can_instance_t g_mss_can_0_hi;
+mss_can_instance_t g_mss_can_1_hi;
+
+static void global_init
+(
+ mss_can_instance_t* this_wd
+);
+
+/***************************************************************************//**
+ * MSS_CAN_init()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_init
+(
+ mss_can_instance_t* this_can,
+ uint32_t bitrate,
+ pmss_can_config_reg pcan_config,
+ uint8_t basic_can_rx_mb,
+ uint8_t basic_can_tx_mb
+)
+{
+ uint32_t temp;
+ uint8_t mailbox_number;
+ uint8_t ret_value;
+ mss_can_rxmsgobject canrxobj;
+
+ global_init(this_can);
+
+ /* Initialize the device structure */
+ this_can->basic_can_rx_mb = basic_can_rx_mb;
+ this_can->basic_can_tx_mb = basic_can_tx_mb;
+
+ /* Initialize the rx mailbox */
+ canrxobj.ID = 0u;
+ canrxobj.DATAHIGH = 0u;
+ canrxobj.DATALOW = 0u;
+ canrxobj.AMR.L = 0u;
+ canrxobj.ACR.L = 0u;
+ canrxobj.AMR_D = 0u;
+ canrxobj.ACR_D = 0u;
+ canrxobj.RXB.L = (0u | CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL);
+
+ for (mailbox_number = 0u; mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ ret_value = MSS_CAN_config_buffer_n(this_can, mailbox_number,
+ &canrxobj);
+ }
+
+ /* Configure CAN controller */
+ if (CAN_SPEED_MANUAL == bitrate)
+ {
+ /*
+ * If user wants to specify registers directly Check if parameters
+ * meet minimums.
+ */
+ if (pcan_config->CFG_TSEG1 < 2u)
+ {
+ return (CAN_TSEG1_TOO_SMALL );
+ }
+
+ if ((pcan_config->CFG_TSEG2 == 0u) ||
+ ((pcan_config->SAMPLING_MODE == 1u) && (pcan_config->CFG_TSEG2
+ == 1u)))
+ {
+ return (CAN_TSEG2_TOO_SMALL);
+ }
+ temp = pcan_config->CFG_SJW;
+ if ((temp > pcan_config->CFG_TSEG1) ||
+ (temp > pcan_config->CFG_TSEG2))
+ {
+ return (CAN_SJW_TOO_BIG);
+ }
+
+ this_can->hw_reg->Config.L = pcan_config->L;
+ }
+ else
+ {
+ /* User has chosen a default setting. */
+ this_can->hw_reg->Config.L = bitrate;
+ }
+
+ /* Disable Interrupts */
+ this_can->hw_reg->IntEbl.L = DISABLE;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_config_reg()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_config_reg
+(
+ mss_can_instance_t* this_can,
+ uint32_t cfg
+)
+{
+ /* Clear all pending interrupts */
+ this_can->hw_reg->IntStatus.L = DISABLE;
+
+ /* Disable CAN Device */
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+
+ /* Disable receive interrupts. */
+ this_can->hw_reg->IntEbl.RX_MSG = DISABLE;
+
+ /* Disable interrupts from CAN device. */
+ this_can->hw_reg->IntEbl.INT_EBL = DISABLE;
+
+ /* Sets configuration bits */
+ this_can->hw_reg->Config.L = cfg;
+ MSS_CAN_start(this_can);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_mode()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_mode
+(
+ mss_can_instance_t* this_can,
+ mss_can_mode_t mode
+)
+{
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+ if (CANOP_SW_RESET == mode)
+ {
+ SYSREG->SOFT_RESET_CR |= SYSREG_CAN_SOFTRESET_MASK;
+ SYSREG->SOFT_RESET_CR &= ~SYSREG_CAN_SOFTRESET_MASK;
+ }
+ else
+ {
+ this_can->hw_reg->Command.L = (uint32_t)mode;
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_start()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_start
+(
+ mss_can_instance_t* this_can
+)
+{
+ /* Clear all pending interrupts*/
+ this_can->hw_reg->IntStatus.L = DISABLE;
+
+ /* Enable CAN Device*/
+ this_can->hw_reg->Command.RUN_STOP = ENABLE;
+
+ /* Enable CAN Interrupt at NVIC level- if supported */
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ if (if (&g_mss_can_0_lo == this_can) || (&g_mss_can_0_hi == this_can))
+ {
+ PLIC_DisableIRQ(CAN0_PLIC);
+ }
+ else
+ {
+ PLIC_DisableIRQ(CAN1_PLIC);
+ }
+#endif
+
+ /* Enable receive interrupts. */
+ this_can->hw_reg->IntEbl.RX_MSG = ENABLE;
+
+ /* Enable interrupts from CAN device.*/
+ this_can->hw_reg->IntEbl.INT_EBL = ENABLE;
+
+}
+
+/***************************************************************************//**
+ * MSS_CAN_stop()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_stop
+(
+ mss_can_instance_t* this_can
+)
+{
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_id()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_id
+(
+ pmss_can_msgobject pmsg
+)
+{
+ if (pmsg->IDE)
+ {
+ return (pmsg->ID);
+ }
+ else
+ {
+ return (pmsg->ID >> CAN_ID_SHIFT);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_id()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_set_id
+(
+ pmss_can_msgobject pmsg
+)
+{
+ if (pmsg->IDE)
+ {
+ return (pmsg->ID);
+ }
+ else
+ {
+ return (pmsg->ID << CAN_ID_SHIFT);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_msg_filter_mask()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_msg_filter_mask
+(
+ uint32_t id,
+ uint8_t ide,
+ uint8_t rtr
+)
+{
+ if (ide)
+ {
+ id <<= 3u;
+ }
+ else
+ {
+ id <<= 21;
+
+ /* Set unused ID bits to 1! */
+ id |= (0x3FFFF << 3u);
+ }
+ id |= ((uint32_t)(ide << 2u) | (uint32_t)(rtr << 1u));
+
+ return (id);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntEbl.L |= irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_clear_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_clear_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntEbl.L &= ~irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_global_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_global_int_ebl
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntEbl.INT_EBL);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_int_ebl
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntEbl.L & CAN_INT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_clear_int_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_clear_int_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntStatus.L = irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_int_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_int_status
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntStatus.L);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_rtr_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_set_rtr_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Is buffer configured for RTR auto-replay? */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRREPLY == 0u)
+ {
+ return (CAN_NO_RTR_MAILBOX);
+ }
+ else
+ {
+ /* Transfer the ID. */
+ this_can->hw_reg->RxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->RxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ return (CAN_OK);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rtr_message_abort_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_rtr_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ /* Mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Set abort request */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRABORT = 1u;
+
+ /* Check the abort is granted */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRREPLYPEND == 0u)
+ {
+ /* If the RX buffer isn't busy. Abort was successful */
+ return (CAN_OK);
+ }
+ else
+ {
+ /* Message not aborted.*/
+ return (CAN_ERR);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_config_buffer()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_config_buffer
+(
+ mss_can_instance_t* this_can,
+ pmss_can_filterobject pfilter
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX - this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Set filters */
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = pfilter->ACR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = pfilter->AMR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = pfilter->AMCR_D.MASK;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = pfilter->AMCR_D.CODE;
+
+ /* Configure mailbox */
+ if (mailbox_number < (CAN_RX_MAILBOX - 1))
+ {
+ /* set link flag, if not last buffer */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L =
+ (CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL | \
+ CAN_RX_LINK_EBL);
+ }
+ else
+ {
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L =
+ (CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL);
+ }
+ success = CAN_OK;
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_config_buffer_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_config_buffer_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_rxmsgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Configure mailbox */
+ this_can->hw_reg->RxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->RxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = pmsg->ACR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = pmsg->AMR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = pmsg->AMR_D;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = pmsg->ACR_D;
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L = (pmsg->RXB.L | \
+ CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL);
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Check that a new message is available and get it */
+ if ((ENABLE == this_can->hw_reg->Command.RUN_STOP) &&
+ (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV))
+ {
+ /* Copy ID */
+ pmsg->ID = this_can->hw_reg->RxMsg[mailbox_number].ID;
+
+ /* Copy 4 of the data bytes */
+ pmsg->DATALOW = this_can->hw_reg->RxMsg[mailbox_number].DATALOW;
+
+ /* Copy the other 4 data bytes. */
+ pmsg->DATAHIGH = this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH;
+
+ /* Get DLC, IDE and RTR and time stamp. */
+ pmsg->L = this_can->hw_reg->RxMsg[mailbox_number].RXB.L;
+
+ /* Ack that it's been removed from the FIFO */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV = ENABLE;
+
+ /* And let app know there is a message. */
+ return (CAN_VALID_MSG);
+ }
+ else
+ {
+ return (CAN_NO_MSG);
+ }
+}
+
+/*******************************************************************************
+ * MSS_CAN_get_message()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX-this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Check that if there is a valid message */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV)
+ {
+ /* Copy ID */
+ pmsg->ID = this_can->hw_reg->RxMsg[mailbox_number].ID;
+
+ /* Copy 4 of the data bytes */
+ pmsg->DATALOW = this_can->hw_reg->RxMsg[mailbox_number].DATALOW;
+
+ /* Copy the other 4 data bytes.*/
+ pmsg->DATAHIGH = this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH;
+
+ /* Get DLC, IDE and RTR and time stamp.*/
+ pmsg->L = this_can->hw_reg->RxMsg[mailbox_number].RXB.L;
+
+ /* Ack that it's been removed from the FIFO */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV = ENABLE;
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_message_av()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message_av
+(
+ mss_can_instance_t* this_can
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX-this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Check that buffer is enabled and contains a message */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV)
+ {
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Can't send if device is disabled */
+ if (DISABLE == this_can->hw_reg->Command.RUN_STOP)
+ {
+ /* Message not sent. */
+ return (CAN_NO_MSG);
+ }
+
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_TX_MAILBOX - this_can->basic_can_tx_mb))
+ {
+ /* mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXREQ == 0u)
+ {
+ /* If the Tx buffer isn't busy.... */
+ this_can->hw_reg->TxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->TxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->TxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L = (pmsg->L | \
+ CAN_TX_WPNH_EBL | \
+ CAN_TX_REQ);
+ return (CAN_VALID_MSG);
+ }
+ else
+ {
+ /* Message not sent. */
+ return (CAN_NO_MSG);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_abort_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_TX_MAILBOX - this_can->basic_can_tx_mb))
+ {
+ /* mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Set abort request */
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L =
+ ((this_can->hw_reg->TxMsg[mailbox_number].TXB.L & ~CAN_TX_REQ) | \
+ CAN_TX_ABORT);
+
+ /* Check the abort is granted */
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXABORT == 0u)
+ {
+ /* If the Tx buffer isn't busy, Abort was successful */
+ return (CAN_OK);
+ }
+ else
+ {
+ /* Message not aborted. */
+ return (CAN_ERR);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_ready()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_ready
+(
+ mss_can_instance_t* this_can
+)
+{
+ uint8_t success = CAN_ERR;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_tx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that is available */
+ for (mailbox_number = CAN_TX_MAILBOX-this_can->basic_can_tx_mb; \
+ mailbox_number < CAN_TX_MAILBOX; mailbox_number++)
+ {
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXREQ == 0u)
+ {
+ /* Tx buffer isn't busy */
+ success = CAN_OK;
+ break;
+ }
+ }
+
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_tx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that is available */
+ for (mailbox_number = CAN_TX_MAILBOX-this_can->basic_can_tx_mb; \
+ mailbox_number < CAN_TX_MAILBOX; mailbox_number++)
+ {
+ /* Check which transmit mailbox is not busy and use it. */
+ if ((MSS_CAN_get_tx_buffer_status(this_can) & (1u << mailbox_number))
+ == 0)
+ {
+ /* If the Tx buffer isn't busy.... */
+ this_can->hw_reg->TxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->TxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->TxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L = (pmsg->L | \
+ CAN_TX_WPNH_EBL | \
+ CAN_TX_REQ);
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_mask_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t *pamr,
+ uint32_t *pacr,
+ uint16_t *pdta_amr,
+ uint16_t *pdta_acr
+)
+{
+ if (mailbox_number >= CAN_RX_MAILBOX)
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ *pamr = this_can->hw_reg->RxMsg[mailbox_number].AMR.L;
+ *pacr = this_can->hw_reg->RxMsg[mailbox_number].ACR.L;
+ *pdta_acr = this_can->hw_reg->RxMsg[mailbox_number].ACR_D;
+ *pdta_amr = this_can->hw_reg->RxMsg[mailbox_number].AMR_D;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_mask_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_set_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t amr,
+ uint32_t acr,
+ uint16_t dta_amr,
+ uint16_t dta_acr
+)
+{
+ if (mailbox_number >= CAN_RX_MAILBOX)
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = amr;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = acr;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = (uint32_t)dta_amr;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = (uint32_t)dta_acr;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_buffer_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_buffer_status
+(
+ mss_can_instance_t* this_can
+)
+{
+#ifdef CANMOD3
+ return (this_can->hw_reg->BufferStatus.L & 0x0000FFFF);
+#else
+ return (this_can->hw_reg->BufferStatus.RXMSGAV);
+#endif
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_buffer_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_buffer_status
+(
+ mss_can_instance_t* this_can
+)
+{
+#ifdef CANMOD3
+ return ((this_can->hw_reg->BufferStatus.L >> 16u) & 0x00FF);
+#else
+ return (this_can->hw_reg->BufferStatus.TXREQ);
+#endif
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_error_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_error_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t *status
+)
+{
+ /* Supply error register info if user wants. */
+ *status = this_can->hw_reg->ErrorStatus.L;
+
+ /* 00 Error Active, 01 Error Passive, 1x Bus Off */
+ return ((uint8_t)(((*status) >> CAN_ERROR_STATUS_SHIFT) &
+ CAN_ERROR_STATUS_MASK));
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_error_count()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_error_count
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_ERROR_COUNT_SHIFT) & \
+ CAN_ERROR_COUNT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_gte96()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_gte96
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_RX_GTE96_SHIFT) & \
+ CAN_FLAG_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_error_count()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_error_count
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->ErrorStatus.L & CAN_ERROR_COUNT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_gte96 ()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_gte96
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_TXGTE96_SHIFT) & \
+ CAN_FLAG_MASK);
+}
+
+/*******************************************************************************
+ * Global initialization for all modes
+ */
+static void global_init
+(
+ mss_can_instance_t* this_wd
+)
+{
+ if (&g_mss_can_0_lo == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_0_LO_BASE;
+ this_wd->irqn = CAN0_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_1_lo == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_1_LO_BASE;
+ this_wd->irqn = CAN1_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_0_hi == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_0_HI_BASE;
+ this_wd->irqn = CAN0_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_1_hi == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_1_HI_BASE;
+ this_wd->irqn = CAN1_PLIC;
+ this_wd->int_type = 0;
+ }
+ else
+ {
+ ;/* LDRA Warning */
+ }
+}
+
+#ifndef MSS_CAN_USER_ISR
+/***************************************************************************//**
+ * CAN interrupt service routine.
+ * CAN_IRQHandler is included within the RISC-V vector table as part of the
+ * MPFS HAL.
+ */
+uint8_t External_can0_plic_IRQHandler(void)
+{
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ /* User provided code is required here to handle interrupts from the MSS CAN
+ * peripheral. Remove the assert once this is in place.*/
+ ASSERT(!"An ISR is required here if interrupts are enabled");
+#else
+ ASSERT(!"Unexpected MSS CAN interrupt - MSS CAN NVIC Interrupts should be \
+ disabled");
+#endif
+ return 0;
+}
+
+uint8_t can1_IRQHandler(void)
+{
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ /* User provided code is required here to handle interrupts from the MSS CAN
+ * peripheral. Remove the assert once this is in place.*/
+ ASSERT(!"An ISR is required here if interrupts are enabled");
+#else
+ ASSERT(!"Unexpected MSS CAN interrupt - MSS CAN NVIC Interrupts should be \
+ disabled");
+#endif
+ return 0;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_can/mss_can.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_can/mss_can.h
new file mode 100644
index 00000000..d4153c32
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_can/mss_can.h
@@ -0,0 +1,2430 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * PolarFire SoC Microprocessor Subsystem(MSS) CAN bare metal software driver
+ * public API.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire SoC MSS CAN Bare Metal Driver.
+
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor Subsystem (MSS) includes two CAN controller.
+ The CAN controller is configurable to provide support for up to 32 transmit
+ and 32 receive mailboxes.
+
+ This PolarFire SoC MSS CAN driver provides a set of functions for accessing
+ and controlling the MSS CAN as part of a bare metal system where no operating
+ system is available. The driver can be adapted for use as part of an
+ operating system, but the implementation of the adaptation layer between the
+ driver and the operating system's driver model is outside the scope of the
+ driver.
+
+ --------------------------------
+ Features
+ --------------------------------
+ The MSS CAN driver provides support for the following features:
+ - Basic CAN APIs if application needs support for Basic CAN operation.
+ (Configure as FIFO by linking several mailboxes together, one message
+ filter for entire FIFO)
+ - Full CAN APIs (each mail box has its own message filter)
+ - Support for 11 bit and 29 bit message identifiers
+ - Support for Data frame and Remote frames
+ - Error detection mechanism
+
+ ==============================================================================
+ Hardware Flow Dependencies
+ ==============================================================================
+ The configuration of all features of the PolarFire MSS CAN is covered by
+ this driver, with the exception of the PolarFire SoC IOMUX configuration.
+ The PolarFire SoC allows multiple non-concurrent uses of few external pins
+ through IOMUX configuration. This feature allows optimization of external pin
+ usage by assigning external pins for use by either the microprocessor
+ subsystem or the FPGA fabric. The MSS CAN serial signals are routed through
+ IOMUXs to the PolarFire SoC device external pins. The MSS CAN serial
+ signals can also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
+ For more information on IOMUX, refer to the I/O Configuration section of the
+ PolarFire SoC Microprocessor Subsystem (MSS) User's Guide.
+
+ The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
+ must ensure that the MSS CAN peripherals are enabled and configured in the
+ PolarFire SoC MSS configurator if you wish to use them. For more information
+ on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
+ Subsystem (MSS) User's Guide.
+
+ On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
+ masters and multiple slaves. Five RISC-V CPUs connect to the Master ports M10
+ to M14 of the AXI switch. By default, all the APB peripherals are accessible
+ on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB bridges
+ (referred as main APB bus). However, to support logical separation in the
+ Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals can
+ alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to APB
+ bridges (referred as the AMP APB bus).
+ Application must make sure that the desired CAN instance is appropriately
+ configured on one of the APB bus described above by configuring the PolarFire
+ SoC system registers (SYSREG) as per the application need and that the
+ appropriate data structures are provided to this driver as parameter to the
+ functions provided by this driver.
+
+ The base address and the register addresses are defined in this driver as
+ constants. The interrupt number assignment for the MSS CAN peripherals is
+ defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
+ is included in the project settings of the SoftConsole toolchain and that it
+ is generated into your project.
+
+ ==============================================================================
+ Theory of Operation
+ ==============================================================================
+ The MSS CAN driver uses one instance of the mss_can_instance_t structure per
+ port. This instance is used to identify the target port and a pointer to this
+ instance is passed as the first argument to all CAN driver functions.
+
+ The PolarFire SoC MSS CAN driver operations can be divided in following
+ sub-sections:
+ - CAN Controller Configuration
+ - Operation Status
+ - Interrupt Support
+ - Helper Functions
+ - Basic CAN Message Handling
+ - Full CAN Message Handling
+
+ --------------------------------
+ Configuration
+ --------------------------------
+ The MSS CAN driver must first be initialized and the mode of operation must
+ be selected before performing data transfers on CAN Bus. The MSS_CAN_init()
+ function is used to initialize the CAN controller and driver. Set CAN
+ controller operation mode as normal operation using MSS_CAN_set_mode()
+ function. The operating mode of operation is selected using
+ MSS_CAN_set_mode() function. The actual data transfer can be started using
+ start the CAN controller by using MSS_CAN_start() function, with this actual
+ data transmission or reception shall start. MSS_CAN_stop() function is used
+ to stops the CAN controller. Once initialized, during normal mode of
+ operation, the MSS CAN driver configuration can be changed using
+ MSS_CAN_set_config_reg() function is used to change the CAN controllers
+ configuration during normal operation.
+
+ --------------------------------
+ Operation Status
+ --------------------------------
+ MSS_CAN_get_error_status() function returns the current CAN error state
+ (error active, error passive, and bus off). The MSS_CAN_get_rx_error_count()
+ and MSS_CAN_get_tx_error_count() functions return the actual
+ receive and transmit error counter values while MSS_CAN_get_rx_gte96()
+ function and MSS_CAN_get_tx_gte96() function show if the error counters are
+ greater or equal to 96, which indicates a heavily disturbed bus.
+
+ --------------------------------
+ Interrupt Support
+ --------------------------------
+ The interrupt service routines are not part of the CAN driver. But access
+ functions for the interrupt registers are provided. The individual
+ interrupt enable bits can be set using MSS_CAN_set_int_ebl() function and
+ individual interrupt enable bits can be cleared using MSS_CAN_clear_int_ebl
+ while MSS_CAN_get_int_ebl() function returns their actual state.
+ MSS_CAN_get_global_int_ebl() function indicates if interrupt
+ generation is enabled at all. MSS_CAN_get_int_status() function shows the
+ current state of the different interrupt status bits. Each interrupt status
+ bit can be individually cleared using MSS_CAN_clear_int_status() function.
+
+ The interrupt service routines are not part of the MSS CAN driver and the
+ driver ships with the MSS_CAN_ENABLE_INTERRUPTS macro disabled which stops
+ the MSS CAN interrupt being enabled at the PLIC, however a stub ISR is
+ present in the mss_can.c file to show the format of the function and catch
+ any unexpected interrupts to aid in debugging.
+
+ --------------------------------
+ Helper Functions
+ --------------------------------
+ The MSS CAN peripheral expects all ID bits to be left aligned. This makes
+ setting the ID cumbersome. Using MSS_CAN_set_id(), a given right-aligned
+ ID field is modified according to the ID size which is indicated by the
+ IDE bit. MSS_CAN_get_id() provides the reverse operation: It returns the
+ ID right aligned. MSS_CAN_get_msg_filter_mask() packs the ID, IDE, and RTR
+ bits together as they are used in the mask registers. MSS_CAN_get_mask_n()
+ returns the message filter settings of the selected receive mailbox.
+ MSS_CAN_set_mask_n() configures the message filter settings for the
+ selected receive mailbox.
+
+ --------------------------------
+ Basic CAN Message Handling
+ --------------------------------
+ A Basic CAN type controller contains one or more message filter and one
+ common message buffer or FIFO. The CAN driver contains some functions to
+ emulate Basic CAN operation by linking several buffers together to form a
+ buffer array that shares one message filter. Since this buffer array is not
+ a real FIFO, message inversion might happen (eg, a newer message might be
+ pulled from the receive buffer prior to an older message).
+ Before using the Basic CAN API, the CAN controller has to be configured
+ first with a MSS_CAN_config_buffer() function call. This sets up the
+ message array and configures the message filter. MSS_CAN_send_message()
+ function and MSS_CAN_get_message() function are used to send and receive
+ a message from transmit or receive buffers. MSS_CAN_send_message_ready()
+ function indicates if a new message can be sent. MSS_CAN_get_message_av()
+ function shows if a new message is available.
+
+ --------------------------------
+ Full CAN Message Handling
+ --------------------------------
+ In Full CAN operation, each message mailbox has its own message filter.
+ This reduces the number of receive interrupts as the host CPU only gets an
+ interrupt when a message of interest has arrived. Further, software based
+ message filtering overhead is reduced and there is less message to
+ be checked. Before a buffer can be used for Full CAN operation, it needs to
+ be configured using MSS_CAN_config_buffer_n() function. An error is
+ generated if this buffer is already reserved for Basic CAN operation.
+ The MSS_CAN_get_rx_buffer_status() and MSS_CAN_get_tx_buffer_status()
+ functions indicate the current state of the receive and transmit buffers
+ respectively. With MSS_CAN_send_message_n() function a message can be sent
+ using buffer. A pending message transfer can be aborted with
+ MSS_CAN_send_message_abort_n() function and a message can be read with
+ MSS_CAN_get_message_n() function. If a buffer is set for automatic RTR reply,
+ MSS_CAN_set_rtr_message_n() function sets the CAN message that is returned
+ upon reception of the RTR message. MSS_CAN_get_rtr_message_abort_n()
+ function aborts a RTR message transmit request.
+
+ NOTE:
+ 1. User has to set the RTR message filter to match with
+ MSS_CAN_rtr_message_abort_n() function a pending RTR auto-reply can be
+ aborted.
+ 2. An error is generated if buffer is already reserved for Basic CAN
+ operation and is trying to use the same buffer for Full CAN functionality.
+ 3. Special case of Full CAN where several mailboxes are linked together to
+ create FIFOs that share an identical message filter configuration, can
+ be built upon the available Full CAN functions.
+
+ *//*=========================================================================*/
+
+#ifndef MSS_CAN_H_
+#define MSS_CAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following macro MSS_CAN_ENABLE_INTERRUPTS must be defined to allow the
+ * enabling of the MSS CAN peripheral interrupts at the PLIC level.
+ * This version of the MSS CAN driver does not provide any support for MSS CAN
+ * interrupts and so this MACRO should be disabled unless there is a user
+ * supplied ISR.
+ */
+
+#if 0
+#define MSS_CAN_ENABLE_INTERRUPTS
+#endif
+
+/**
+ * Define CAN target device
+ *
+ * CANMOD3: Device with 16 Rx and 8 Tx mailboxes
+ * CANMOD3X: Device with 32 Rx and 32 Tx mailboxes
+ */
+
+#define CANMOD3X
+
+#ifdef CANMOD3
+ #define CAN_RX_MAILBOX 16u
+ #define CAN_TX_MAILBOX 8u
+#else
+ #define CAN_RX_MAILBOX 32u
+ #define CAN_TX_MAILBOX 32u
+#endif
+
+
+/* Configuration and Speed definitions */
+#define CAN_PRESET (mss_can_config_reg.L)0
+#define CAN_SAMPLE_BOTH_EDGES 0x00000001u
+#define CAN_THREE_SAMPLES 0x00000002u
+#define CAN_SET_SJW(_sjw) (_sjw<<2u)
+#define CAN_AUTO_RESTART 0x00000010u
+#define CAN_SET_TSEG2(_tseg2) (_tseg2<<5u)
+#define CAN_SET_TSEG1(_tseg1) (_tseg1<<8u)
+#define CAN_SET_BITRATE(_bitrate) (_bitrate<<16u)
+#define CAN_ARB_ROUNDROBIN 0x00000000u
+#define CAN_ARB_FIXED_PRIO 0x00001000u
+#define CAN_BIG_ENDIAN 0x00000000u
+#define CAN_LITTLE_ENDIAN 0x00002000u
+
+/* Manual setting with specified fields */
+#define CAN_SPEED_MANUAL 0u
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used in the PolarFire SoC MSS CAN driver for
+ bitrate definitions:
+
+ | Constants | Description |
+ |--------------------|-----------------------------------------------------|
+ | CAN_SPEED_8M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 32MHz. |
+ | AN_SPEED_8M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 32MHz. |
+
+ */
+/* 5000m 81% Sample bit three times */
+#define CAN_SPEED_8M_5K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_5K CAN_SET_BITRATE(199)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_5K CAN_SET_BITRATE(399)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 5000m 81% Sample bit three times */
+#define CAN_SPEED_8M_10K CAN_SET_BITRATE(49)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_10K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_10K CAN_SET_BITRATE(199)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 2500m 81% Sample bit three times */
+#define CAN_SPEED_8M_20K CAN_SET_BITRATE(24)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_20K CAN_SET_BITRATE(49)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_20K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 1000m 87% */
+#define CAN_SPEED_8M_50K CAN_SET_BITRATE(9)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_50K CAN_SET_BITRATE(19)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_50K CAN_SET_BITRATE(39)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 600m 87% */
+#define CAN_SPEED_8M_100K CAN_SET_BITRATE(4)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_100K CAN_SET_BITRATE(9)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_100K CAN_SET_BITRATE(19)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 500m 87% */
+#define CAN_SPEED_8M_125K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_125K CAN_SET_BITRATE(7)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_125K CAN_SET_BITRATE(15)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 250m 87% */
+#define CAN_SPEED_8M_250K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_250K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_250K CAN_SET_BITRATE(7)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 100m 75% @ 8M, 87% @ 16M */
+#define CAN_SPEED_8M_500K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_500K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_500K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 25m 75% */
+#define CAN_SPEED_8M_1M CAN_SET_BITRATE(0)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_1M CAN_SET_BITRATE(1)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_1M CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_ERR | Indicates error condition |
+ | CAN_TSEG1_TOO_SMALL | Value provided to configure TSEG1 is too |
+ | | small |
+ | CAN_TSEG2_TOO_SMALL | Value provided to configure TSEG2 is too |
+ | | small |
+ | CAN_SJW_TOO_BIG | Value provided to configure synchronous jump|
+ | | width (SJW) is too big. |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+ | CAN_NO_RTR_MAILBOX | Indicates that there is no mailbox for |
+ | | remote transmit request (RTR) frame |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ */
+#define CAN_OK 0u
+#define CAN_ERR 1u
+#define CAN_TSEG1_TOO_SMALL 2u
+#define CAN_TSEG2_TOO_SMALL 3u
+#define CAN_SJW_TOO_BIG 4u
+#define CAN_BASIC_CAN_MAILBOX 5u
+#define CAN_NO_RTR_MAILBOX 6u
+#define CAN_INVALID_MAILBOX 7u
+
+/* Flag bits */
+#define CAN_NO_MSG 0x00u
+#define CAN_VALID_MSG 0x01u
+
+/*
+ * A couple of definitions just to make the code more readable so we know
+ * what a 1 and 0 mean.
+#define CAN_RTR 1<<21
+#define CAN_EXT_IDE 1<<20
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used in the MSS CAN driver for Interrupt Bit
+ Definitions
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ */
+#define CAN_INT_GLOBAL 1<<0 /* Global interrupt */
+#define CAN_INT_ARB_LOSS 1<<2 /* Arbitration loss interrupt */
+#define CAN_INT_OVR_LOAD 1<<3 /*Overload interrupt */
+#define CAN_INT_BIT_ERR 1<<4 /* Bit error interrupt */
+#define CAN_INT_STUFF_ERR 1<<5 /* Bit stuffing error interrupt */
+#define CAN_INT_ACK_ERR 1<<6 /* Acknowledgement error interrupt */
+#define CAN_INT_FORM_ERR 1<<7 /* Format error interrupt */
+#define CAN_INT_CRC_ERR 1<<8 /* CRC error interrupt */
+#define CAN_INT_BUS_OFF 1<<9 /* Bus-off interrupt */
+#define CAN_INT_RX_MSG_LOST 1<<10 /* Rx message lost interrupt */
+#define CAN_INT_TX_MSG 1<<11 /* Tx message interupt */
+#define CAN_INT_RX_MSG 1<<12 /* Rx message interrupt */
+#define CAN_INT_RTR_MSG 1<<13 /* RTR message interrupt */
+#define CAN_INT_STUCK_AT_0 1<<14 /* Stuck-at-0 error interrupt */
+#define CAN_INT_SST_FAILURE 1<<15 /* Single-shot transmission error interrupt*/
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for transmit message buffer control bit
+ definitions:
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_TX_WPNH_EBL | Indicates “WPNH” bit mask |
+ | CAN_TX_WPNL_EBL | Indicates WPNL bit mask |
+ | CAN_TX_REQ | Indicates transmit request flag bit position |
+ | CAN_TX_INT_EBL | Indicates transmit Interrupt enable bit mask |
+ | CAN_TX_ABORT | Indicates Transmit abort mask |
+
+ */
+#define CAN_TX_WPNH_EBL 1<<23
+#define CAN_TX_WPNL_EBL 1<<3
+#define CAN_TX_INT_EBL 1<<2
+#define CAN_TX_ABORT 1<<1
+#define CAN_TX_REQ 0x01u
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for receive message buffer control bit
+ definitions:
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_RX_WPNH_EBL | Indicates WPNH bit mask. |
+ | CAN_RX_WPNL_EBL | Indicates WPNL bit mask |
+ | CAN_RX_LINK_EBL | Indicates link flag bit mask |
+ | CAN_RX_INT_EBL | Indicates receive interrupt enable bit mask |
+ | CAN_RX_RTR_REPLY_EBL | Indicates RTR reply bit mask |
+ | CAN_RX_BUFFER_EBL | Indicates Transaction buffer enable bit mask |
+ | CAN_RX_RTR_ABORT | Indicates RTR abort request mask |
+ | CAN_RX_RTRP | Indicates RTReply pending status mask |
+ | CAN_RX_MSGAV | Indicates receive message available status mask|
+
+ */
+#define CAN_RX_WPNH_EBL 1<<23
+#define CAN_RX_WPNL_EBL 1<<7
+#define CAN_RX_LINK_EBL 1<<6
+#define CAN_RX_INT_EBL 1<<5
+#define CAN_RX_RTR_REPLY_EBL 1<<4
+#define CAN_RX_BUFFER_EBL 1<<3
+#define CAN_RX_RTR_ABORT 1<<2
+#define CAN_RX_RTRP 1<<1
+#define CAN_RX_MSGAV 0x01
+
+/*-------------------------------------------------------------------------*//**
+ The mss_can_mode_t enumeration specifies the possible operating modes of CAN
+ controller. The meaning of the constants is as described below
+
+ | Modes | Description |
+ |----------------------------|------------------------------------------|
+ | CANOP_MODE_NORMAL | Indicates CAN controller is in normal |
+ | | operational mode. |
+ | CANOP_MODE_LISTEN_ONLY | Indicates CAN controller is in listen |
+ | | only mode. |
+ | CANOP_MODE_EXT_LOOPBACK | Indicates CAN controller is in external |
+ | | loop back mode. |
+ | CANOP_MODE_INT_LOOPBACK | Indicates CAN controller is in internal |
+ | | loop back mode. |
+ | CANOP_SRAM_TEST_MODE | Indicates CAN controller is in test mode.|
+ | CANOP_SW_RESET | Indicates CAN controller is in stop mode.|
+
+ */
+typedef enum mss_can_mode
+{
+ CANOP_MODE_NORMAL = 0x01u,
+ CANOP_MODE_LISTEN_ONLY = 0x03u,
+ CANOP_MODE_EXT_LOOPBACK = 0x05u,
+ CANOP_MODE_INT_LOOPBACK = 0x07u,
+ CANOP_SRAM_TEST_MODE = 0x08u,
+ CANOP_SW_RESET = 0x10u
+} mss_can_mode_t;
+
+typedef struct _mss_can_msgobject
+{
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields. */
+ union
+ {
+ __IO uint32_t L; /* 32 bit flag */
+ struct
+ {
+ /* Flags structure. */
+ __IO uint32_t NA0:16;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:10;
+ };
+ };
+} mss_can_msgobject;
+
+typedef mss_can_msgobject * pmss_can_msgobject;
+
+/* _CAN_filterobject */
+
+typedef struct _CAN_filterobject
+{
+ /* Acceptance mask settings */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } AMR;
+
+ /* Acceptance code settings */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } ACR;
+
+ /* Acceptance mask and code settings for first two data bytes */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t MASK:16;
+ __IO uint32_t CODE:16;
+ };
+ } AMCR_D;
+} mss_can_filterobject;
+
+typedef mss_can_filterobject * pmss_can_filterobject;
+
+/*_CAN_txmsgobject */
+
+typedef struct _CAN_txmsgobject
+{
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields.*/
+ union
+ {
+ __IO uint32_t L;
+
+ /* Tx Flags structure. */
+ struct
+ {
+ __IO uint32_t TXREQ:1;
+ __IO uint32_t TXABORT:1;
+ __IO uint32_t TXINTEBL:1;
+ __IO uint32_t WPNL:1;
+ __IO uint32_t NA0:12;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:1;
+ __IO uint32_t WPNH:1;
+ __IO uint32_t NA2:8;
+ };
+ } TXB;
+
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+} mss_can_txmsgobject;
+
+/* _mss_can_rxmsgobject */
+
+typedef struct _mss_can_rxmsgobject
+{
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields. */
+ union
+ {
+ __IO uint32_t L; /* 32 bit flag */
+
+ /* Tx Flags structure. */
+ struct
+ {
+ __IO uint32_t MSGAV:1;
+ __IO uint32_t RTRREPLYPEND:1;
+ __IO uint32_t RTRABORT:1;
+ __IO uint32_t BUFFEREBL:1;
+ __IO uint32_t RTRREPLY:1;
+ __IO uint32_t RXINTEBL:1;
+ __IO uint32_t LINKFLAG:1;
+ __IO uint32_t WPNL:1;
+ __IO uint32_t NA0:8;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:1;
+ __IO uint32_t WPNH:1;
+ __IO uint32_t NA2:8;
+ };
+ } RXB;
+
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+ /* CAN Message Filter: Acceptance mask register */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } AMR;
+
+ /* CAN Message Filter: Acceptance code register */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } ACR;
+
+ __IO uint32_t AMR_D;
+ __IO uint32_t ACR_D;
+
+} mss_can_rxmsgobject;
+typedef mss_can_rxmsgobject * pmss_can_rxmsgobject;
+
+/* Error status register */
+typedef union error_status
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t TX_ERR_CNT:8;
+ __IO uint32_t RX_ERR_CNT:8;
+ __IO uint32_t ERROR_STAT:2;
+ __IO uint32_t TXGTE96:1;
+ __IO uint32_t RXGTE96:1;
+ __IO uint32_t N_A:12;
+ };
+} mss_can_error_status;
+
+/*
+ * Buffer status register For CANMOD3X,
+ * this are two 32-bit registers, for can, it is only one 32-bit register.
+ */
+#ifdef CANMOD3
+typedef union buffer_status
+{
+ __I uint32_t L;
+ struct
+ {
+ __I uint32_t RXMSGAV:16;
+ __I uint32_t TXREQ:8;
+ __I uint32_t N_A:8;
+ };
+#else
+typedef struct buffer_status
+{
+ __I uint32_t RXMSGAV;
+ __I uint32_t TXREQ;
+#endif
+} mss_can_buffer_status;
+
+/* Interrupt enable register */
+typedef union int_enable
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t INT_EBL:1;
+ __IO uint32_t N_A0:1;
+ __IO uint32_t ARB_LOSS:1;
+ __IO uint32_t OVR_LOAD:1;
+ __IO uint32_t BIT_ERR:1;
+ __IO uint32_t STUFF_ERR:1;
+ __IO uint32_t ACK_ERR:1;
+ __IO uint32_t FORM_ERR:1;
+ __IO uint32_t CRC_ERR:1;
+ __IO uint32_t BUS_OFF:1;
+ __IO uint32_t RX_MSG_LOSS:1;
+ __IO uint32_t TX_MSG:1;
+ __IO uint32_t RX_MSG:1;
+ __IO uint32_t RTR_MSG:1;
+ __IO uint32_t STUCK_AT_0:1;
+ __IO uint32_t SST_FAILURE:1;
+ __IO uint32_t N_A1:16;
+ };
+} mss_can_int_enable;
+
+typedef mss_can_int_enable * pmss_can_int_enable;
+
+/* Interrupt status register */
+typedef union int_status
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A0:2;
+ __IO uint32_t ARB_LOSS:1;
+ __IO uint32_t OVR_LOAD:1;
+ __IO uint32_t BIT_ERR:1;
+ __IO uint32_t STUFF_ERR:1;
+ __IO uint32_t ACK_ERR:1;
+ __IO uint32_t FORM_ERR:1;
+ __IO uint32_t CRC_ERR:1;
+ __IO uint32_t BUS_OFF:1;
+ __IO uint32_t RX_MSG_LOSS:1;
+ __IO uint32_t TX_MSG:1;
+ __IO uint32_t RX_MSG:1;
+ __IO uint32_t RTR_MSG:1;
+ __IO uint32_t STUCK_AT_0:1;
+ __IO uint32_t SST_FAILURE:1;
+ __IO uint32_t N_A1:16;
+ };
+} mss_can_int_status;
+typedef mss_can_int_status * pmss_can_int_status;
+
+/* Command register */
+typedef union command_reg
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t RUN_STOP:1;
+ __IO uint32_t LISTEN_ONLY:1;
+ __IO uint32_t LOOP_BACK:1;
+ __IO uint32_t SRAM_TEST:1;
+ __IO uint32_t SW_RESET:1;
+ __IO uint32_t N_A:27;
+ };
+} mss_can_command_reg;
+
+/* Configuration register */
+typedef union can_config_reg
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t EDGE_MODE:1;
+ __IO uint32_t SAMPLING_MODE:1;
+ __IO uint32_t CFG_SJW:2;
+ __IO uint32_t AUTO_RESTART:1;
+ __IO uint32_t CFG_TSEG2:3;
+ __IO uint32_t CFG_TSEG1:4;
+ __IO uint32_t CFG_ARBITER:1;
+ __IO uint32_t ENDIAN:1;
+ __IO uint32_t ECR_MODE:1;
+ __IO uint32_t N_A0:1;
+ __IO uint32_t CFG_BITRATE:15;
+ __IO uint32_t N_A1:1;
+ };
+} mss_can_config_reg;
+typedef mss_can_config_reg * pmss_can_config_reg ;
+
+/* Register mapping of CAN controller */
+typedef struct CAN_device
+{
+ mss_can_int_status IntStatus; /* Interrupt status register */
+ mss_can_int_enable IntEbl; /* Interrupt enable register */
+ mss_can_buffer_status BufferStatus; /* Buffer status indicators */
+ mss_can_error_status ErrorStatus; /* Error status */
+ mss_can_command_reg Command; /* CAN operating mode */
+ mss_can_config_reg Config; /* Configuration register */
+#ifdef CANMOD3
+ uint32_t NA[2];
+#else
+ uint32_t NA;
+#endif
+ mss_can_txmsgobject TxMsg[CAN_TX_MAILBOX]; /* Tx message buffers */
+ mss_can_rxmsgobject RxMsg[CAN_RX_MAILBOX]; /* Rx message buffers */
+
+} CAN_DEVICE;
+
+typedef CAN_DEVICE * PCAN_DEVICE;
+
+#define MSS_CAN_0_LO_BASE (CAN_DEVICE*)0x2010C000
+#define MSS_CAN_1_LO_BASE (CAN_DEVICE*)0x2010D000
+#define MSS_CAN_0_HI_BASE (CAN_DEVICE*)0x2810C000
+#define MSS_CAN_1_HI_BASE (CAN_DEVICE*)0x2810D000
+
+#define SYSREG_CAN_A_SOFTRESET_MASK ( (uint32_t)0x01u << 14u )
+#define SYSREG_CAN_B_SOFTRESET_MASK ( (uint32_t)0x01u << 15u )
+
+/*-------------------------------------------------------------------------*//**
+ The structure mss_can_instance_t is used by the driver to manage the
+ configuration and operation of each MSS CAN peripheral. The instance content
+ should only be accessed by using the respective API functions.
+
+ Each API function has a pointer to this instance as first argument.
+
+ */
+typedef struct can_instance
+{
+ /* Hardware related entries (pointer to device, interrupt number etc) */
+ CAN_DEVICE * hw_reg; /* Pointer to CAN registers. */
+ uint8_t irqn; /* refer to local or PLIC */
+ uint8_t int_type; /*!< 0 => local, 1 => PLIC */
+ /* Local data (eg pointer to local FIFO, irq number etc) */
+ uint8_t basic_can_rx_mb; /* number of rx mailboxes */
+ uint8_t basic_can_tx_mb; /* number of tx mailboxes */
+ } mss_can_instance_t;
+
+ /*------------------------------------------------------------------------*//**
+ This instances of mss_can_instance_t holds all data related to the operations
+ performed by CAN. A pointer to instance is passed as the first parameter
+ to CAN driver functions to indicate that which CAN instance should perform the
+ requested operation.
+ */
+extern mss_can_instance_t g_mss_can_0_lo;
+extern mss_can_instance_t g_mss_can_1_lo;
+extern mss_can_instance_t g_mss_can_0_hi;
+extern mss_can_instance_t g_mss_can_1_hi;
+
+/*----------------------------------------------------------------------------*/
+/*-----------------------MSS CAN Public APIs ---------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_init() function initializes the CAN driver as well as the CAN
+ controller. The basic_can_rx_mb and basic_can_tx_mb are used to configure the
+ number of receive and transmit mailboxes in basic CAN operation. This function
+ configures the CAN channel speed as per the “bitrate” parameter. It
+ initializes all receive mailboxes and make it ready for configuration. This is
+ the first function to be called before using any other function.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param bitrate
+ The bitRate parameter is used to configure CAN speed. The following standard
+ preset definitions are provided for systems with a PCLK1 of 8MHz, 16MHz or
+ 32MHz:
+ +-------------------+--------------------+--------------------+
+ | 8MHz PCLK1 | 16MHz PCLK1 | 32MHz PCLK1 |
+ +-------------------+--------------------+--------------------+
+ | CAN_SPEED_8M_5K | CAN_SPEED_16M_5K | CAN_SPEED_32M_5K |
+ | CAN_SPEED_8M_10K | CAN_SPEED_16M_10K | CAN_SPEED_32M_10K |
+ | CAN_SPEED_8M_20K | CAN_SPEED_16M_20K | CAN_SPEED_32M_20K |
+ | CAN_SPEED_8M_50K | CAN_SPEED_16M_50K | CAN_SPEED_32M_50K |
+ | CAN_SPEED_8M_100K | CAN_SPEED_16M_100K | CAN_SPEED_32M_100K |
+ | CAN_SPEED_8M_125K | CAN_SPEED_16M_125K | CAN_SPEED_32M_125K |
+ | CAN_SPEED_8M_250K | CAN_SPEED_16M_250K | CAN_SPEED_32M_250K |
+ | CAN_SPEED_8M_500K | CAN_SPEED_16M_500K | CAN_SPEED_32M_500K |
+ | CAN_SPEED_8M_1M | CAN_SPEED_16M_1M | CAN_SPEED_32M_1M |
+ +-------------------+--------------------+--------------------+
+
+ For custom settings, use CAN_SPEED_MANUAL and configure the settings via
+ pcan_config.
+
+ The default configurations can be altered by the addition of 0 or more of
+ the following:
+ - CAN_AUTO_RESTART
+ - CAN_ARB_FIXED_PRIO
+ - CAN_LITTLE_ENDIAN
+
+ @param pcan_config
+ The pcan_config parameter is a pointer to a mss_can_config_reg structure. This
+ structure is only used when bitrate is configured as CAN_SPEED_MANUAL.
+
+ When populating the mss_can_config_reg structure, the following should be noted:
+
+ 1. CFG_BITRATE defines the length of a CAN time quantum in terms of PCLK1
+ with 0 = 1 PCLK1, 1 = 2 PCLK1s and so on.
+ 2. A CAN bit time is made up of between 8 and 25 time quanta and the bit
+ rate is PCLK1 / ((CFG_BITRATE + 1) * number of time quanta per bit).
+ 3. There is a fixed overhead of 1 time quantum for synchronization at the
+ start of every CAN bit and the remaining time quanta in the bit are
+ allocated with CFG_TSEG1 and CFG_TSEG2.
+ 4. CFG_TSEG1 can have a value between 2 and 15 which represents between 3
+ and 16 time quanta.
+ 5. If SAMPLING_MODE is 0, CFG_TSEG2 can have a value between 1 and 7 which
+ represents between 2 and 8 time quanta and if SAMPLING_MODE is 1,
+ CFG_TSEG2 can have a value between 2 and 7 which represents between 3
+ and 8 time quanta.
+ 6. Receive sampling takes place at the end of the segment defined by
+ CFG_TSEG1.
+
+ For example, if CFG_TSEG1 = 3 and CFG_TSEG2 = 2 we get:
+
+ |<------------ 1 CAN bit time (8 time quanta)------------>|
+ /------+------+------+------+------+------+------+------\
+ -+ Synch | CFG_TSEG1 + 1 | CFG_TSEG2 + 1 +-
+ \------+------+------+------+------+------+------+------/
+ |
+ Receiver samples date here -->|
+
+ @param basic_can_rx_mb
+ The basic_can_rx_mb parameter is the number of receive mailboxes used in
+ basic CAN mode.
+
+ @param basic_can_tx_mb
+ The basic_can_tx_mb parameter is the number of transmit mailboxes used in
+ basic CAN mode.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_TSEG1_TOO_SMALL | Value provided to configure TSEG1 is too |
+ | | small |
+ | CAN_TSEG2_TOO_SMALL | Value provided to configure TSEG2 is too |
+ | | small |
+ | CAN_SJW_TOO_BIG | Value provided to configure synchronous jump|
+ | | width (SJW) is too big. |
+
+ Example 1: Using a default set for bitrate, tseg1, tseg2, and sjw and
+ additional configuration parameters.
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo, (CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16u,7u);
+
+ return(0);
+ }
+ @endcode
+
+ Example 2: Using custom settings for bitrate, tseg1, tseg2, and sjw.
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+
+ #define SYSTEM_CLOCK 8000000
+ #define BITS_PER_SECOND 10000
+
+ int e51(void)
+ {
+ mss_can_config_reg canreg;
+
+ canreg.CFG_BITRATE = (SYSTEM_CLOCK / (BITS_PER_SECOND * 8) - 1;
+ canreg.CFG_TSEG1 = 4;
+ canreg.CFG_TSEG2 = 1;
+ canreg.AUTO_RESTART = 0;
+ canreg.CFG_SJW = 0;
+ canreg.SAMPLING_MODE = 0;
+ canreg.EDGE_MODE = 0;
+ canreg.ENDIAN = 1;
+
+ MSS_CAN_init(&g_mss_can_0_lo,CAN_SPEED_MANUAL,&canreg,8,4);
+
+ return(0);
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_init
+(
+ mss_can_instance_t* this_can,
+ uint32_t bitrate,
+ pmss_can_config_reg pcan_config,
+ uint8_t basic_can_rx_mb,
+ uint8_t basic_can_tx_mb
+);
+
+ /*------------------------------------------------------------------------*//**
+ The MSS_CAN_set_config_reg() function sets the configuration register and
+ starts the CAN controller for normal mode operation. This function is used
+ when one needs to change the configuration settings while the CAN controller
+ was already initialized using MSS_CAN_init() function and is running.
+ MSS_CAN_set_config_reg() function should not be used when the CAN controller
+ wasn't initialized yet.
+
+ It performs following tasks:
+ - Clears all pending interrupts
+ - Stops CAN controller
+ - Disable interrupts
+ - Sets new configuration
+ - Starts CAN controller
+
+ @param this_can
+ The this_can parameter is a pointer to the MSS_CAN_instance_t structure.
+
+ @param cfg
+ The cfg parameter is a 4 bytes variable used to set the configuration
+ settings.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+
+ int e51(void)
+ {
+ Return_status = MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | \
+ CAN_AUTO_RESTART | CAN_LITTLE_ENDIAN),
+ (pmss_can_config_reg)0,16,7);
+ ....
+
+ MSS_CAN_set_config_reg(&g_mss_can_0_lo, (CAN_SPEED_16M_500K | \
+ CAN_AUTO_RESTART | CAN_LITTLE_ENDIAN));
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_config_reg
+(
+ mss_can_instance_t* this_can,
+ uint32_t cfg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_mode() function sets the CAN controller operating mode based
+ on the mode parameter. After this operation CAN controller is not in
+ operational, to do that invoke MSS_CAN_start() function.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mode
+ The mode parameter tells about desired operating mode of CAN controller.
+ Possible operating modes are as mentioned below:
+
+ | Mode | Description |
+ |--------------------------|-----------------------------------------|
+ | CANOP_MODE_INT_LOOPBACK | Sets normal operating mode |
+ | CANOP_MODE_LISTEN_ONLY | In listen-only mode, the CAN controller |
+ | | does not send any messages. Normally |
+ | | used for automatic bitrate detection |
+ | CANOP_MODE_INT_LOOPBACK | Selects internal loopback mode. This is |
+ | | used for self-test |
+ | CANOP_MODE_EXT_LOOPBACK | Selects external loopback. The CAN |
+ | | controller will receive a copy of each |
+ | | message sent. |
+ | CANOP_SRAM_TEST_MODE | Sets SRAM test mode |
+ | CANOP_SW_RESET | Issues a software reset |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+
+ ....
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_mode
+(
+ mss_can_instance_t* this_can,
+ mss_can_mode_t mode
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_start() function clears all pending interrupts and enable CAN
+ controller to perform normal operation. It enables receive interrupts also.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+ MSS_CAN_start(&g_mss_can_0_lo);
+
+ ....
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_start
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_stop() function is used to disable the CAN controller.
+
+ NOTE: Interrupt flags status remain unaffected.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+ MSS_CAN_start(&g_mss_can_0_lo);
+
+ ....
+ ....
+
+ MSS_CAN_stop(&g_mss_can_0_lo);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_stop
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_id() function returns the message identifier. Bits right
+ justified based on message identifier (Extended identifier) type.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns message identifier.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ...
+ return_id = MSS_CAN_get_id(&pmsg);
+
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_id
+(
+ pmss_can_msgobject pmsg
+);
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_id() function returns ID bits left justified based on IDE
+ type. IDE type might be either standard or extended.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns message identifier.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+ pmsg->ID = 0x120;
+ MSS_CAN_set_id(&pmsg);
+
+ ....
+ return(0);
+ }
+ @endcode
+*/
+uint32_t
+MSS_CAN_set_id
+(
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_msg_filter_mask() function packs the ID, IDE, and RTR bits
+ together as they are used in the message filter mask and returns packed
+ identifier.
+
+ @param id
+ The id parameter is a 4 byte variable to hold message identifier.
+
+ @param ide
+ The ide parameter is a 1 byte variable to indicate IDE type. Acceptable
+ values are as mentioned below:
+
+ | Value | Description |
+ |------------|-------------------------------|
+ | 0 | Standard format |
+ | 1 | Extended format |
+
+ @param rtr
+ The rtr parameter is a 1 byte variable to indicate message type. Acceptable
+ values are as mentioned below:
+
+ | Value | Description |
+ |------------|-------------------------------|
+ | 0 | Regular message (data frame) |
+ | 1 | RTR message (remote frame) |
+
+ @return
+ This function returns packed id.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_msg_filter_mask( 0x120, 1, 0);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_msg_filter_mask
+(
+ uint32_t id,
+ uint8_t ide,
+ uint8_t rtr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_int_ebl() function enable specific interrupt based on
+ irq_flag parameter.
+
+ @param this_can
+ This is a pointer to an mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+
+ | Constants | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_set_int_ebl(&g_mss_can_0_lo,CAN_INT_TX_MSG);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_clear_int_ebl() function disable specific interrupt based on
+ irq_flag parameter.
+
+ @param this_can
+ This is a pointer to an mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+
+ | Constant | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_clear_int_ebl(&g_mss_can_0_lo,CAN_INT_TX_MSG);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_clear_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_global_int_ebl() function returns the status of global
+ interrupt enable flag.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns global interrupt enable flag status.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_global_int_ebl(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_global_int_ebl
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_int_ebl() function returns the status of interrupt enable
+ flags.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns interrupt enable flag status.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_int_ebl(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_int_ebl
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_clear_int_status() function clears the selected interrupt flags.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+ | Constants | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+ MSS_CAN_clear_int_status(&g_mss_can_0_lo,CAN_INT_RX_MSG);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_clear_int_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_int_status() function returns the status of interrupts.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of existed interrupts.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_int_status(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_int_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_rtr_message_n () function loads mailbox with the given CAN
+ message. This message will be sent out after receipt of a RTR message
+ request. It verifies that whether the given mailbox is configured for Full
+ CAN or not and also checks for RTR auto-reply is enabled or not.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+ | CAN_NO_RTR_MAILBOX | Indicates that there is no mailbox for |
+ | | remote transmit request (RTR) frame |
+
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ pmsg->ID = 0x120;
+ pmsg->DATALOW = 0xAA5555AA;
+ pmsg->DATAHIGH = 0xAA5555AA;
+
+ MSS_CAN_set_rtr_message_n(&g_mss_can_0_lo, 5, &pmsg);
+
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_set_rtr_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rtr_message_abort_n() function aborts a RTR message transmit
+ request on mailbox mailbox_number and checks that message abort was
+ successful.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ ret_status = MSS_CAN_get_rtr_message_abort_n((&g_mss_can_0_lo, 6);
+
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_get_rtr_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_config_buffer() function configures receive mailboxes initialized
+ for Basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pfilter
+ The pfilter parameter is a pointer to the CAN message filter structure.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ pfilter.ACR.L=0x00000000;
+ pfilter.AMR.L= 0xFFFFFFFF;
+ pfilter.AMCR_D.MASK= 0xFFFF;
+ pfilter.AMCR_D.CODE= 0x00;
+
+ ret_status = MSS_CAN_config_buffer(&g_mss_can_0_lo, &pfilter);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_config_buffer
+(
+ mss_can_instance_t* this_can,
+ pmss_can_filterobject pfilter
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_config_buffer_n() function configures the receive mailbox
+ specified in mailbox_number. The function checks that the mailbox is set for
+ Full CAN operation, if not it return with error code.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes
+ - CAN_BASIC_CAN_MAILBOX
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ rx_msg.ID = 0x200;
+ rx_msg.DATAHIGH = 0u;
+ rx_msg.DATALOW = 0u;
+ rx_msg.AMR.L = 0xFFFFFFFF;
+ rx_msg.ACR.L = 0x00000000;
+ rx_msg.AMR_D = 0x0000FFFF;
+ rx_msg.ACR_D = 0x00000000;
+ rx_msg.RXB.DLC = 8u;
+ rx_msg.RXB.IDE = 0;
+
+ ret_status = MSS_CAN_config_buffer_n(&g_mss_can_0_lo, 3, &rx_msg);
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_config_buffer_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_rxmsgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message_n() function read message from the receive mailbox
+ specified in "mailbox_number" parameter and returns status of operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that will hold the
+ received message.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject msg;
+ ...
+
+ ret_status = MSS_CAN_get_message_n(&g_mss_can_0_lo, 3, &msg);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message() function read message from the first mailbox set
+ for Basic CAN operation that contains a message. Once the message has been
+ read from the mailbox, the message receipt is acknowledged.
+ Note: Since neither a hardware nor a software FIFO exists, message inversion
+ might happen (example, a newer message might be read from the receive
+ buffer prior to an older message).
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object, that will hold the
+ received message.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject rx_buf;
+ ...
+ if(CAN_VALID_MSG == MSS_CAN_get_message_av(&g_mss_can_0_lo))
+ {
+ if(CAN_VALID_MSG != MSS_CAN_get_message(&g_mss_can_0_lo, &rx_buf))
+ {
+ ....
+ }
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message_av() function indicates if receive buffer contains a
+ new message in Basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject rx_buf;
+ ...
+ if(CAN_VALID_MSG == MSS_CAN_get_message_av(&g_mss_can_0_lo))
+ {
+ MSS_CAN_get_message(&g_mss_can_0_lo, &rx_buf);
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message_av
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_n() function sends a message using mailbox
+ "mailbox_number". The function verifies that this mailbox is configured for
+ Full CAN operation and is empty.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that holds the CAN
+ message to transmit.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will return the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID=0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0<<20)| 0x00080000);
+
+ if (CAN_OK != MSS_CAN_send_message_n(&g_mss_can_0_lo, 0, &pmsg))
+ {
+ ...
+ }
+
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_abort_n() function aborts a message transmit
+ request for the specified mailbox number in mailbox_number and checks that
+ message abort status.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it
+ will return the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ if (CAN_OK != MSS_CAN_send_message_abort_n(&g_mss_can_0_lo, 0))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_ready() function will identify the availability of
+ mailbox to fill with new message in basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns CAN_OK on successful identification of free mailbox,
+ otherwise it will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID = 0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0 << 20)| 0x00080000);
+
+ if(CAN_OK == MSS_CAN_send_message_ready(&g_mss_can_0_lo))
+ {
+ MSS_CAN_send_message(&g_mss_can_0_lo, &pmsg);
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_ready
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message() function will copy the data to the first available
+ mailbox set for Basic CAN operation and send data on to the bus.
+ Note: Since neither a hardware nor a software FIFO exists, message inversion
+ might happen (example, a newer message might be send from the transmit
+ buffer prior to an older message).
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that holds the CAN
+ message to transmit.
+
+ @return
+ This function returns CAN_OK on successful identification of free mailbox,
+ otherwise it will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID = 0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0 << 20)| 0x00080000);
+
+ if (CAN_OK == MSS_CAN_send_message_ready(&g_mss_can_0_lo))
+ {
+ if (CAN_OK != MSS_CAN_send_message(&g_mss_can_0_lo, &pmsg))
+ {
+ ...
+ }
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_mask_n() function returns the message filter settings of the
+ selected receive mailbox. The function is valid for Full CAN operation only.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pamr
+ The pamr parameter is a pointer to the acceptance mask.
+
+ @param pacr
+ The pacr parameter is a pointer to the acceptance code.
+
+ @param pdta_amr
+ The pdta_amr parameter is a pointer to the acceptance mask of first two
+ data bytes.
+
+ @param pdta_acr
+ The pdta_acr parameter is a pointer to the acceptance code of first two
+ data bytes.
+
+ @return
+ This function will returns the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ if (CAN_OK != MSS_CAN_get_mask_n(&g_mss_can_0_lo,mailbox_number,&pamr,&pacr,
+ &pdamr, &pdacr))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_get_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t *pamr,
+ uint32_t *pacr,
+ uint16_t *pdta_amr,
+ uint16_t *pdta_acr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_mask_n() function configures the message filter settings for
+ the selected receive mailbox. The function is valid for Full CAN operation
+ only.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param amr
+ The amr parameter is a variable to hold the acceptance mask.
+
+ @param acr
+ The acr parameter is a variable to hold the acceptance code.
+
+ @param dta_amr
+ The dta_amr parameter is a variable to hold the acceptance mask of first two
+ data bytes.
+
+ @param dta_acr
+ The dta_acr parameter is a variable to hold the acceptance code of first two
+ data bytes.
+
+ @return
+ This function returns the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ if (CAN_OK != MSS_CAN_set_mask_n(&g_mss_can_0_lo,mailbox_number,&pamr,&pacr,
+ &pdamr, &pdacr))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_set_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t amr,
+ uint32_t acr,
+ uint16_t dta_amr,
+ uint16_t dta_acr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_buffer_status() function returns the buffer status of all
+ receive (32) mailboxes.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of receive buffers (32 buffers).
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status=0;
+ ...
+ return_status = MSS_CAN_get_rx_buffer_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_buffer_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_buffer_status() function returns the buffer status of all
+ transmit(32) mailboxes.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of transmit buffers (32 buffers).
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_buffer_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+*/
+uint32_t
+MSS_CAN_get_tx_buffer_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_error_status() function returns the present error state of
+ the CAN controller. Error state might be error active or error passive or
+ bus-off.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param status
+ The status parameter is a pointer to hold the content of error status
+ register.
+
+ @return
+ The function shall return the following codes:
+ | Codes | Descriptions |
+ |--------|-------------------------------|
+ | 0 | error active |
+ | 1 | error passive |
+ | 2 | bus-off |
+
+ Example:
+ @code
+ e51()
+ {
+ uint8_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_error_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_error_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t* status
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_error_count() function returns the current receive error
+ counter value. Counter value ranges from 0x00 - 0xFF.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns the receive error counter value.
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_rx_error_count(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_error_count
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_gte96() function provides information about receive
+ error count. It identifies that receive error count is greater than or equal
+ to 96, and reports 1 if count exceeds 96.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns following values:
+
+ | Value | Description |
+ |-------|------------------------------------------------------|
+ | 0 | if receive error count less than 96. |
+ | 1 | if receive error count greater than or equals to 96. |
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_rx_gte96(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_gte96
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_error_count() function returns the current transmit error
+ counter value. Counter value ranges from 0x00 - 0xFF.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns the transmit error counter value.
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_error_count(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_tx_error_count
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_gte96() function provides information about transmit
+ error count. It identifies that transmit error count is greater than or equals
+ to 96, and reports 1 if count exceeds 96.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns following values:
+
+ | Value | Description |
+ |-------|-------------------------------------------------------|
+ | 0 | if transmit error count less than 96. |
+ | 1 | if transmit error count greater than or equals to 96. |
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_gte96(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_tx_gte96
+(
+ mss_can_instance_t* this_can
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_CAN_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart.c
new file mode 100644
index 00000000..3c63ce71
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart.c
@@ -0,0 +1,1841 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver
+ * implementation.
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+#include "mss_uart_regs.h"
+#include "mss_uart.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MSS_UART0_LO_BASE (MSS_UART_TypeDef*)0x20000000UL
+#define MSS_UART1_LO_BASE (MSS_UART_TypeDef*)0x20100000UL
+#define MSS_UART2_LO_BASE (MSS_UART_TypeDef*)0x20102000UL
+#define MSS_UART3_LO_BASE (MSS_UART_TypeDef*)0x20104000UL
+#define MSS_UART4_LO_BASE (MSS_UART_TypeDef*)0x20106000UL
+
+#define MSS_UART0_HI_BASE (MSS_UART_TypeDef*)0x28000000UL
+#define MSS_UART1_HI_BASE (MSS_UART_TypeDef*)0x28100000UL
+#define MSS_UART2_HI_BASE (MSS_UART_TypeDef*)0x28102000UL
+#define MSS_UART3_HI_BASE (MSS_UART_TypeDef*)0x28104000UL
+#define MSS_UART4_HI_BASE (MSS_UART_TypeDef*)0x28106000UL
+
+
+mss_uart_instance_t g_mss_uart0_lo;
+mss_uart_instance_t g_mss_uart1_lo;
+mss_uart_instance_t g_mss_uart2_lo;
+mss_uart_instance_t g_mss_uart3_lo;
+mss_uart_instance_t g_mss_uart4_lo;
+
+mss_uart_instance_t g_mss_uart0_hi;
+mss_uart_instance_t g_mss_uart1_hi;
+mss_uart_instance_t g_mss_uart2_hi;
+mss_uart_instance_t g_mss_uart3_hi;
+mss_uart_instance_t g_mss_uart4_hi;
+
+/* This variable tracks if the UART peripheral is located on S5 or S6 on AXI
+ * switch. This will be used to determine which UART instance to be passed to
+ * UART interrupt handler. value 0 = S5(low). value 1 = S6(high)
+ * Bit positions:
+ * 0 ==> MMUART0
+ * 1 ==> MMUART1
+ * 2 ==> MMUART2
+ * 3 ==> MMUART3
+ * 4 ==> MMUART4
+
+ */
+static uint32_t g_uart_axi_pos = 0x0u;
+
+/*******************************************************************************
+ * Defines
+ */
+#define TX_COMPLETE 0u
+#define TX_FIFO_SIZE 16u
+
+#define FCR_TRIG_LEVEL_MASK 0xC0u
+
+#define IIRF_MASK 0x0Fu
+
+#define INVALID_INTERRUPT 0u
+#define INVALID_IRQ_HANDLER ((mss_uart_irq_handler_t) 0)
+#define NULL_HANDLER ((mss_uart_irq_handler_t) 0)
+
+#define MSS_UART_DATA_READY ((uint8_t) 0x01)
+
+#define SYNC_ASYNC_MODE_MASK (0x7u)
+
+#define UART0_POSITION_MASK 0x01u
+#define UART1_POSITION_MASK 0x02u
+#define UART2_POSITION_MASK 0x04u
+#define UART3_POSITION_MASK 0x08u
+#define UART4_POSITION_MASK 0x10u
+
+/*******************************************************************************
+ * Possible values for Interrupt Identification Register Field.
+ */
+#define IIRF_MODEM_STATUS 0x00u
+#define IIRF_THRE 0x02u
+#define IIRF_MMI 0x03u
+#define IIRF_RX_DATA 0x04u
+#define IIRF_RX_LINE_STATUS 0x06u
+#define IIRF_DATA_TIMEOUT 0x0Cu
+
+/*******************************************************************************
+ * Receiver error status mask.
+ */
+#define STATUS_ERROR_MASK ( MSS_UART_OVERUN_ERROR | MSS_UART_PARITY_ERROR | \
+ MSS_UART_FRAMING_ERROR | MSS_UART_BREAK_ERROR | \
+ MSS_UART_FIFO_ERROR)
+
+/*******************************************************************************
+ * Local functions.
+ */
+static void global_init(mss_uart_instance_t * this_uart, uint32_t baud_rate,
+ uint8_t line_config);
+static void uart_isr(mss_uart_instance_t * this_uart);
+static void default_tx_handler(mss_uart_instance_t * this_uart);
+static void enable_irq(const mss_uart_instance_t * this_uart);
+static void disable_irq(const mss_uart_instance_t * this_uart);
+static void config_baud_divisors
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baudrate
+);
+
+/*******************************************************************************
+ * Public Functions
+ *******************************************************************************/
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Disable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+
+ /* set default tx handler for automated TX using interrupt in USART mode */
+ this_uart->tx_handler = default_tx_handler;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void MSS_UART_lin_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Enable LIN mode */
+ this_uart->hw_reg->MM0 |= ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_irda_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config,
+ mss_uart_rzi_polarity_t rxpol,
+ mss_uart_rzi_polarity_t txpol,
+ mss_uart_rzi_pulsewidth_t pw
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Enable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 |= EIRD_MASK;
+
+ ((rxpol == MSS_UART_ACTIVE_LOW) ? (this_uart->hw_reg->MM1 &= ~EIRX_MASK) :
+ (this_uart->hw_reg->MM1 |= EIRX_MASK));
+
+ ((txpol == MSS_UART_ACTIVE_LOW) ? (this_uart->hw_reg->MM1 &= ~EITX_MASK) :
+ (this_uart->hw_reg->MM1 |= EITX_MASK));
+
+ ((pw == MSS_UART_3_BY_16) ? (this_uart->hw_reg->MM1 &= ~EITP_MASK) :
+ (this_uart->hw_reg->MM1 |= EITP_MASK));
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_smartcard_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Disable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Enable SmartCard Mode : Only when data is 8-bit and 2 stop bits */
+ if ((MSS_UART_DATA_8_BITS | MSS_UART_TWO_STOP_BITS) ==
+ (line_config & (MSS_UART_DATA_8_BITS | MSS_UART_TWO_STOP_BITS)))
+ {
+ this_uart->hw_reg->MM2 |= EERR_MASK;
+
+ /* Enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 |= ESWM_MASK;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_polled_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+)
+{
+ uint32_t char_idx = 0u;
+ uint32_t size_sent;
+ uint8_t status;
+ uint32_t temp_tx_size = tx_size;
+
+ ASSERT(pbuff != ( (uint8_t*)0));
+ ASSERT(tx_size > 0u);
+
+ if ((pbuff != ((uint8_t*)0)) && (temp_tx_size > 0u))
+ {
+ /* Remain in this loop until the entire input buffer
+ * has been transferred to the UART.
+ */
+ do
+ {
+ /* Read the Line Status Register and update the sticky record */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /* Check if TX FIFO is empty. */
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t fill_size = TX_FIFO_SIZE;
+
+ /* Calculate the number of bytes to transmit. */
+ if (temp_tx_size < TX_FIFO_SIZE)
+ {
+ fill_size = temp_tx_size;
+ }
+
+ /* Fill the TX FIFO with the calculated the number of bytes. */
+ for (size_sent = 0u; size_sent < fill_size; ++size_sent)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = pbuff[char_idx];
+ char_idx++;
+ }
+
+ /* find the number of bytes remaining(not transmitted yet) */
+ temp_tx_size -= size_sent;
+ }
+ }while (temp_tx_size);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_polled_tx_string
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * p_sz_string
+)
+{
+ uint32_t char_idx = 0u;
+ uint32_t fill_size;
+ uint8_t data_byte;
+ uint8_t status;
+
+ ASSERT(p_sz_string != ((uint8_t*)0));
+
+ if (p_sz_string != ((uint8_t*)0))
+ {
+ /* Get the first data byte from the input buffer */
+ data_byte = p_sz_string[char_idx];
+
+ /* First check for the NULL terminator byte.
+ * Then remain in this loop until the entire string in the input buffer
+ * has been transferred to the UART.
+ */
+ while (0u != data_byte)
+ {
+ /* Wait until TX FIFO is empty. */
+ do
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+ }while (0u == (status & MSS_UART_THRE));
+
+ /* Send bytes from the input buffer until the TX FIFO is full
+ * or we reach the NULL terminator byte.
+ */
+ fill_size = 0u;
+
+ while ((0u != data_byte) && (fill_size < TX_FIFO_SIZE))
+ {
+ /* Send the data byte */
+ this_uart->hw_reg->THR = data_byte;
+ ++fill_size;
+ char_idx++;
+ /* Get the next data byte from the input buffer */
+ data_byte = p_sz_string[char_idx];
+ }
+ }
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_irq_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+)
+{
+ ASSERT(pbuff != ((uint8_t*)0));
+ ASSERT(tx_size > 0u);
+
+ if ((tx_size > 0u) && (pbuff != ((uint8_t*)0)))
+ {
+ /* Initialize the transmit info for the UART instance with the
+ * arguments */
+ this_uart->tx_buffer = pbuff;
+ this_uart->tx_buff_size = tx_size;
+ this_uart->tx_idx = 0u;
+
+ /* assign default handler for data transfer */
+ this_uart->tx_handler = default_tx_handler;
+
+ /* enables TX interrupt */
+ this_uart->hw_reg->IER |= ETBEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+int8_t
+MSS_UART_tx_complete
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ int8_t ret_value = 0;
+ uint8_t status = 0u;
+
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ if ((TX_COMPLETE == this_uart->tx_buff_size) &&
+ ((status & MSS_UART_TEMT) != 0u))
+ {
+ ret_value = (int8_t)1;
+ }
+
+ return ret_value;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+size_t
+MSS_UART_get_rx
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t * rx_buff,
+ size_t buff_size
+)
+{
+ size_t rx_size = 0u;
+ uint8_t status = 0u;
+
+ ASSERT(rx_buff != ((uint8_t*)0));
+ ASSERT(buff_size > 0u);
+
+ if ((rx_buff != (uint8_t*)0) && (buff_size > 0u))
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ while (((status & MSS_UART_DATA_READY) != 0u) && (rx_size < buff_size))
+ {
+ rx_buff[rx_size] = this_uart->hw_reg->RBR;
+ ++rx_size;
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+ }
+ }
+
+ return rx_size;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+)
+{
+ ASSERT(MSS_UART_INVALID_IRQ > irq_mask);
+
+ enable_irq(this_uart);
+
+ if (MSS_UART_INVALID_IRQ > irq_mask)
+ {
+ /* irq_mask encoding: 1- enable
+ * bit 0 - Receive Data Available Interrupt
+ * bit 1 - Transmitter Holding Register Empty Interrupt
+ * bit 2 - Receiver Line Status Interrupt
+ * bit 3 - Modem Status Interrupt
+ */
+ this_uart->hw_reg->IER |= ((uint8_t)(((uint32_t)irq_mask &
+ (uint32_t)IIRF_MASK)));
+
+
+ /*
+ * bit 4 - Receiver time-out interrupt
+ * bit 5 - NACK / ERR signal interrupt
+ * bit 6 - PID parity error interrupt
+ * bit 7 - LIN break detection interrupt
+ * bit 8 - LIN Sync detection interrupt
+ */
+ this_uart->hw_reg->IEM |= (uint8_t)(((uint32_t)irq_mask >> 4u) &
+ ((uint32_t)IIRF_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+)
+{
+ /* irq_mask encoding: 1 - disable
+ * bit 0 - Receive Data Available Interrupt
+ * bit 1 - Transmitter Holding Register Empty Interrupt
+ * bit 2 - Receiver Line Status Interrupt
+ * bit 3 - Modem Status Interrupt
+ */
+ this_uart->hw_reg->IER &= ((uint8_t)(~((uint32_t)irq_mask &
+ (uint32_t)IIRF_MASK)));
+
+ /*
+ * bit 4 - Receiver time-out interrupt
+ * bit 5 - NACK / ERR signal interrupt
+ * bit 6 - PID parity error interrupt
+ * bit 7 - LIN break detection interrupt
+ * bit 8 - LIN Sync detection interrupt
+ */
+ this_uart->hw_reg->IEM &= (uint8_t)(~(((uint32_t)irq_mask >> 4u) &
+ ((uint32_t)IIRF_MASK)));
+
+ if(1 == this_uart->local_irq_enabled)
+ {
+ __disable_local_irq((int8_t)MMUART0_E51_INT);
+ }
+ else
+ {
+ disable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler,
+ mss_uart_rx_trig_level_t trigger_level
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER );
+ ASSERT(trigger_level < MSS_UART_FIFO_INVALID_TRIG_LEVEL);
+
+ if ((handler != INVALID_IRQ_HANDLER) &&
+ (trigger_level < MSS_UART_FIFO_INVALID_TRIG_LEVEL))
+ {
+ this_uart->rx_handler = handler;
+
+ /* Set the receive interrupt trigger level. */
+ this_uart->hw_reg->FCR = (this_uart->hw_reg->FCR &
+ (uint8_t)(~((uint8_t)FCR_TRIG_LEVEL_MASK))) |
+ (uint8_t)trigger_level;
+
+ /* Enable receive interrupt. */
+ this_uart->hw_reg->IER |= ERBFI_MASK;
+
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_loopback
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_loopback_t loopback
+)
+{
+ ASSERT(MSS_UART_INVALID_LOOPBACK > loopback);
+
+ if (MSS_UART_INVALID_LOOPBACK > loopback)
+ {
+ switch (loopback)
+ {
+ case MSS_UART_LOCAL_LOOPBACK_OFF:
+ /* Disable local loopback */
+ this_uart->hw_reg->MCR &= ~LOOP_MASK;
+ break;
+
+ case MSS_UART_LOCAL_LOOPBACK_ON:
+ /* Enable local loopback */
+ this_uart->hw_reg->MCR |= LOOP_MASK;
+ break;
+
+ case MSS_UART_REMOTE_LOOPBACK_OFF:
+ case MSS_UART_AUTO_ECHO_OFF:
+ /* Disable remote loopback & automatic echo */
+ this_uart->hw_reg->MCR &= ~(RLOOP_MASK|ECHO_MASK);
+ break;
+
+ case MSS_UART_REMOTE_LOOPBACK_ON:
+ /* Enable remote loopback */
+ this_uart->hw_reg->MCR |= (1u << RLOOP);
+ break;
+
+ case MSS_UART_AUTO_ECHO_ON:
+ /* Enable automatic echo */
+ this_uart->hw_reg->MCR |= (1u << ECHO);
+ break;
+
+ case MSS_UART_INVALID_LOOPBACK:
+ /* Fall through to default. */
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+}
+
+/***************************************************************************//**
+ * interrupt service routine.
+ */
+uint8_t mmuart0_plic_77_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART0_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart0_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart0_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart1_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART1_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart1_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart1_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart2_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART2_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart2_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart2_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart3_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART3_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart3_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart3_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart4_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART4_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart4_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart4_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+void mmuart0_e51_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART0_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart0_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart0_lo);
+ }
+}
+
+void mmuart_u54_h1_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART1_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart1_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart1_lo);
+ }
+}
+
+void mmuart_u54_h2_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART2_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart2_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart2_lo);
+ }
+}
+
+void mmuart_u54_h3_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART3_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart3_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart3_lo);
+ }
+}
+
+void mmuart_u54_h4_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART4_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart4_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart4_lo);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rxstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->linests_handler = handler;
+
+ /* Enable receiver line status interrupt. */
+ this_uart->hw_reg->IER |= ELSI_MASK;
+
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_tx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->tx_handler = handler;
+
+ /* Make TX buffer info invalid */
+ this_uart->tx_buffer = (const uint8_t*)0;
+ this_uart->tx_buff_size = 0u;
+
+ /* Enable transmitter holding register Empty interrupt. */
+ this_uart->hw_reg->IER |= ETBEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_modemstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->modemsts_handler = handler;
+
+ /* Enable modem status interrupt. */
+ this_uart->hw_reg->IER |= EDSSI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+size_t
+MSS_UART_fill_tx_fifo
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * tx_buffer,
+ size_t tx_size
+)
+{
+ uint8_t status = 0u;
+ uint32_t size_sent = 0u;
+
+ ASSERT(tx_buffer != ( (uint8_t*)0));
+ ASSERT(tx_size > 0);
+
+ /* Fill the UART's Tx FIFO until the FIFO is full or the complete input
+ * buffer has been written. */
+ if ((tx_buffer != ((uint8_t*)0)) && (tx_size > 0u))
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t fill_size = TX_FIFO_SIZE;
+
+ if (tx_size < TX_FIFO_SIZE)
+ {
+ fill_size = tx_size;
+ }
+
+ /* Fill up FIFO */
+ for (size_sent = 0u; size_sent < fill_size; size_sent++)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = tx_buffer[size_sent];
+ }
+ }
+ }
+
+ return size_sent;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_rx_status
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_INVALID_PARAM;
+
+ /*
+ * Extract UART receive error status.
+ * Bit 1 - Overflow error status
+ * Bit 2 - Parity error status
+ * Bit 3 - Frame error status
+ * Bit 4 - Break interrupt indicator
+ * Bit 7 - FIFO data error status
+ */
+ this_uart->status |= (this_uart->hw_reg->LSR);
+ status = (this_uart->status & STATUS_ERROR_MASK);
+ /* Clear the sticky status after reading */
+ this_uart->status = 0u;
+
+ return status;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_modem_status
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_INVALID_PARAM;
+
+ /*
+ * Extract UART modem status and place in lower bits of "status".
+ * Bit 0 - Delta Clear to Send Indicator
+ * Bit 1 - Delta Clear to Receive Indicator
+ * Bit 2 - Trailing edge of Ring Indicator detector
+ * Bit 3 - Delta Data Carrier Detect indicator
+ * Bit 4 - Clear To Send
+ * Bit 5 - Data Set Ready
+ * Bit 6 - Ring Indicator
+ * Bit 7 - Data Carrier Detect
+ */
+ status = this_uart->hw_reg->MSR;
+
+ return status;
+}
+
+/***************************************************************************//**
+ * MSS_UART_get_tx_status.
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_tx_status
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_TX_BUSY;
+
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /*
+ * Extract the transmit status bits from the UART's Line Status Register.
+ * Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status.
+ (If = 1, TX FIFO is empty)
+ * Bit 6 - Transmitter Empty (TEMT) status.
+ (If = 1, both TX FIFO and shift register are empty)
+ */
+ status &= (MSS_UART_THRE | MSS_UART_TEMT);
+
+ return status;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_break
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* set break character on Tx line */
+ this_uart->hw_reg->LCR |= SB_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_clear_break
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* remove break character from Tx line */
+ this_uart->hw_reg->LCR &= ~SB_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_pidpei_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->pid_pei_handler = handler;
+
+ /* Enable PID parity error interrupt. */
+ this_uart->hw_reg->IEM |= EPID_PEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_linbreak_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->break_handler = handler;
+
+ /* Enable LIN break detection interrupt. */
+ this_uart->hw_reg->IEM |= ELINBI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_linsync_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->sync_handler = handler;
+
+ /* Enable LIN sync detection interrupt. */
+ this_uart->hw_reg->IEM |= ELINSI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_nack_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->nack_handler = handler;
+
+ /* Enable LIN sync detection interrupt. */
+ this_uart->hw_reg->IEM |= ENACKI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_timeout_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->rto_handler = handler;
+
+ /* Enable receiver timeout interrupt. */
+ this_uart->hw_reg->IEM |= ERTOI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 |= ESWM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 &= ~ESWM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+)
+{
+ ASSERT(MSS_UART_INVALID_ENDIAN > endian);
+
+ if (MSS_UART_INVALID_ENDIAN > endian)
+ {
+ /* Configure MSB first / LSB first for receiver */
+ ((MSS_UART_LITTLEEND == endian) ? (this_uart->hw_reg->MM1 &= ~E_MSB_RX_MASK) :
+ (this_uart->hw_reg->MM1 |= E_MSB_RX_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_tx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+)
+{
+ ASSERT(MSS_UART_INVALID_ENDIAN > endian);
+
+ if (MSS_UART_INVALID_ENDIAN > endian)
+ {
+ /* Configure MSB first / LSB first for transmitter */
+ ((MSS_UART_LITTLEEND == endian) ? (this_uart->hw_reg->MM1 &= ~E_MSB_TX_MASK) :
+ (this_uart->hw_reg->MM1 |= E_MSB_TX_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_filter_length
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_filter_length_t length
+)
+{
+ ASSERT(MSS_UART_INVALID_FILTER_LENGTH > length);
+
+ if (MSS_UART_INVALID_FILTER_LENGTH > length)
+ {
+ /* Configure glitch filter length */
+ this_uart->hw_reg->GFR = (uint8_t)length;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_afm
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable RX FIFO till address flag with correct address is received */
+ this_uart->hw_reg->MM2 |= EAFM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_afm
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Enable RX FIFO irrespective of address flag and
+ correct address is received */
+ this_uart->hw_reg->MM2 &= ~EAFM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_afclear
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Enable address flag clearing */
+ /* Disable RX FIFO till another address flag with
+ correct address is received */
+ this_uart->hw_reg->MM2 |= EAFC_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_afclear
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable address flag clearing */
+ this_uart->hw_reg->MM2 &= ~EAFC_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_rx_timeout
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeout
+)
+{
+ /* Load the receive timeout value */
+ this_uart->hw_reg->RTO = timeout;
+
+ /*Enable receiver time-out */
+ this_uart->hw_reg->MM0 |= ERTO_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_rx_timeout
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable receiver time-out */
+ this_uart->hw_reg->MM0 &= ~ERTO_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeguard
+)
+{
+ /* Load the transmitter time guard value */
+ this_uart->hw_reg->TTG = timeguard;
+
+ /* Enable transmitter time guard */
+ this_uart->hw_reg->MM0 |= ETTG_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable transmitter time guard */
+ this_uart->hw_reg->MM0 &= ~ETTG_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_address
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t address
+)
+{
+ this_uart->hw_reg->ADR = address;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_ready_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_ready_mode_t mode
+)
+{
+ ASSERT(MSS_UART_INVALID_READY_MODE > mode);
+
+ if (MSS_UART_INVALID_READY_MODE > mode )
+ {
+ /* Configure mode 0 or mode 1 for TXRDY and RXRDY */
+ ((MSS_UART_READY_MODE0 == mode) ? (this_uart->hw_reg->FCR &= ~RDYMODE_MASK) :
+ (this_uart->hw_reg->FCR |= RDYMODE_MASK) );
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_usart_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_usart_mode_t mode
+)
+{
+ ASSERT(MSS_UART_INVALID_SYNC_MODE > mode);
+
+ if (MSS_UART_INVALID_SYNC_MODE > mode)
+ {
+ /* Nothing to do for the baudrate:
+ operates at PCLK / 2 + glitch filter length */
+ /* Clear the ESYN bits 2:0 */
+ this_uart->hw_reg->MM0 &= ~SYNC_ASYNC_MODE_MASK;
+ this_uart->hw_reg->MM0 |= (uint8_t)mode;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_local_irq
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Make sure to disable interrupt on PLIC as it might have been enabled
+ * when application registered an interrupt handler function or
+ * used MSS_UART_enable_irq() to enable PLIC interrupt */
+ disable_irq(this_uart);
+
+ this_uart->local_irq_enabled = 1u;
+
+ /* Enable local interrupt UART instance.
+ * Local interrupt will be enabled on the HART on which the application
+ * calling this API is being executed*/
+ __enable_local_irq((int8_t)MMUART0_E51_INT);
+}
+
+/*******************************************************************************
+ * Local Functions
+ ******************************************************************************/
+/*******************************************************************************
+ * Global initialization for all modes
+ */
+static void global_init
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ if ((&g_mss_uart0_lo == this_uart))
+ {
+ this_uart->hw_reg = MSS_UART0_LO_BASE;
+ g_uart_axi_pos &= ~0x01u;
+ }
+
+ else if (&g_mss_uart1_lo == this_uart)
+ {
+
+ this_uart->hw_reg = MSS_UART1_LO_BASE;
+ g_uart_axi_pos &= ~0x02u;
+ }
+
+ else if (&g_mss_uart2_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART2_LO_BASE;
+ g_uart_axi_pos &= ~0x04u;
+ }
+
+ else if (&g_mss_uart3_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART3_LO_BASE;
+ g_uart_axi_pos &= ~0x08u;
+ }
+
+ else if (&g_mss_uart4_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART4_LO_BASE;
+ g_uart_axi_pos &= ~0x10u;
+ }
+
+ else if ((&g_mss_uart0_hi == this_uart))
+ {
+ this_uart->hw_reg = MSS_UART0_HI_BASE;
+ g_uart_axi_pos |= 0x01u;
+ }
+
+ else if (&g_mss_uart1_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART1_HI_BASE;
+ g_uart_axi_pos |= 0x02u;
+ }
+
+ else if (&g_mss_uart2_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART2_HI_BASE;
+ g_uart_axi_pos |= 0x04u;
+ }
+
+ else if (&g_mss_uart3_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART3_HI_BASE;
+ g_uart_axi_pos |= 0x08u;
+ }
+
+ else if (&g_mss_uart4_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART4_HI_BASE;
+ g_uart_axi_pos |= 0x10u;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* disable interrupts */
+ this_uart->hw_reg->IER = 0u;
+
+ /* FIFO configuration */
+ this_uart->hw_reg->FCR = 0u;
+
+ /* clear receiver FIFO */
+ this_uart->hw_reg->FCR |= CLEAR_RX_FIFO_MASK;
+
+ /* clear transmitter FIFO */
+ this_uart->hw_reg->FCR |= CLEAR_TX_FIFO_MASK;
+
+ /* set default READY mode : Mode 0*/
+ /* enable RXRDYN and TXRDYN pins. The earlier FCR write to set the TX FIFO
+ * trigger level inadvertently disabled the FCR_RXRDY_TXRDYN_EN bit. */
+ this_uart->hw_reg->FCR |= RXRDY_TXRDYN_EN_MASK;
+
+ /* disable loopback : local * remote */
+ this_uart->hw_reg->MCR &= ~LOOP_MASK;
+
+ this_uart->hw_reg->MCR &= ~RLOOP_MASK;
+
+ /* set default TX endian */
+ this_uart->hw_reg->MM1 &= ~E_MSB_TX_MASK;
+
+ /* set default RX endian */
+ this_uart->hw_reg->MM1 &= ~E_MSB_RX_MASK;
+
+ /* default AFM : disabled */
+ this_uart->hw_reg->MM2 &= ~EAFM_MASK;
+
+ /* disable TX time guard */
+ this_uart->hw_reg->MM0 &= ~ETTG_MASK;
+
+ /* set default RX timeout */
+ this_uart->hw_reg->MM0 &= ~ERTO_MASK;
+
+ /* disable fractional baud-rate */
+ this_uart->hw_reg->MM0 &= ~EFBR_MASK;
+
+ /* disable single wire mode */
+ this_uart->hw_reg->MM2 &= ~ESWM_MASK;
+
+ /* set filter to minimum value */
+ this_uart->hw_reg->GFR = 0u;
+
+ /* set default TX time guard */
+ this_uart->hw_reg->TTG = 0u;
+
+ /* set default RX timeout */
+ this_uart->hw_reg->RTO = 0u;
+
+ /*
+ * Configure baud rate divisors. This uses the fractional baud rate divisor
+ * where possible to provide the most accurate baud rat possible.
+ */
+ config_baud_divisors(this_uart, baud_rate);
+
+ /* set the line control register (bit length, stop bits, parity) */
+ this_uart->hw_reg->LCR = line_config;
+
+ /* Instance setup */
+ this_uart->baudrate = baud_rate;
+ this_uart->lineconfig = line_config;
+ this_uart->tx_buff_size = TX_COMPLETE;
+ this_uart->tx_buffer = (const uint8_t*)0;
+ this_uart->tx_idx = 0u;
+
+ /* Default handlers for MSS UART interrupts */
+ this_uart->rx_handler = NULL_HANDLER;
+ this_uart->tx_handler = NULL_HANDLER;
+ this_uart->linests_handler = NULL_HANDLER;
+ this_uart->modemsts_handler = NULL_HANDLER;
+ this_uart->rto_handler = NULL_HANDLER;
+ this_uart->nack_handler = NULL_HANDLER;
+ this_uart->pid_pei_handler = NULL_HANDLER;
+ this_uart->break_handler = NULL_HANDLER;
+ this_uart->sync_handler = NULL_HANDLER;
+
+ this_uart->local_irq_enabled = 0u;
+
+ /* Initialize the sticky status */
+ this_uart->status = 0u;
+}
+
+/***************************************************************************//**
+ * Configure baud divisors using fractional baud rate if possible.
+ */
+static void
+config_baud_divisors
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baudrate
+)
+{
+ uint32_t baud_value;
+ uint32_t baud_value_by_64;
+ uint32_t baud_value_by_128;
+ uint32_t fractional_baud_value;
+ uint64_t pclk_freq;
+
+ this_uart->baudrate = baudrate;
+
+ pclk_freq = LIBERO_SETTING_MSS_APB_AHB_CLK;
+
+ /*
+ * Compute baud value based on requested baud rate and PCLK frequency.
+ * The baud value is computed using the following equation:
+ * baud_value = PCLK_Frequency / (baud_rate * 16)
+ */
+ baud_value_by_128 = (uint32_t)((8UL * pclk_freq) / baudrate);
+ baud_value_by_64 = baud_value_by_128 / 2u;
+ baud_value = baud_value_by_64 / 64u;
+ fractional_baud_value = baud_value_by_64 - (baud_value * 64u);
+ fractional_baud_value += (baud_value_by_128 - (baud_value * 128u))
+ - (fractional_baud_value * 2u);
+
+ /* Assert if integer baud value fits in 16-bit. */
+ ASSERT(baud_value <= UINT16_MAX);
+
+ if (baud_value <= (uint32_t)UINT16_MAX)
+ {
+ if (baud_value > 1u)
+ {
+ /* Use Fractional baud rate divisors */
+ /* set divisor latch */
+ this_uart->hw_reg->LCR |= DLAB_MASK;
+
+ /* MSB of baud value */
+ this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8);
+
+ /* LSB of baud value */
+ this_uart->hw_reg->DLR = (uint8_t)baud_value;
+
+ /* reset divisor latch */
+ this_uart->hw_reg->LCR &= ~DLAB_MASK;
+
+ /* Enable Fractional baud rate */
+ this_uart->hw_reg->MM0 |= EFBR_MASK;
+
+ /* Load the fractional baud rate register */
+ ASSERT(fractional_baud_value <= (uint32_t)UINT8_MAX);
+ this_uart->hw_reg->DFR = (uint8_t)fractional_baud_value;
+ }
+ else
+ {
+ /* Do NOT use Fractional baud rate divisors. */
+ /* set divisor latch */
+ this_uart->hw_reg->LCR |= DLAB_MASK;
+
+ /* MSB of baud value */
+ this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8u);
+
+ /* LSB of baud value */
+ this_uart->hw_reg->DLR = (uint8_t)baud_value;
+
+ /* reset divisor latch */
+ this_uart->hw_reg->LCR &= ~DLAB_MASK;
+
+ /* Disable Fractional baud rate */
+ this_uart->hw_reg->MM0 &= ~EFBR_MASK;
+ }
+ }
+}
+
+/***************************************************************************//**
+ * Interrupt service routine triggered by any MSS UART interrupt. This routine
+ * will call the handler function appropriate to the interrupt from the
+ * handlers previously registered with the driver through calls to the
+ * MSS_UART_set_*_handler() functions, or it will call the default_tx_handler()
+ * function in response to transmit interrupts if MSS_UART_irq_tx() is used to
+ * transmit data.
+ */
+static void
+uart_isr
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t iirf;
+
+ iirf = this_uart->hw_reg->IIR & IIRF_MASK;
+
+ switch (iirf)
+ {
+ case IIRF_MODEM_STATUS: /* Modem status interrupt */
+ {
+ ASSERT(NULL_HANDLER != this_uart->modemsts_handler);
+ if (NULL_HANDLER != this_uart->modemsts_handler)
+ {
+ (*(this_uart->modemsts_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_THRE: /* Transmitter Holding Register Empty */
+ {
+ ASSERT(NULL_HANDLER != this_uart->tx_handler);
+ if (NULL_HANDLER != this_uart->tx_handler)
+ {
+ (*(this_uart->tx_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_RX_DATA: /* Received Data Available */
+ case IIRF_DATA_TIMEOUT: /* Received Data Timed-out */
+ {
+ ASSERT(NULL_HANDLER != this_uart->rx_handler);
+ if (NULL_HANDLER != this_uart->rx_handler)
+ {
+ (*(this_uart->rx_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_RX_LINE_STATUS: /* Line Status Interrupt */
+ {
+ ASSERT(NULL_HANDLER != this_uart->linests_handler);
+ if (NULL_HANDLER != this_uart->linests_handler)
+ {
+ (*(this_uart->linests_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_MMI:
+ {
+ /* Identify multi-mode interrupts and handle */
+
+ /* Receiver time-out interrupt */
+ if (this_uart->hw_reg->IIM & ERTOI_MASK)
+ {
+ ASSERT(NULL_HANDLER != this_uart->rto_handler);
+
+ if (NULL_HANDLER != this_uart->rto_handler)
+ {
+ (*(this_uart->rto_handler))(this_uart);
+ }
+ }
+
+ /* NACK interrupt */
+ if (this_uart->hw_reg->IIM &ENACKI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->nack_handler);
+
+ if (NULL_HANDLER != this_uart->nack_handler)
+ {
+ (*(this_uart->nack_handler))(this_uart);
+ }
+ }
+
+ /* PID parity error interrupt */
+ if (this_uart->hw_reg->IIM & EPID_PEI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->pid_pei_handler);
+
+ if (NULL_HANDLER != this_uart->pid_pei_handler)
+ {
+ (*(this_uart->pid_pei_handler))(this_uart);
+ }
+ }
+
+ /* LIN break detection interrupt */
+ if (this_uart->hw_reg->IIM & ELINBI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->break_handler);
+
+ if (NULL_HANDLER != this_uart->break_handler)
+ {
+ (*(this_uart->break_handler))(this_uart);
+ }
+ }
+
+ /* LIN Sync detection interrupt */
+ if (this_uart->hw_reg->IIM & ELINSI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->sync_handler);
+
+ if (NULL_HANDLER != this_uart->sync_handler)
+ {
+ (*(this_uart->sync_handler))(this_uart);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ ASSERT(INVALID_INTERRUPT); /* Comment to avoid LDRA warning */
+ }
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+static void
+default_tx_handler
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status;
+
+ ASSERT(( (uint8_t*)0 ) != this_uart->tx_buffer);
+ ASSERT(0u < this_uart->tx_buff_size);
+
+ if ((((uint8_t*)0 ) != this_uart->tx_buffer) &&
+ (0u < this_uart->tx_buff_size))
+ {
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /*
+ * This function should only be called as a result of a THRE interrupt.
+ * Verify that this is true before proceeding to transmit data.
+ */
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t cnt;
+ uint32_t fill_size = TX_FIFO_SIZE;
+ uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;
+
+ /* Calculate the number of bytes to transmit. */
+ if (tx_remain < TX_FIFO_SIZE)
+ {
+ fill_size = tx_remain;
+ }
+
+ /* Fill the TX FIFO with the calculated the number of bytes. */
+ for (cnt = 0u; cnt < fill_size; ++cnt)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx];
+ ++this_uart->tx_idx;
+ }
+ }
+
+ /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */
+ if (this_uart->tx_idx == this_uart->tx_buff_size)
+ {
+ this_uart->tx_buff_size = TX_COMPLETE;
+
+ /* disables TX interrupt */
+ this_uart->hw_reg->IER &= ~ETBEI_MASK;
+ }
+ }
+}
+
+static void
+enable_irq
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ PLIC_IRQn_Type plic_num = 0;
+
+ if(0u == this_uart->local_irq_enabled)
+ {
+ if (((&g_mss_uart0_lo == this_uart)) || ((&g_mss_uart0_hi == this_uart)))
+ {
+ plic_num = MMUART0_PLIC_77;
+ }
+ else if (((&g_mss_uart1_lo == this_uart)) || ((&g_mss_uart1_hi == this_uart)))
+ {
+ plic_num = MMUART1_PLIC;
+ }
+ else if (((&g_mss_uart2_lo == this_uart)) || ((&g_mss_uart2_hi == this_uart)))
+ {
+ plic_num = MMUART2_PLIC;
+ }
+ else if (((&g_mss_uart3_lo == this_uart)) || ((&g_mss_uart3_hi == this_uart)))
+ {
+ plic_num = MMUART3_PLIC;
+ }
+ else if (((&g_mss_uart4_lo == this_uart)) || ((&g_mss_uart4_hi == this_uart)))
+ {
+ plic_num = MMUART4_PLIC;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* Enable UART instance interrupt in PLIC. */
+ PLIC_EnableIRQ(plic_num);
+ }
+}
+
+static void
+disable_irq
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ PLIC_IRQn_Type plic_num = 0;
+
+ if (((&g_mss_uart0_lo == this_uart)) || ((&g_mss_uart0_hi == this_uart)))
+ {
+ plic_num = MMUART0_PLIC_77;
+ }
+ else if (((&g_mss_uart1_lo == this_uart)) || ((&g_mss_uart1_hi == this_uart)))
+ {
+ plic_num = MMUART1_PLIC;
+ }
+ else if (((&g_mss_uart2_lo == this_uart)) || ((&g_mss_uart2_hi == this_uart)))
+ {
+ plic_num = MMUART2_PLIC;
+ }
+ else if (((&g_mss_uart3_lo == this_uart)) || ((&g_mss_uart3_hi == this_uart)))
+ {
+ plic_num = MMUART3_PLIC;
+ }
+ else if (((&g_mss_uart4_lo == this_uart)) || ((&g_mss_uart4_hi == this_uart)))
+ {
+ plic_num = MMUART4_PLIC;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* Disable UART instance interrupt in PLIC. */
+ PLIC_DisableIRQ(plic_num);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart.h
new file mode 100644
index 00000000..49e18448
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart.h
@@ -0,0 +1,3335 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver
+ * public API.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire SoC MSS UART Bare Metal Driver.
+
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor subsystem (MSS) includes five multi-mode UART
+ (MMUART) peripherals for serial communication. This driver provides a set of
+ functions for controlling the MSS MMUARTs as part of a bare metal system
+ where no operating system is available. These drivers can be adapted for use
+ as part of an operating system, but the implementation of the adaptation layer
+ between this driver and the operating system's driver model is outside the
+ scope of this driver.
+ Note: MSS UART is synonymous with MSS MMUART in this document.
+
+ ==============================================================================
+ Hardware Flow Dependencies
+ ==============================================================================
+ The configuration of all features of the MSS MMUART peripherals is covered by
+ this driver with the exception of the PolarFire SoC IOMUX configuration.
+ PolarFire SoC allows multiple non-concurrent uses of some external pins
+ through IOMUX configuration. This feature allows optimization of external pin
+ usage by assigning external pins for use by either the microprocessor
+ subsystem or the FPGA fabric. The MSS MMUART serial signals are routed through
+ IOMUXs to the PolarFire SoC device external pins. The MSS MMUART serial
+ signals may also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
+ For more information on IOMUX, refer to the I/O Configuration section of the
+ PolarFire SoC Microprocessor Subsystem (MSS) User's Guide.
+
+ The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
+ must ensure that the MSS MMUART peripherals are enabled and configured in the
+ PolarFire SoC MSS configurator if you wish to use them. For more information
+ on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
+ Subsystem (MSS) User's Guide.
+
+ On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
+ masters and multiple slaves. Five RISC-V CPUs connect to the Master ports
+ M10 to M14 of the AXI switch. By default, all the APB peripherals are
+ accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB
+ bridges (referred as main APB bus). However, to support logical separation in
+ the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals
+ can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to
+ APB bridges (referred as the AMP APB bus).
+
+ Application must make sure that the desired MMUART instance is appropriately
+ configured on one of the APB bus described above by configuring the PolarFire
+ SoC system registers (SYSREG) as per the application need and that the
+ appropriate data structures are provided to this driver as parameter to the
+ functions provided by this driver.
+
+ The base address and register addresses are defined in this driver as
+ constants. The interrupt number assignment for the MSS MMUART peripherals are
+ defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
+ is included in the project settings of the SoftConsole tool chain and that it
+ is generated into your project.
+
+ ==============================================================================
+ Theory of Operation
+ ==============================================================================
+ The MSS MMUART driver functions are grouped into the following categories:
+ - Initialization and configuration functions
+ - Polled transmit and receive functions
+ - Interrupt driven transmit and receive functions
+
+ --------------------------------
+ Initialization and Configuration
+ --------------------------------
+ The MSS MMUART supports the following four broad modes of operation:
+ - UART or USART mode
+ - LIN mode
+ - IrDA mode
+ - Smartcard or ISO 7816 mode
+
+ The MSS MMUART driver provides the MSS_UART_init(), MSS_UART_lin_init(),
+ MSS_UART_irda_init() and MSS_UART_smartcard_init() functions to initialize the
+ MSS MMUARTs for operation in one of these modes. One of these initialization
+ functions must be called before any other MSS MMUART driver functions can be
+ called. The MSS MMUART operating modes are mutually exclusive; therefore only
+ one of the initialization functions must be called. The first parameter of the
+ initialization functions is a pointer to one of ten global data structures
+ used to store state information for each MSS MMUART. A pointer to these data
+ structures is also used as the first parameter to many of the driver functions
+ to identify which MSS MMUART will be used by the called function. The names of
+ these data structures are:
+ - g_mss_uart0_lo
+ - g_mss_uart1_lo
+ - g_mss_uart2_lo
+ - g_mss_uart3_lo
+ - g_mss_uart4_lo
+ - g_mss_uart0_hi
+ - g_mss_uart1_hi
+ - g_mss_uart2_hi
+ - g_mss_uart3_hi
+ - g_mss_uart4_hi
+
+ Therefore, any call to an MSS MMUART function should be of the form
+ MSS_UART_function_name( &g_mss_uart0_lo, ... ) or
+ MSS_UART_function_name( &g_mss_uart1_hi, ... ).
+
+ UART or USART Mode
+ For the UART or USART modes of operation, the MSS MMUART driver is initialized
+ through a call to the MSS_UART_init() function. This function takes the UART's
+ configuration as its parameters. The MSS_UART_init() function must be called
+ before any other MSS MMUART driver functions can be called.
+ The MSS_UART_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the LIN, IrDA and SmartCard modes.
+
+ LIN mode
+ For the LIN mode of operation, the MSS MMUART driver is initialized through a
+ call to the MSS_UART_lin_init() function. This function takes the LIN node's
+ configuration as its parameters. The MSS_UART_lin_init() function must be
+ called before any other MSS MMUART driver functions can be called. The
+ MSS_UART_lin_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the IrDA and SmartCard modes.
+ The driver also provides the following LIN mode configuration functions:
+ - MSS_UART_set_break()
+ - MSS_UART_clear_break()
+ - MSS_UART_set_pidpei_handler()
+ - MSS_UART_set_linbreak_handler()
+ - MSS_UART_set_linsync_handler()
+
+ Note: These LIN mode configuration functions can only be called after the
+ MSS_UART_lin_init() function is called.
+
+ IrDA mode
+ For the IrDA mode of operation, the driver is initialized through a call to
+ the MSS_UART_irda_init() function. This function takes the IrDA node's
+ configuration as its parameters. The MSS_UART_irda_init() function must be
+ called before any other MSS MMUART driver functions can be called. The
+ MSS_UART_irda_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the LIN and SmartCard modes.
+
+ Smartcard or ISO 7816 mode
+ For the Smartcard or ISO 7816 mode of operation, the driver is initialized
+ through a call to the MSS_UART_smartcard_init() function. This function takes
+ the smartcard configuration as its parameters. The MSS_UART_smartcard_init()
+ function must be called before any other MSS MMUART driver functions can be
+ called. The MSS_UART_smartcard_init() function configures the baud rate based
+ on the input baud rate parameter and if possible uses a fractional baud rate
+ for greater precision. This function disables the LIN and IrDA modes.
+ The driver also provides the following Smartcard mode configuration functions:
+ - MSS_UART_enable_halfduplex()
+ - MSS_UART_disable_halfduplex()
+ - MSS_UART_set_nack_handler()
+
+ Note: These Smartcard mode configuration functions can only be called after
+ the MSS_UART_smartcard_init() function is called.
+
+ Common Configuration Functions
+ The driver also provides the configuration functions that can be used with all
+ MSS MMUART operating modes. These common configuration functions are as
+ follows:
+ - MSS_UART_set_rx_endian()
+ - MSS_UART_set_tx_endian()
+ - MSS_UART_enable_afclear()
+ - MSS_UART_disable_afclear()
+ - MSS_UART_enable_rx_timeout()
+ - MSS_UART_disable_rx_timeout()
+ - MSS_UART_enable_tx_time_guard()
+ - MSS_UART_disable_tx_time_guard()
+ - MSS_UART_set_address()
+ - MSS_UART_set_ready_mode()
+ - MSS_UART_set_usart_mode()
+ - MSS_UART_set_filter_length()
+ - MSS_UART_enable_afm()
+ - MSS_UART_disable_afm()
+
+ Note: These configuration functions can only be called after one of the
+ MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init() or
+ MSS_UART_smartcard_init() functions is called.
+
+ --------------------------------------
+ Polled Transmit and Receive Operations
+ --------------------------------------
+ The driver can be used to transmit and receive data once initialized.
+ Data is transmitted using the MSS_UART_polled_tx() function. This function is
+ blocking, meaning that it will only return once the data passed to the
+ function has been sent to the MSS MMUART hardware transmitter. Data received
+ by the MSS MMUART hardware receiver can be read by the MSS_UART_get_rx()
+ function.
+ The MSS_UART_polled_tx_string() function is provided to transmit a NUL ('\0')
+ terminated string in polled mode. This function is blocking, meaning that it
+ will only return once the data passed to the function has been sent to the MSS
+ MMUART hardware transmitter.
+ The MSS_UART_fill_tx_fifo() function fills the MSS MMUART hardware transmit
+ FIFO with data from a buffer passed as a parameter and returns the number of
+ bytes transferred to the FIFO. If the transmit FIFO is not empty when the
+ MSS_UART_fill_tx_fifo() function is called it returns immediately without
+ transferring any data to the FIFO.
+
+ ---------------------------
+ Interrupt Driven Operations
+ ---------------------------
+ The driver can also transmit or receive data under interrupt control, freeing
+ your application to perform other tasks until an interrupt occurs indicating
+ that the driver's attention is required.
+
+ Local or PLIC interrupt:
+ PolarFire SoC architecture provides flexibility in terms of how the MMUART
+ interrupt is seen by the PolarFire SoC Core Complex. Each of the 5 MMUART
+ instance interrupt line is connected to the PolarFire SoC Core Complex PLIC.
+ The MMUART0 instance interrupt line is also available as local interrupt on
+ E51 processor. The MMUART1 instance interrupt onwards are available as local
+ interrupt on the U54_1 processor onwards. e.g. MMUART2 interrupt is available
+ as local interrupt on U54_2.
+
+ Interrupt Handlers
+ The MSS MMUART driver supports all types of interrupt triggered by the MSS
+ MMUART. The driver's internal top level interrupt handler identifies the
+ source of the MSS MMUART interrupt and calls the corresponding lower level
+ handler function that you previously registered with the driver through calls
+ to the MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(),
+ MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler()
+ functions. You are responsible for creating these lower level interrupt
+ handlers as part of your application program and registering them with the
+ driver.
+ Note: The PolarFire SoC HAL defines the interrupt handler functions for all
+ 5 MMUART instances(with weak linkage) and assigns them as the interrupt
+ service routines (ISR) for the MSS MMUART interrupt inputs to the
+ PolarFire SoC Core Complex PLIC or the Local interrupts on each of the
+ respective CPUs. The MSS MMUART driver provides the implementation
+ functions all these ISRs from which it calls its own internal top level,
+ interrupt handler function.
+
+ The MSS_UART_enable_irq() and MSS_UART_disable_irq() functions are used to
+ enable or disable the received line status, received data available/character
+ time-out, transmit holding register empty and modem status interrupts at the
+ MSS MMUART level. The MSS_UART_enable_irq() function also enables the MSS
+ MMUART instance interrupt at the PolarFire SoC Core Complex level.
+
+ Note that the MSS_UART_enable_irq() and MSS_UART_disable_irq() and all the
+ calls to set the handler functions assume that the MMUART interrupt is
+ connected to the PolarFire SoC Core Complex PLIC. If you want the MMUART
+ interrupt to appear as a local interrupt to the corresponding HART then you
+ must explicitly call the MSS_UART_enable_local_irq() function. This function
+ will disable the PLIC interrupt (if it was previously enable) and enable the
+ local interrupt on the HART on which this function is being executed.
+
+ Transmitting Data
+ Interrupt-driven transmit is initiated by a call to MSS_UART_irq_tx(),
+ specifying the block of data to transmit. Your application is then free to
+ perform other tasks and inquire later whether transmit has completed by
+ calling the MSS_UART_tx_complete() function. The MSS_UART_irq_tx() function
+ enables the UART's transmit holding register empty (THRE) interrupt and then,
+ when the interrupt goes active, the driver's default THRE interrupt handler
+ transfers the data block to the UART until the entire block is transmitted.
+ Note: You can use the MSS_UART_set_tx_handler() function to assign an
+ alternative handler to the THRE interrupt. In this case, you must not
+ use the MSS_UART_irq_tx() function to initiate the transmit, as this
+ will re-assign the driver's default THRE interrupt handler to the THRE
+ interrupt. Instead, your alternative THRE interrupt handler must include
+ a call to the MSS_UART_fill_tx_fifo() function to transfer the data to
+ the UART.
+
+ Receiving Data
+ Interrupt-driven receive is performed by first calling
+ MSS_UART_set_rx_handler() to register a receive handler function that will be
+ called by the driver whenever receive data is available. You must provide this
+ receive handler function which must include a call to the MSS_UART_get_rx()
+ function to actually read the received data.
+
+ -----------
+ UART Status
+ -----------
+ The function MSS_UART_get_rx_status() is used to read the receiver error
+ status. This function returns the overrun, parity, framing, break, and FIFO
+ error status of the receiver.
+ The function MSS_UART_get_tx_status() is used to read the transmitter status.
+ This function returns the transmit empty (TEMT) and transmit holding register
+ empty (THRE) status of the transmitter.
+ The function MSS_UART_get_modem_status() is used to read the modem status
+ flags. This function returns the current value of the modem status register.
+
+ --------
+ Loopback
+ --------
+ The MSS_UART_set_loopback() function can be used to locally loopback the Tx
+ and Rx lines of a UART. This is not to be confused with the loopback of UART0
+ to UART1, which can be achieved through the microprocessor subsystem's system
+ registers.
+
+ *//*=========================================================================*/
+#ifndef __MSS_UART_H_
+#define __MSS_UART_H_ 1
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************************************************************//**
+ Baud rates
+ ==========
+ The following definitions are used to specify standard baud rates as a
+ parameter to the MSS_UART_init() function.
+
+ | Constant | Description |
+ |----------------------|------------------|
+ | MSS_UART_110_BAUD | 110 baud rate |
+ | MSS_UART_300_BAUD | 300 baud rate |
+ | MSS_UART_600_BAUD | 600 baud rate |
+ | MSS_UART_1200_BAUD | 1200 baud rate |
+ | MSS_UART_2400_BAUD | 2400 baud rate |
+ | MSS_UART_4800_BAUD | 4800 baud rate |
+ | MSS_UART_9600_BAUD | 9600 baud rate |
+ | MSS_UART_19200_BAUD | 19200 baud rate |
+ | MSS_UART_38400_BAUD | 38400 baud rate |
+ | MSS_UART_57600_BAUD | 57600 baud rate |
+ | MSS_UART_115200_BAUD | 115200 baud rate |
+ | MSS_UART_230400_BAUD | 230400 baud rate |
+ | MSS_UART_460800_BAUD | 460800 baud rate |
+ | MSS_UART_921600_BAUD | 921600 baud rate |
+
+ */
+#define MSS_UART_110_BAUD 110U
+#define MSS_UART_300_BAUD 300U
+#define MSS_UART_600_BAUD 600U
+#define MSS_UART_1200_BAUD 1200U
+#define MSS_UART_2400_BAUD 2400U
+#define MSS_UART_4800_BAUD 4800U
+#define MSS_UART_9600_BAUD 9600U
+#define MSS_UART_19200_BAUD 19200U
+#define MSS_UART_38400_BAUD 38400U
+#define MSS_UART_57600_BAUD 57600U
+#define MSS_UART_115200_BAUD 115200U
+#define MSS_UART_230400_BAUD 230400U
+#define MSS_UART_460800_BAUD 460800U
+#define MSS_UART_921600_BAUD 921600U
+
+/***************************************************************************//**
+ Data Bits Length
+ ================
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |----------------------|----------------------------|
+ | MSS_UART_DATA_5_BITS | 5 bits of data transmitted |
+ | MSS_UART_DATA_6_BITS | 6 bits of data transmitted |
+ | MSS_UART_DATA_7_BITS | 7 bits of data transmitted |
+ | MSS_UART_DATA_8_BITS | 8 bits of data transmitted |
+
+ */
+#define MSS_UART_DATA_5_BITS ((uint8_t) 0x00)
+#define MSS_UART_DATA_6_BITS ((uint8_t) 0x01)
+#define MSS_UART_DATA_7_BITS ((uint8_t) 0x02)
+#define MSS_UART_DATA_8_BITS ((uint8_t) 0x03)
+
+/***************************************************************************//**
+ Parity
+ ======
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |-------------------------|--------------------------|
+ | MSS_UART_NO_PARITY | No parity |
+ | MSS_UART_ODD_PARITY | Odd Parity |
+ | MSS_UART_EVEN_PARITY | Even parity |
+ | MSS_UART_STICK_PARITY_0 | Stick parity bit to zero |
+ | MSS_UART_STICK_PARITY_1 | Stick parity bit to one |
+
+ */
+#define MSS_UART_NO_PARITY ((uint8_t) 0x00)
+#define MSS_UART_ODD_PARITY ((uint8_t) 0x08)
+#define MSS_UART_EVEN_PARITY ((uint8_t) 0x18)
+#define MSS_UART_STICK_PARITY_0 ((uint8_t) 0x38)
+#define MSS_UART_STICK_PARITY_1 ((uint8_t) 0x28)
+
+/***************************************************************************//**
+ Number of Stop Bits
+ ===================
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |---------------------------|--------------------------|
+ | MSS_UART_ONE_STOP_BIT | One stop bit |
+ | MSS_UART_ONEHALF_STOP_BIT | One and a half stop bits |
+ | MSS_UART_TWO_STOP_BITS | Two stop bits |
+
+ */
+#define MSS_UART_ONE_STOP_BIT ((uint8_t) 0x00)
+#define MSS_UART_ONEHALF_STOP_BIT ((uint8_t) 0x04)
+#define MSS_UART_TWO_STOP_BITS ((uint8_t) 0x04)
+
+/***************************************************************************//**
+ Receiver Error Status
+ =====================
+ The following defines are used to determine the UART receiver error type.
+ These bit mask constants are used with the return value of the
+ MSS_UART_get_rx_status() function to find out if any errors occurred while
+ receiving data.
+
+
+ | Constant | Description |
+ |------------------------|--------------------------------------------|
+ | MSS_UART_NO_ERROR | No error bit mask (0x00) |
+ | MSS_UART_OVERUN_ERROR | Overrun error bit mask (0x02) |
+ | MSS_UART_PARITY_ERROR | Parity error bit mask (0x04) |
+ | MSS_UART_FRAMING_ERROR | Framing error bit mask (0x08) |
+ | MSS_UART_BREAK_ERROR | Break error bit mask (0x10) |
+ | MSS_UART_FIFO_ERROR | FIFO error bit mask (0x80) |
+ | MSS_UART_INVALID_PARAM | Invalid function parameter bit mask (0xFF) |
+
+ */
+#define MSS_UART_INVALID_PARAM ((uint8_t)0xFF)
+#define MSS_UART_NO_ERROR ((uint8_t)0x00 )
+#define MSS_UART_OVERUN_ERROR ((uint8_t)0x02)
+#define MSS_UART_PARITY_ERROR ((uint8_t)0x04)
+#define MSS_UART_FRAMING_ERROR ((uint8_t)0x08)
+#define MSS_UART_BREAK_ERROR ((uint8_t)0x10)
+#define MSS_UART_FIFO_ERROR ((uint8_t)0x80)
+
+/***************************************************************************//**
+ Transmitter Status
+ ==================
+ The following definitions are used to determine the UART transmitter status.
+ These bit mask constants are used with the return value of the
+ MSS_UART_get_tx_status() function to find out the status of the transmitter.
+
+ | Constant | Description |
+ |------------------|----------------------------------------------------|
+ | MSS_UART_TX_BUSY | Transmitter busy (0x00) |
+ | MSS_UART_THRE | Transmitter holding register empty bit mask (0x20) |
+ | MSS_UART_TEMT | Transmitter empty bit mask (0x40) |
+
+ */
+#define MSS_UART_TX_BUSY ((uint8_t) 0x00)
+#define MSS_UART_THRE ((uint8_t) 0x20)
+#define MSS_UART_TEMT ((uint8_t) 0x40)
+
+/***************************************************************************//**
+ Modem Status
+ ============
+ The following defines are used to determine the modem status. These bit
+ mask constants are used with the return value of the
+ MSS_UART_get_modem_status() function to find out the modem status of
+ the UART.
+
+ | Constant | Description |
+ |---------------|-------------------------------------------------|
+ | MSS_UART_DCTS | Delta clear to send bit mask (0x01) |
+ | MSS_UART_DDSR | Delta data set ready bit mask (0x02) |
+ | MSS_UART_TERI | Trailing edge of ring indicator bit mask (0x04) |
+ | MSS_UART_DDCD | Delta data carrier detect bit mask (0x08) |
+ | MSS_UART_CTS | Clear to send bit mask (0x10) |
+ | MSS_UART_DSR | Data set ready bit mask (0x20) |
+ | MSS_UART_RI | Ring indicator bit mask (0x40) |
+ | MSS_UART_DCD | Data carrier detect bit mask (0x80) |
+
+ */
+#define MSS_UART_DCTS ((uint8_t) 0x01)
+#define MSS_UART_DDSR ((uint8_t) 0x02)
+#define MSS_UART_TERI ((uint8_t) 0x04)
+#define MSS_UART_DDCD ((uint8_t) 0x08)
+#define MSS_UART_CTS ((uint8_t) 0x10)
+#define MSS_UART_DSR ((uint8_t) 0x20)
+#define MSS_UART_RI ((uint8_t) 0x40)
+#define MSS_UART_DCD ((uint8_t) 0x80)
+
+/***************************************************************************//**
+ This typedef specifies the irq_mask parameter for the MSS_UART_enable_irq()
+ and MSS_UART_disable_irq() functions. The driver defines a set of bit masks
+ that are used to build the value of the irq_mask parameter. A bitwise OR of
+ these bit masks is used to enable or disable multiple MSS MMUART interrupts.
+ */
+typedef uint16_t mss_uart_irq_t;
+
+/***************************************************************************//**
+ MSS MMUART Interrupts
+ =====================
+ The following defines specify the interrupt masks to enable and disable MSS
+ MMUART interrupts. They are used to build the value of the irq_mask parameter
+ for the MSS_UART_enable_irq() and MSS_UART_disable_irq() functions. A bitwise
+ OR of these constants is used to enable or disable multiple interrupts.
+
+
+ | Constant | Description |
+ |--------------------|---------------------------------------------------------------|
+ | MSS_UART_RBF_IRQ | Receive Data Available Interrupt bit mask (0x001) |
+ | MSS_UART_TBE_IRQ | Transmitter Holding Register Empty interrupt bit mask (0x002) |
+ | MSS_UART_LS_IRQ | Receiver Line Status interrupt bit mask (0x004) |
+ | MSS_UART_MS_IRQ | Modem Status interrupt bit mask (0x008) |
+ | MSS_UART_RTO_IRQ | Receiver time-out interrupt bit mask (0x010) |
+ | MSS_UART_NACK_IRQ | NACK / ERR signal interrupt bit mask (0x020) |
+ | MSS_UART_PIDPE_IRQ | PID parity error interrupt bit mask (0x040) |
+ | MSS_UART_LINB_IRQ | LIN break detection interrupt bit mask (0x080) |
+ | MSS_UART_LINS_IRQ | LIN Sync detection interrupt bit mask (0x100) |
+
+ */
+#define MSS_UART_RBF_IRQ 0x001
+#define MSS_UART_TBE_IRQ 0x002
+#define MSS_UART_LS_IRQ 0x004
+#define MSS_UART_MS_IRQ 0x008
+#define MSS_UART_RTO_IRQ 0x010
+#define MSS_UART_NACK_IRQ 0x020
+#define MSS_UART_PIDPE_IRQ 0x040
+#define MSS_UART_LINB_IRQ 0x080
+#define MSS_UART_LINS_IRQ 0x100
+#define MSS_UART_INVALID_IRQ UINT16_MAX
+
+/***************************************************************************//**
+ This enumeration specifies the receiver FIFO trigger level. This is the number
+ of bytes that must be received before the UART generates a receive data
+ available interrupt. It provides the allowed values for the
+ MSS_UART_set_rx_handler() function trigger_level parameter.
+ */
+typedef enum {
+ MSS_UART_FIFO_SINGLE_BYTE = 0x00,
+ MSS_UART_FIFO_FOUR_BYTES = 0x40,
+ MSS_UART_FIFO_EIGHT_BYTES = 0x80,
+ MSS_UART_FIFO_FOURTEEN_BYTES = 0xC0,
+ MSS_UART_FIFO_INVALID_TRIG_LEVEL
+
+} mss_uart_rx_trig_level_t;
+
+/***************************************************************************//**
+ This enumeration specifies the loopback configuration of the UART. It provides
+ the allowed values for the MSS_UART_set_loopback() function's loopback
+ parameter. Use MSS_UART_LOCAL_LOOPBACK_ON to set up the UART to locally
+ loopback its Tx and Rx lines. Use MSS_UART_REMOTE_LOOPBACK_ON to set up the
+ UART in remote loopback mode.
+ */
+typedef enum {
+ MSS_UART_LOCAL_LOOPBACK_OFF,
+ MSS_UART_LOCAL_LOOPBACK_ON,
+ MSS_UART_REMOTE_LOOPBACK_OFF,
+ MSS_UART_REMOTE_LOOPBACK_ON,
+ MSS_UART_AUTO_ECHO_OFF,
+ MSS_UART_AUTO_ECHO_ON,
+ MSS_UART_INVALID_LOOPBACK
+
+} mss_uart_loopback_t;
+
+/***************************************************************************//**
+ IrDA input / output polarity.
+ This enumeration specifies the RZI modem polarity for input and output signals.
+ This is passed as parameters in MSS_UART_irda_init() function.
+ */
+typedef enum {
+ MSS_UART_ACTIVE_LOW = 0u,
+ MSS_UART_ACTIVE_HIGH = 1u,
+ MSS_UART_INVALID_POLARITY
+
+} mss_uart_rzi_polarity_t;
+
+/***************************************************************************//**
+ IrDA input / output pulse width.
+ This enumeration specifies the RZI modem pulse width for input and output
+ signals. This is passed as parameters in MSS_UART_irda_init() function.
+ */
+typedef enum {
+ MSS_UART_3_BY_16 = 0u,
+ MSS_UART_1_BY_4 = 1u,
+ MSS_UART_INVALID_PW
+
+} mss_uart_rzi_pulsewidth_t;
+
+/***************************************************************************//**
+ Tx / Rx endianess.
+ This enumeration specifies the MSB first or LSB first for MSS UART transmitter
+ and receiver. The parameter of this type shall be passed in
+ MSS_UART_set_rx_endian()and MSS_UART_set_tx_endian() functions.
+ */
+typedef enum {
+ MSS_UART_LITTLEEND,
+ MSS_UART_BIGEND,
+ MSS_UART_INVALID_ENDIAN
+
+} mss_uart_endian_t;
+
+/***************************************************************************//**
+ Glitch filter length.
+ This enumeration specifies the glitch filter length. The function
+ MSS_UART_set_filter_length() accepts the parameter of this type.
+ */
+typedef enum {
+ MSS_UART_LEN0 = 0,
+ MSS_UART_LEN1 = 1,
+ MSS_UART_LEN2 = 2,
+ MSS_UART_LEN3 = 3,
+ MSS_UART_LEN4 = 4,
+ MSS_UART_LEN5 = 5,
+ MSS_UART_LEN6 = 6,
+ MSS_UART_LEN7 = 7,
+ MSS_UART_INVALID_FILTER_LENGTH = 8
+
+} mss_uart_filter_length_t;
+
+/***************************************************************************//**
+ TXRDY and RXRDY mode.
+ This enumeration specifies the TXRDY and RXRDY signal modes. The function
+ MSS_UART_set_ready_mode() accepts the parameter of this type.
+ */
+typedef enum {
+ MSS_UART_READY_MODE0,
+ MSS_UART_READY_MODE1,
+ MSS_UART_INVALID_READY_MODE
+
+} mss_uart_ready_mode_t;
+
+/***************************************************************************//**
+ USART mode of operation.
+ This enumeration specifies the mode of operation of MSS UART when operating
+ as USART. The function MSS_UART_set_usart_mode() accepts the parameter of this
+ type.
+ */
+typedef enum {
+ MSS_UART_ASYNC_MODE = 0,
+ MSS_UART_SYNC_SLAVE_POS_EDGE_CLK = 1,
+ MSS_UART_SYNC_SLAVE_NEG_EDGE_CLK = 2,
+ MSS_UART_SYNC_MASTER_POS_EDGE_CLK = 3,
+ MSS_UART_SYNC_MASTER_NEG_EDGE_CLK = 4,
+ MSS_UART_INVALID_SYNC_MODE = 5
+
+} mss_uart_usart_mode_t;
+
+
+typedef enum {
+ MSS_UART0_LO = 0,
+ MSS_UART1_LO = 1,
+ MSS_UART2_LO = 2,
+ MSS_UART3_LO = 3,
+ MSS_UART4_LO = 4,
+ MSS_UART0_HI = 5,
+ MSS_UART1_HI = 6,
+ MSS_UART2_HI = 7,
+ MSS_UART3_HI = 8,
+ MSS_UAR4_HI = 9,
+
+} mss_uart_num_t;
+
+/***************************************************************************//**
+ MSS UART instance type.
+ This is type definition for MSS UART instance. You need to create and
+ maintain a record of this type. This holds all data regarding the MSS UART
+ instance
+ */
+typedef struct mss_uart_instance mss_uart_instance_t;
+
+/***************************************************************************//**
+ Interrupt handler prototype.
+ This typedef specifies the function prototype for MSS UART interrupt handlers.
+ All interrupt handlers registered with the MSS UART driver must be of this type.
+ The interrupt handlers are registered with the driver through the
+ MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(),
+ MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler()
+ functions.
+ The this_uart parameter is a pointer to either g_mss_uart0 or g_mss_uart1 to
+ identify the MSS UART to associate with the handler function.
+ */
+typedef void (*mss_uart_irq_handler_t)( mss_uart_instance_t * this_uart );
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------- UART -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+typedef struct
+{
+ union
+ {
+ volatile const uint8_t RBR;
+ volatile uint8_t THR;
+ volatile uint8_t DLR;
+ uint32_t RESERVED0;
+ };
+
+ union
+ {
+ volatile uint8_t DMR;
+ volatile uint8_t IER;
+ uint32_t RESERVED1;
+ };
+
+ union
+ {
+ volatile uint8_t IIR;
+ volatile uint8_t FCR;
+ uint32_t RESERVED2;
+ };
+
+ volatile uint8_t LCR;
+ uint8_t RESERVED3[3];
+
+ volatile uint8_t MCR;
+ uint8_t RESERVED4[3];
+
+ volatile const uint8_t LSR;
+ uint8_t RESERVED5[3];
+
+ volatile const uint8_t MSR;
+ uint8_t RESERVED6[3];
+
+ volatile uint8_t SR;
+ uint8_t RESERVED7[7];
+
+ volatile uint8_t IEM;
+ uint8_t RESERVED8[3];
+
+ volatile uint8_t IIM;
+ uint8_t RESERVED9[7];
+
+ volatile uint8_t MM0;
+ uint8_t RESERVED10[3];
+
+ volatile uint8_t MM1;
+ uint8_t RESERVED11[3];
+
+ volatile uint8_t MM2;
+ uint8_t RESERVED12[3];
+
+ volatile uint8_t DFR;
+ uint8_t RESERVED13[7];
+
+ volatile uint8_t GFR;
+ uint8_t RESERVED14[3];
+
+ volatile uint8_t TTG;
+ uint8_t RESERVED15[3];
+
+ volatile uint8_t RTO;
+ uint8_t RESERVED16[3];
+
+ volatile uint8_t ADR;
+ uint8_t RESERVED17[3];
+
+} MSS_UART_TypeDef;
+
+
+/***************************************************************************//**
+ mss_uart_instance.
+ There is one instance of this structure for each instance of the
+ microprocessor subsystem's UARTs. Instances of this structure are used to
+ identify a specific UART. A pointer to an initialized instance of the
+ mss_uart_instance_t structure is passed as the first parameter to
+ MSS UART driver functions to identify which UART should perform the
+ requested operation.
+ */
+struct mss_uart_instance{
+ /* CMSIS related defines identifying the UART hardware. */
+ MSS_UART_TypeDef * hw_reg; /*!< Pointer to UART registers. */
+ uint32_t baudrate; /*!< Operating baud rate. */
+ uint8_t lineconfig; /*!< Line configuration parameters. */
+ uint8_t status; /*!< Sticky line status. */
+
+ /* transmit related info (used with interrupt driven transmit): */
+ const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */
+ uint32_t tx_buff_size; /*!< Transmit buffer size. */
+ uint32_t tx_idx; /*!< Index within transmit buffer of next byte to transmit.*/
+
+ /* line status interrupt handler:*/
+ mss_uart_irq_handler_t linests_handler; /*!< Pointer to user registered line status handler. */
+ /* receive interrupt handler:*/
+ mss_uart_irq_handler_t rx_handler; /*!< Pointer to user registered receiver handler. */
+ /* transmit interrupt handler:*/
+ mss_uart_irq_handler_t tx_handler; /*!< Pointer to user registered transmit handler. */
+ /* modem status interrupt handler:*/
+ mss_uart_irq_handler_t modemsts_handler; /*!< Pointer to user registered modem status handler. */
+ /* receiver timeout interrupt handler */
+ mss_uart_irq_handler_t rto_handler; /*!< Pointer to user registered receiver timeout handler. */
+ /* NACK interrupt handler */
+ mss_uart_irq_handler_t nack_handler; /*!< Pointer to user registered NACK handler. */
+ /* PID parity perror interrupt handler */
+ mss_uart_irq_handler_t pid_pei_handler; /*!< Pointer to user registered PID parity error handler. */
+ /* LIN break interrupt handler */
+ mss_uart_irq_handler_t break_handler; /*!< Pointer to user registered LIN break handler. */
+ /* LIN sync detection interrupt handler */
+ mss_uart_irq_handler_t sync_handler; /*!< Pointer to user registered LIN sync detection handler. */
+ uint8_t local_irq_enabled; /*!< check if local interrupt were enabled on this instance*/
+ void* user_data; /*!< Pointer to user provided pointer for user specific use. */
+
+};
+
+/***************************************************************************//**
+ This instance of mss_uart_instance_t holds all data related to the operations
+ performed by the MMUART. The function MSS_UART_init() initializes this structure.
+ A pointer to g_mss_uart0_lo is passed as the first parameter to MSS UART driver
+ functions to indicate that MMUART0 should perform the requested operation.
+ */
+
+extern mss_uart_instance_t g_mss_uart0_lo;
+extern mss_uart_instance_t g_mss_uart1_lo;
+extern mss_uart_instance_t g_mss_uart2_lo;
+extern mss_uart_instance_t g_mss_uart3_lo;
+extern mss_uart_instance_t g_mss_uart4_lo;
+
+extern mss_uart_instance_t g_mss_uart0_hi;
+extern mss_uart_instance_t g_mss_uart1_hi;
+extern mss_uart_instance_t g_mss_uart2_hi;
+extern mss_uart_instance_t g_mss_uart3_hi;
+extern mss_uart_instance_t g_mss_uart4_hi;
+
+
+/***************************************************************************//**
+ The MSS_UART_init() function initializes and configures one of the PolarFire SoC
+ MSS UARTs with the configuration passed as a parameter. The configuration
+ parameters are the baud_rate which is used to generate the baud value and the
+ line_config which is used to specify the line configuration (bit length,
+ stop bits and parity).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit length,
+ number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The MSS_UART_lin_init() function is used to initialize the MSS UART for
+ LIN mode of operation. The configuration parameters are the baud_rate which is
+ used to generate the baud value and the line_config which is used to specify
+ the line configuration (bit length, stop bits and parity).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit length,
+ number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_lin_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The MSS_UART_irda_init() function is used to initialize the MSS UART instance
+ referenced by the parameter this_uart for IrDA mode of operation. This
+ function must be called before calling any other IrDA functionality specific
+ functions.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit
+ length, number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_irda_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT,
+ MSS_UART_ACTIVE_LOW,
+ MSS_UART_ACTIVE_LOW,
+ MSS_UART_3_BY_16);
+ @endcode
+ */
+void
+MSS_UART_irda_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config,
+ mss_uart_rzi_polarity_t rxpol,
+ mss_uart_rzi_polarity_t txpol,
+ mss_uart_rzi_pulsewidth_t pw
+);
+
+/***************************************************************************//**
+ The MSS_UART_smartcard_init() function is used to initialize the MSS UART
+ for ISO 7816 (smartcard) mode of operation. The configuration parameters are
+ the baud_rate which is used to generate the baud value and the line_config
+ which is used to specify the line configuration (bit length, stop bits and
+ parity). This function disables all other modes of the MSS UART instance
+ pointed by the parameter this_uart.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit
+ length, number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_smartcard_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_smartcard_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The function MSS_UART_polled_tx() is used to transmit data. It transfers the
+ contents of the transmitter data buffer, passed as a function parameter, into
+ the UART's hardware transmitter FIFO. It returns when the full content of the
+ transmit data buffer has been transferred to the UART's transmit FIFO. It is
+ safe to release or reuse the memory used as the transmitter data buffer once
+ this function returns.
+
+ Note: This function reads the UART's line status register (LSR) to poll
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. It
+ transfers data to the transmitter FIFO in blocks of 16 bytes or less and
+ allows the FIFO to empty before transferring the next block of data.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param pbuff
+ The pbuff parameter is a pointer to a buffer containing the data to
+ be transmitted.
+
+ @param tx_size
+ The tx_size parameter specifies the size, in bytes, of the data to
+ be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello World";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ SS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx(&g_mss_uart0_lo, message, sizeof(message));
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_polled_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+
+/***************************************************************************//**
+ The function MSS_UART_polled_tx_string() is used to transmit a NUL ('\0')
+ terminated string. It transfers the text string, from the buffer starting at
+ the address pointed to by p_sz_string into the UART's hardware transmitter
+ FIFO. It returns when the complete string has been transferred to the UART's
+ transmit FIFO. It is safe to release or reuse the memory used as the string
+ buffer once this function returns.
+
+ Note: This function reads the UART's line status register (LSR) to poll
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. It
+ transfers data to the transmitter FIFO in blocks of 16 bytes or less and
+ allows the FIFO to empty before transferring the next block of data.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param p_sz_string
+ The p_sz_string parameter is a pointer to a buffer containing the NUL ('\0')
+ terminated string to be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello World";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx_string(&g_mss_uart0_lo, message);
+
+ return(0);
+ }
+ @endcode
+
+ */
+void
+MSS_UART_polled_tx_string
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * p_sz_string
+);
+
+/***************************************************************************//**
+ The function MSS_UART_irq_tx() is used to initiate an interrupt-driven
+ transmit. It returns immediately after making a note of the transmit buffer
+ location and enabling transmit interrupts both at the UART and the PolarFire
+ SoC Core Complex PLIC level. This function takes a pointer via the pbuff
+ parameter to a memory buffer containing the data to transmit. The memory
+ buffer specified through this pointer must remain allocated and contain the
+ data to transmit until the transmit completion has been detected through calls
+ to function MSS_UART_tx_complete(). The actual transmission over the serial
+ connection is still in progress until calls to the MSS_UART_tx_complete()
+ function indicate transmit completion.
+
+ Note: The MSS_UART_irq_tx() function enables both the transmit holding
+ register empty (THRE) interrupt in the UART and the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC as part of its implementation.
+
+ Note: The MSS_UART_irq_tx() function assigns an internal default transmit
+ interrupt handler function to the UART's THRE interrupt. This interrupt
+ handler overrides any custom interrupt handler that you may have previously
+ registered using the MSS_UART_set_tx_handler() function.
+
+ Note: The MSS_UART_irq_tx() function's default transmit interrupt
+ handler disables the UART's THRE interrupt when all of the data has
+ been transferred to the UART's transmit FIFO.
+
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param pbuff
+ The pbuff parameter is a pointer to a buffer containing the data
+ to be transmitted.
+
+ @param tx_size
+ The tx_size parameter specifies the size, in bytes, of the data
+ to be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_irq_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff));
+
+ while(0 == MSS_UART_tx_complete(&g_mss_uart0_lo))
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_irq_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_tx_complete() function is used to find out if the
+ interrupt-driven transmit previously initiated through a call to
+ MSS_UART_irq_tx() is complete. This is typically used to find out when it is
+ safe to reuse or release the memory buffer holding transmit data.
+
+ Note: The transfer of all of the data from the memory buffer to the UART's
+ transmit FIFO and the actual transmission over the serial connection are both
+ complete when a call to the MSS_UART_tx_complete() function indicates transmit
+ completion.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function return a non-zero value if transmit has completed, otherwise
+ it returns zero.
+
+ Example:
+ See the MSS_UART_irq_tx() function for an example that uses the
+ MSS_UART_tx_complete() function.
+
+ */
+int8_t
+MSS_UART_tx_complete
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_rx() function reads the content of the UART receiver's FIFO
+ and stores it in the receive buffer that is passed via the rx_buff function
+ parameter. It copies either the full contents of the FIFO into the receive
+ buffer, or just enough data from the FIFO to fill the receive buffer,
+ dependent upon the size of the receive buffer passed by the buff_size
+ parameter. The MSS_UART_get_rx() function returns the number of bytes copied
+ into the receive buffer .This function is non-blocking and will return 0
+ immediately if no data has been received.
+
+ Note: The MSS_UART_get_rx() function reads and accumulates the receiver
+ status of the MSS UART instance before reading each byte from the receiver's
+ data register/FIFO. This allows the driver to maintain a sticky record of any
+ receiver errors that occur as the UART receives each data byte; receiver
+ errors would otherwise be lost after each read from the receiver's data
+ register. A call to the MSS_UART_get_rx_status() function returns any receiver
+ errors accumulated during the execution of the MSS_UART_get_rx() function.
+
+ Note: If you need to read the error status for each byte received, set
+ the buff_size to 1 and read the receive line error status for each byte
+ using the MSS_UART_get_rx_status() function.
+
+ The MSS_UART_get_rx() function can be used in polled mode, where it is called
+ at regular intervals to find out if any data has been received, or in
+ interrupt driven-mode, where it is called as part of a receive handler that is
+ called by the driver as a result of data being received.
+
+ Note: In interrupt driven mode you should call the MSS_UART_get_rx()
+ function as part of the receive handler function that you register with
+ the MSS UART driver through a call to MSS_UART_set_rx_handler().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param rx_buff
+ The rx_buff parameter is a pointer to a buffer where the received
+ data is copied.
+
+ @param buff_size
+ The buff_size parameter specifies the size of the receive buffer in bytes.
+
+ @return
+ This function returns the number of bytes that were copied into the
+ rx_buff buffer. It returns 0 if no data has been received.
+
+ Polled mode example:
+ @code
+ int main( void )
+ {
+ uint8_t rx_buff[RX_BUFF_SIZE];
+ uint32_t rx_idx = 0;
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ while(1)
+ {
+ rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_buff, sizeof(rx_buff));
+ if(rx_size > 0)
+ {
+ process_rx_data(rx_buff, rx_size);
+ }
+ task_a();
+ task_b();
+ }
+ return 0;
+ }
+ @endcode
+
+ Interrupt driven example:
+ @code
+ int main( void )
+ {
+ MSS_UART_init(&g_mss_uart1,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart1,
+ uart1_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ while(1)
+ {
+ task_a();
+ task_b();
+ }
+ return 0;
+ }
+
+ void uart1_rx_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t rx_buff[RX_BUFF_SIZE];
+ uint32_t rx_idx = 0;
+ rx_size = MSS_UART_get_rx(this_uart, rx_buff, sizeof(rx_buff));
+ process_rx_data(rx_buff, rx_size);
+ }
+ @endcode
+ */
+size_t
+MSS_UART_get_rx
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t * rx_buff,
+ size_t buff_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_handler() function is used to register a receive handler
+ function that is called by the driver when a UART receive data available (RDA)
+ interrupt occurs. You must create and register the receive handler function
+ to suit your application and it must include a call to the MSS_UART_get_rx()
+ function to actually read the received data.
+
+ Note: The MSS_UART_set_rx_handler() function enables both the RDA
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part
+ of its implementation.
+
+ Note: You can disable the RDA interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a receive interrupt handler function
+ provided by your application that will be called as a result of a UART RDA
+ interrupt. This handler function must be of type mss_uart_irq_handler_t.
+
+ @param trigger_level
+ The trigger_level parameter is the receive FIFO trigger level. This
+ specifies the number of bytes that must be received before the UART
+ triggers an RDA interrupt.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ #define RX_BUFF_SIZE 64
+
+ uint8_t g_rx_buff[RX_BUFF_SIZE];
+
+ void uart0_rx_handler(mss_uart_instance_t * this_uart)
+ {
+ MSS_UART_get_rx(this_uart, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff));
+ }
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart0_lo,
+ uart0_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_rx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler,
+ mss_uart_rx_trig_level_t trigger_level
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_loopback() function is used to locally loop-back the Tx and
+ Rx lines of a UART. This is not to be confused with the loop-back of UART0
+ to UART1, which can be achieved through the microprocessor subsystem's
+ system registers.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param loopback
+ The loopback parameter indicates whether or not the UART's transmit and
+ receive lines should be looped back. Allowed values are as follows:
+ - MSS_UART_LOCAL_LOOPBACK_ON
+ - MSS_UART_LOCAL_LOOPBACK_OFF
+ - MSS_UART_REMOTE_LOOPBACK_ON
+ - MSS_UART_REMOTE_LOOPBACK_OFF
+ - MSS_UART_AUTO_ECHO_ON
+ - MSS_UART_AUTO_ECHO_OFF
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_loopback(&g_mss_uart0_lo, MSS_UART_LOCAL_LOOPBACK_OFF);
+ @endcode
+ */
+void
+MSS_UART_set_loopback
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_loopback_t loopback
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_irq() function enables the MSS UART interrupts specified
+ by the irq_mask parameter. The irq_mask parameter identifies the MSS UART
+ interrupts by bit position, as defined in the interrupt enable register (IER)
+ of MSS UART. The MSS UART interrupts and their identifying irq_mask bit
+ positions are as follows:
+ When an irq_mask bit position is set to 1, this function enables the
+ corresponding MSS UART interrupt in the IER register. When an irq_mask bit
+ position is set to 0, the state of the corresponding interrupt remains
+ unchanged in the IER register.
+
+ Note: The MSS_UART_enable_irq() function also enables the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param irq_mask
+ The irq_mask parameter is used to select which of the MSS UART's interrupts
+ you want to enable. The allowed value for the irq_mask parameter is one of
+ the following constants or a bitwise OR of more than one:
+ - MSS_UART_RBF_IRQ (bit mask = 0x001)
+ - MSS_UART_TBE_IRQ (bit mask = 0x002)
+ - MSS_UART_LS_IRQ (bit mask = 0x004)
+ - MSS_UART_MS_IRQ (bit mask = 0x008)
+ - MSS_UART_RTO_IRQ (bit mask = 0x010)
+ - MSS_UART_NACK_IRQ (bit mask = 0x020)
+ - MSS_UART_PIDPE_IRQ (bit mask = 0x040)
+ - MSS_UART_LINB_IRQ (bit mask = 0x080)
+ - MSS_UART_LINS_IRQ (bit mask = 0x100)
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_irq(&g_mss_uart0_lo,(MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ));
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_enable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_irq() function disables the MSS UART interrupts specified
+ by the irq_mask parameter. The irq_mask parameter identifies the MSS UART
+ interrupts by bit position, as defined in the interrupt enable register (IER)
+ of MSS UART. The MSS UART interrupts and their identifying bit positions are
+ as follows:
+ When an irq_mask bit position is set to 1, this function disables the
+ corresponding MSS UART interrupt in the IER register. When an irq_mask bit
+ position is set to 0, the state of the corresponding interrupt remains
+ unchanged in the IER register.
+
+ Note: If you disable all four of the UART's interrupts, the
+ MSS_UART_disable_irq() function also disables the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param irq_mask
+ The irq_mask parameter is used to select which of the MSS UART's interrupts
+ you want to disable. The allowed value for the irq_mask parameter is one of
+ the following constants or a bitwise OR of more than one:
+ - MSS_UART_RBF_IRQ (bit mask = 0x001)
+ - MSS_UART_TBE_IRQ (bit mask = 0x002)
+ - MSS_UART_LS_IRQ (bit mask = 0x004)
+ - MSS_UART_MS_IRQ (bit mask = 0x008)
+ - MSS_UART_RTO_IRQ (bit mask = 0x010)
+ - MSS_UART_NACK_IRQ (bit mask = 0x020)
+ - MSS_UART_PIDPE_IRQ (bit mask = 0x040)
+ - MSS_UART_LINB_IRQ (bit mask = 0x080)
+ - MSS_UART_LINS_IRQ (bit mask = 0x100)
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_irq(&g_mss_uart0_lo,(MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ));
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_disable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_pidpei_handler() function is used assign a custom interrupt
+ handler for the PIDPEI (PID parity error interrupt) when the MSS UART is
+ operating in LIN mode.
+
+ Note: The MSS_UART_set_pidpei_handler() function enables both the PIDPEI
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the PIDPEI interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_pidpei_handler(&g_mss_uart0_lo, my_pidpei_handler);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_pidpei_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_linbreak_handler () function is used assign a custom
+ interrupt handler for the LIN Break detection interrupt when the MSS UART
+ is operating in LIN mode.
+
+ Note: The MSS_UART_set_linbreak_handler() function enables both the LIN
+ BREAK interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the LIN BREAK interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_linbreak_handler(&g_mss_uart0_lo, my_break_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_linbreak_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_linsync_handler() function is used assign a custom interrupt
+ handler for the LIN Sync character detection interrupt when the MSS UART is
+ operating in LIN mode.
+
+ Note: The MSS_UART_set_linsync_handler() function enables both the LIN
+ SYNC interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the LIN SYNC interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_linsync_handler(&g_mss_uart0_lo, my_linsync_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_linsync_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_nack_handler() function is used assign a custom interrupt
+ handler for the NACK character detection interrupt when the MSS UART
+ is operating in Smartcard mode.
+
+ Note: The MSS_UART_set_nack_handler() function enables both the NAK
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the NAK interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_nack_handler(&g_mss_uart0_lo, my_nack_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_nack_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_timeout_handler() function is used assign a custom
+ interrupt handler for the receiver timeout interrupt when the MSS UART is
+ operating in mode. It finds application in IrDA mode of operation.
+
+ Note: The MSS_UART_set_rx_timeout_handler() function enables both the
+ time-out interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the RX time-out interrupt when required by calling
+ the MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_timeout_handler(&g_mss_uart0_lo, my_rxtimeout_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_rx_timeout_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rxstatus_handler() function is used to register a receiver
+ status handler function that is called by the driver when a UART receiver
+ line status (RLS) interrupt occurs. You must create and register the handler
+ function to suit your application.
+
+ Note: The MSS_UART_set_rxstatus_handler() function enables both the RLS
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+ Note: You can disable the RLS interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a receiver line status interrupt
+ handler function provided by your application that will be called as a
+ result of a UART RLS interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ void uart_rxsts_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_rx_status(this_uart);
+ if(status & MSS_UART_OVERUN_ERROR)
+ {
+ discard_rx_data();
+ }
+ }
+
+ int main(void)
+ {
+ MSS_UART_init( &g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rxstatus_handler(&g_mss_uart0_lo, uart_rxsts_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_rxstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_tx_handler() function is used to register a transmit handler
+ function that is called by the driver when a UART transmit holding register
+ empty (THRE) interrupt occurs. You must create and register the transmit
+ handler function to suit your application. You can use the
+ MSS_UART_fill_tx_fifo() function in your transmit handler function to
+ write data to the transmitter.
+
+ Note: The MSS_UART_set_tx_handler() function enables both the THRE
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+
+ Note: You can disable the THRE interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ Note: The MSS_UART_irq_tx() function does not use the transmit handler
+ function that you register with the MSS_UART_set_tx_handler() function.
+ It uses its own internal THRE interrupt handler function that overrides
+ any custom interrupt handler that you register using the
+ MSS_UART_set_tx_handler() function.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a transmit interrupt handler
+ function provided by your application that will be called as a result
+ of a UART THRE interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ uint8_t * g_tx_buffer;
+ size_t g_tx_size = 0;
+
+ void uart_tx_handler(mss_uart_instance_t * this_uart)
+ {
+ size_t size_in_fifo;
+ size_in_fifo = MSS_UART_fill_tx_fifo(this_uart,
+ (const uint8_t *)g_tx_buffer,
+ g_tx_size);
+
+ if(size_in_fifo == g_tx_size)
+ {
+ g_tx_size = 0;
+ MSS_UART_disable_irq(this_uart, MSS_UART_TBE_IRQ);
+ }
+ else
+ {
+ g_tx_buffer = &g_tx_buffer[size_in_fifo];
+ g_tx_size = g_tx_size - size_in_fifo;
+ }
+ }
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello world";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ g_tx_buffer = message;
+ g_tx_size = sizeof(message);
+
+ MSS_UART_set_tx_handler(&g_mss_uart0_lo, uart_tx_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_tx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_modemstatus_handler() function is used to register a modem
+ status handler function that is called by the driver when a UART modem status
+ (MS) interrupt occurs. You must create and register the handler function to
+ suit your application.
+
+ Note: The MSS_UART_set_modemstatus_handler() function enables both the MS
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+ Note: You can disable the MS interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent
+ upon your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a modem status interrupt handler
+ function provided by your application that will be called as a result
+ of a UART MS interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ void uart_modem_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_modem_status(this_uart);
+ if(status & MSS_UART_CTS)
+ {
+ uart_cts_handler();
+ }
+ }
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_modemstatus_handler(&g_mss_uart0_lo, uart_modem_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+
+void
+MSS_UART_set_modemstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_fill_tx_fifo() function fills the UART's hardware transmitter
+ FIFO with the data found in the transmitter buffer that is passed via the
+ tx_buffer function parameter. If the transmitter FIFO is not empty when
+ the function is called, the function returns immediately without transferring
+ any data to the FIFO; otherwise, the function transfers data from the
+ transmitter buffer to the FIFO until it is full or until the complete
+ contents of the transmitter buffer have been copied into the FIFO. The
+ function returns the number of bytes copied into the UART's transmitter FIFO.
+
+ Note: This function reads the UART's line status register (LSR) to check
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. If
+ THRE is 0, the function returns immediately, without transferring any data
+ to the FIFO. If THRE is 1, the function transfers up to 16 bytes of data
+ to the FIFO and then returns.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param tx_buffer
+ The tx_buffer parameter is a pointer to a buffer containing the data
+ to be transmitted.
+
+ @param tx_size
+ The tx_size parameter is the size in bytes, of the data to be transmitted.
+
+ @return
+ This function returns the number of bytes copied into the UART's
+ transmitter FIFO.
+
+ Example:
+ @code
+ void send_using_interrupt(uint8_t * pbuff, size_t tx_size)
+ {
+ size_t size_in_fifo;
+ size_in_fifo = MSS_UART_fill_tx_fifo(&g_mss_uart0_lo, pbuff, tx_size);
+ }
+ @endcode
+ */
+size_t
+MSS_UART_fill_tx_fifo
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * tx_buffer,
+ size_t tx_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_rx_status() function returns the receiver error status of the
+ MSS UART instance. It reads both the current error status of the receiver from
+ the UART's line status register (LSR) and the accumulated error status from
+ preceding calls to the MSS_UART_get_rx() function, and it combines them using
+ a bitwise OR. It returns the cumulative overrun, parity, framing, break and
+ FIFO error status of the receiver, since the previous call to
+ MSS_UART_get_rx_status(), as an 8-bit encoded value.
+
+ Note: The MSS_UART_get_rx() function reads and accumulates the receiver
+ status of the MSS UART instance before reading each byte from the receiver's
+ data register/FIFO. The driver maintains a sticky record of the cumulative
+ receiver error status, which persists after the MSS_UART_get_rx() function
+ returns. The MSS_UART_get_rx_status() function clears the driver's sticky
+ receiver error record before returning.
+
+ Note: The driver's transmit functions also read the line status
+ register (LSR) as part of their implementation. When the driver reads the
+ LSR, the UART clears any active receiver error bits in the LSR. This could
+ result in the driver losing receiver errors. To avoid any loss of receiver
+ errors, the transmit functions also update the driver's sticky record of the
+ cumulative receiver error status whenever they read the LSR.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns the UART's receiver error status as an 8-bit unsigned
+ integer. The returned value is 0 if no receiver errors occurred. The driver
+ provides a set of bit mask constants that should be compared with and/or
+ used to mask the returned value to determine the receiver error status.
+ When the return value is compared to the following bit masks, a non-zero
+ result indicates that the corresponding error occurred:
+ - MSS_UART_OVERRUN_ERROR (bit mask = 0x02)
+ - MSS_UART_PARITY_ERROR (bit mask = 0x04)
+ - MSS_UART_FRAMING_ERROR (bit mask = 0x08)
+ - MSS_UART_BREAK_ERROR (bit mask = 0x10)
+ - MSS_UART_FIFO_ERROR (bit mask = 0x80)
+
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that no error occurred:
+ - MSS_UART_NO_ERROR (bit mask = 0x00)
+
+ Upon unsuccessful execution, this function returns:
+ - MSS_UART_INVALID_PARAM (bit mask = 0xFF)
+
+ Example:
+ @code
+ uint8_t rx_data[MAX_RX_DATA_SIZE];
+ uint8_t err_status;
+ err_status = MSS_UART_get_rx_status(&g_mss_uart0);
+
+ if(MSS_UART_NO_ERROR == err_status)
+ {
+ rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_data, MAX_RX_DATA_SIZE);
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_rx_status
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_modem_status() function returns the modem status of the
+ MSS UART instance. It reads the modem status register (MSR) and returns
+ the 8 bit value. The bit encoding of the returned value is exactly the
+ same as the definition of the bits in the MSR.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns current state of the UART's MSR as an 8 bit
+ unsigned integer. The driver provides the following set of bit mask
+ constants that should be compared with and/or used to mask the
+ returned value to determine the modem status:
+ - MSS_UART_DCTS (bit mask = 0x01)
+ - MSS_UART_DDSR (bit mask = 0x02)
+ - MSS_UART_TERI (bit mask = 0x04)
+ - MSS_UART_DDCD (bit mask = 0x08)
+ - MSS_UART_CTS (bit mask = 0x10)
+ - MSS_UART_DSR (bit mask = 0x20)
+ - MSS_UART_RI (bit mask = 0x40)
+ - MSS_UART_DCD (bit mask = 0x80)
+
+ Example:
+ @code
+ void uart_modem_status_isr(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_modem_status(this_uart);
+ if( status & MSS_UART_DCTS )
+ {
+ uart_dcts_handler();
+ }
+ if( status & MSS_UART_CTS )
+ {
+ uart_cts_handler();
+ }
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_modem_status
+(
+ const mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_tx_status() function returns the transmitter status of the
+ MSS UART instance. It reads both the UART's line status register (LSR) and
+ returns the status of the transmit holding register empty (THRE) and
+ transmitter empty (TEMT) bits.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns the UART's transmitter status as an 8-bit unsigned
+ integer. The returned value is 0 if the transmitter status bits are not
+ set or the function execution failed. The driver provides a set of bit
+ mask constants that should be compared with and/or used to mask the
+ returned value to determine the transmitter status.
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that the corresponding transmitter status bit is set:
+ - MSS_UART_THRE (bit mask = 0x20)
+ - MSS_UART_TEMT (bit mask = 0x40)
+
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that the transmitter is busy or the function execution
+ failed.
+ - MSS_UART_TX_BUSY (bit mask = 0x00)
+
+ Example:
+ @code
+ uint8_t tx_buff[10] = "abcdefghi";
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff));
+
+ while(!(MSS_UART_TEMT & MSS_UART_get_tx_status(&g_mss_uart0)))
+ {
+ ;
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_tx_status
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_break() function is used to send the break
+ (9 zeros after stop bit) signal on the TX line. This function can be used
+ only when the MSS UART is initialized in LIN mode by using MSS_UART_lin_init().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_break(&g_mss_uart0);
+ @endcode
+ */
+void
+MSS_UART_set_break
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_clear_break() function is used to remove the break signal on the
+ TX line. This function can be used only when the MSS UART is initialized in
+ LIN mode by using MSS_UART_lin_init().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_clear_break(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_clear_break
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_half_duplex() function is used to enable the half-duplex
+ (single wire) mode for the MSS UART. Though it finds application in Smartcard
+ mode, half-duplex mode can be used in other modes as well.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_half_duplex(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_half_duplex() function is used to disable the half-duplex
+ (single wire) mode for the MSS UART. Though it finds application in Smartcard
+ mode, half-duplex mode can be used in other modes as well.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_half_duplex(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_endian() function is used to configure the LSB first or
+ MSB first setting for MSS UART receiver
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param endian
+ The endian parameter tells the LSB first or MSB first configuration.
+ This parameter is of type mss_uart_endian_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_endian(&g_mss_uart0_lo, MSS_UART_LITTLEEND);
+ @endcode
+ */
+void
+MSS_UART_set_rx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_tx_endian() function is used to configure the LSB first or
+ MSB first setting for MSS UART transmitter.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param endian
+ The endian parameter tells the LSB first or MSB first configuration.
+ This parameter is of type mss_uart_endian_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_tx_endian(&g_mss_uart0_lo, MSS_UART_LITTLEEND);
+ @endcode
+ */
+void
+MSS_UART_set_tx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_filter_length () function is used to configure the glitch
+ filter length of the MSS UART. This should be configured in accordance with
+ the chosen baud rate.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param length
+ The length parameter is of mss_uart_filter_length_t type that determines
+ the length of the glitch filter.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_filter_length(&g_mss_uart0_lo, MSS_UART_LEN2);
+ @endcode
+ */
+void
+MSS_UART_set_filter_length
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_filter_length_t length
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_afm() function is used to enable address flag detection
+ mode of the MSS UART
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_afm(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_afm
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_afm() function is used to disable address flag detection
+ mode of the MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_afm(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_afm
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_afclear () function is used to enable address flag clear
+ of the MSS UART. This should be used in conjunction with address flag
+ detection mode (AFM).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_afclear(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_afclear
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_afclear () function is used to disable address flag
+ clear of the MSS UART. This should be used in conjunction with address flag
+ detection mode (AFM).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_afclear(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_afclear
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_rx_timeout() function is used to enable and configure
+ the receiver timeout functionality of MSS UART. This function accepts the
+ timeout parameter and applies the timeout based up on the baud rate as per
+ the formula 4 x timeout x bit time.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param timeout
+ The timeout parameter specifies the receiver timeout multiple.
+ It should be configured according to the baud rate in use.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_rx_timeout(&g_mss_uart0_lo, 24);
+ @endcode
+ */
+void
+MSS_UART_enable_rx_timeout
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeout
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_rx_timeout() function is used to disable the receiver
+ timeout functionality of MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_rx_timeout(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_rx_timeout
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_tx_time_guard() function is used to enable and configure
+ the transmitter time guard functionality of MSS UART. This function accepts
+ the timeguard parameter and applies the timeguard based up on the baud rate
+ as per the formula timeguard x bit time.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param timeguard
+ The timeguard parameter specifies the transmitter time guard multiple.
+ It should be configured according to the baud rate in use.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_tx_time_guard(&g_mss_uart0_lo, 24);
+ @endcode
+ */
+void
+MSS_UART_enable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeguard
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_tx_time_guard() function is used to disable the
+ transmitter time guard functionality of MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_tx_time_guard(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_address() function is used to set the 8-bit address for
+ the MSS UART referenced by this_uart parameter.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param address
+ The address parameter is the 8-bit address which is to be configured
+ to the MSS UART referenced by this_uart parameter.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_address(&g_mss_uart0_lo, 0xAA);
+ @endcode
+ */
+void
+MSS_UART_set_address
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t address
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_ready_mode() function is used to configure the MODE0 or MODE1
+ to the TXRDY and RXRDY signals of the MSS UART referenced by this_uart
+ parameter. The mode parameter is used to provide the mode to be configured.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param mode
+ The mode parameter is the mss_uart_ready_mode_t type which is used to
+ configure the TXRDY and RXRDY signal modes.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_ready_mode(&g_mss_uart0_lo, MSS_UART_READY_MODE0);
+ @endcode
+ */
+void
+MSS_UART_set_ready_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_ready_mode_t mode
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_usart_mode() function is used to configure the MSS UART
+ referenced by the parameter this_uart in USART mode. Various USART modes
+ are supported which can be configured by the parameter mode of type
+ mss_uart_usart_mode_t.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param mode
+ The mode parameter is the USART mode to be configured.
+ This parameter is of type mss_uart_usart_mode_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_usart_mode(&g_mss_uart0_lo, MSS_UART_SYNC_MASTER_POS_EDGE_CLK);
+ @endcode
+ */
+void
+MSS_UART_set_usart_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_usart_mode_t mode
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_local_irq() function is used to enable the MMUART
+ interrupt as a local interrupt to the hart rather than via PLIC.
+ MMUART interrupt can be configured to trigger an interrupt via PLIC or it
+ can be configured to trigger a local interrupt. The arrangement is such that
+ the UART0 interrupt can appear as local interrupt on E51. The UART1 to UART4
+ interrupts can appear as local interrupt to U51_1 to U54_4 respectively.
+ The UART0 to UART4 can appear as PLIC interrupt. Multiple HARTs can enable
+ and receive the PLIC interrupt, the HART that claims the interrupt processes
+ it. For rest of the HARTs the IRQ gets silently skipped as the interrupt
+ claim has already been taken.
+
+ By default, the PLIC interrupt is enabled by this driver when
+ MSS_UART_enable_irq() or the APIs to set the interrupt handler is called.
+ To enable the local interrupt application must explicitly call
+ MSS_UART_enable_local_irq() function. Note that this function disables the
+ interrupt over PLIC if it was previously enabled.
+
+ This function must be called after the MMUART is initialized, the required
+ interrupt hander functions are set and before initiating any data transfers.
+ If you want to register multiple register handlers such as tx handler, rx
+ handler etc. then this function must be called after all such handlers are set.
+
+ Call to this function is treated as one time activity. The driver gives no
+ option to disable the local interrupt and enable the PLIC interrupt again at
+ runtime.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+
+
+ __enable_irq();
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart0_lo,
+ uart0_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ MSS_UART_enable_local_irq(&g_mss_uart0_lo);
+
+ @endcode
+ */
+void
+MSS_UART_enable_local_irq
+(
+ mss_uart_instance_t * this_uart
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_UART_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h
new file mode 100644
index 00000000..d550810a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h
@@ -0,0 +1,133 @@
+ /*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Register bit offsets and masks definitions for PolarFire SoC MSS MMUART
+ *
+ */
+
+#ifndef MSS_UART_REGS_H_
+#define MSS_UART_REGS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ Register Bit definitions
+ */
+
+/* Line Control register bit definitions */
+#define SB 6u /* Set break */
+#define DLAB 7u /* Divisor latch access bit */
+
+/* Line Control register bit masks */
+#define SB_MASK (0x01u << SB) /* Set break */
+#define DLAB_MASK (0x01u << DLAB) /* Divisor latch access bit */
+
+/* FIFO Control register bit definitions */
+#define RXRDY_TXRDYN_EN 0u /* Enable TXRDY and RXRDY signals */
+#define CLEAR_RX_FIFO 1u /* Clear receiver FIFO */
+#define CLEAR_TX_FIFO 2u /* Clear transmitter FIFO */
+#define RDYMODE 3u /* Mode 0 or Mode 1 for TXRDY and RXRDY */
+
+/* FIFO Control register bit MASKS */
+#define RXRDY_TXRDYN_EN_MASK (0x01u << 0u) /* Enable TXRDY and RXRDY signals */
+#define CLEAR_RX_FIFO_MASK (0x01u << 1u) /* Clear receiver FIFO */
+#define CLEAR_TX_FIFO_MASK (0x01u << 2u) /* Clear transmitter FIFO */
+#define RDYMODE_MASK (0x01u << 3u) /* Mode 0 or Mode 1 for TXRDY and RXRDY */
+
+/* Modem Control register bit definitions */
+#define LOOP 4u /* Local loopback */
+#define RLOOP 5u /* Remote loopback */
+#define ECHO 6u /* Automatic echo */
+
+/* Modem Control register bit MASKS */
+#define LOOP_MASK (0x01u << 4u) /* Local loopback */
+#define RLOOP_MASK (0x01u << 5u) /* Remote loopback & Automatic echo*/
+#define ECHO_MASK (0x01u << 6u) /* Automatic echo */
+
+/* Line Status register bit definitions */
+#define DR 0u /* Data ready */
+#define THRE 5u /* Transmitter holding register empty */
+#define TEMT 6u /* Transmitter empty */
+
+/* Line Status register bit MASKS */
+#define DR_MASK (0x01u << 0u) /* Data ready */
+#define THRE_MASK (0x01u << 5u) /* Transmitter holding register empty */
+#define TEMT_MASK (0x01u << 6u) /* Transmitter empty */
+
+/* Interrupt Enable register bit definitions */
+#define ERBFI 0u /* Enable receiver buffer full interrupt */
+#define ETBEI 1u /* Enable transmitter buffer empty interrupt */
+#define ELSI 2u /* Enable line status interrupt */
+#define EDSSI 3u /* Enable modem status interrupt */
+
+/* Interrupt Enable register bit MASKS */
+#define ERBFI_MASK (0x01u << 0u) /* Enable receiver buffer full interrupt */
+#define ETBEI_MASK (0x01u << 1u) /* Enable transmitter buffer empty interrupt */
+#define ELSI_MASK (0x01u << 2u) /* Enable line status interrupt */
+#define EDSSI_MASK (0x01u << 3u) /* Enable modem status interrupt */
+
+/* Multimode register 0 bit definitions */
+#define ELIN 3u /* Enable LIN header detection */
+#define ETTG 5u /* Enable transmitter time guard */
+#define ERTO 6u /* Enable receiver time-out */
+#define EFBR 7u /* Enable fractional baud rate mode */
+
+/* Multimode register 0 bit MASKS */
+#define ELIN_MASK (0x01u << 3u) /* Enable LIN header detection */
+#define ETTG_MASK (0x01u << 5u) /* Enable transmitter time guard */
+#define ERTO_MASK (0x01u << 6u) /* Enable receiver time-out */
+#define EFBR_MASK (0x01u << 7u) /* Enable fractional baud rate mode */
+
+/* Multimode register 1 bit definitions */
+#define E_MSB_RX 0u /* MSB / LSB first for receiver */
+#define E_MSB_TX 1u /* MSB / LSB first for transmitter */
+#define EIRD 2u /* Enable IrDA modem */
+#define EIRX 3u /* Input polarity for IrDA modem */
+#define EITX 4u /* Output polarity for IrDA modem */
+#define EITP 5u /* Output pulse width for IrDA modem */
+
+/* Multimode register 1 bit MASKS */
+#define E_MSB_RX_MASK (0x01u << 0u) /* MSB / LSB first for receiver */
+#define E_MSB_TX_MASK (0x01u << 1u) /* MSB / LSB first for transmitter */
+#define EIRD_MASK (0x01u << 2u) /* Enable IrDA modem */
+#define EIRX_MASK (0x01u << 3u) /* Input polarity for IrDA modem */
+#define EITX_MASK (0x01u << 4u) /* Output polarity for IrDA modem */
+#define EITP_MASK (0x01u << 5u) /* Output pulse width for IrDA modem */
+
+/* Multimode register 2 bit definitions */
+#define EERR 0u /* Enable ERR / NACK during stop time */
+#define EAFM 1u /* Enable 9-bit address flag mode */
+#define EAFC 2u /* Enable address flag clear */
+#define ESWM 3u /* Enable single wire half-duplex mode */
+
+/* Multimode register 2 bit MASKS */
+#define EERR_MASK (0x01u << 0u) /* Enable ERR / NACK during stop time */
+#define EAFM_MASK (0x01u << 1u) /* Enable 9-bit address flag mode */
+#define EAFC_MASK (0x01u << 2u) /* Enable address flag clear */
+#define ESWM_MASK (0x01u << 3u) /* Enable single wire half-duplex mode */
+
+/* Multimode Interrupt Enable register and
+ Multimode Interrupt Identification register definitions */
+#define ERTOI 0u /* Enable receiver timeout interrupt */
+#define ENACKI 1u /* Enable NACK / ERR interrupt */
+#define EPID_PEI 2u /* Enable PID parity error interrupt */
+#define ELINBI 3u /* Enable LIN break interrupt */
+#define ELINSI 4u /* Enable LIN sync detection interrupt */
+
+/* Multimode Interrupt Enable register and
+ Multimode Interrupt Identification register MASKS */
+#define ERTOI_MASK (0x01u << 0u) /* Enable receiver timeout interrupt */
+#define ENACKI_MASK (0x01u << 1u) /* Enable NACK / ERR interrupt */
+#define EPID_PEI_MASK (0x01u << 2u) /* Enable PID parity error interrupt */
+#define ELINBI_MASK (0x01u << 3u) /* Enable LIN break interrupt */
+#define ELINSI_MASK (0x01u << 4u) /* Enable LIN sync detection interrupt */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_UART_REGS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/cpu_types.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/cpu_types.h
new file mode 100644
index 00000000..55cfac93
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/cpu_types.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+#ifndef CPU_TYPES_H
+#define CPU_TYPES_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long size_t;
+
+/*------------------------------------------------------------------------------
+ * addr_t: address type.
+ * Used to specify the address of peripherals present in the processor's memory
+ * map.
+ */
+typedef unsigned long addr_t;
+
+/*------------------------------------------------------------------------------
+ * psr_t: processor state register.
+ * Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the
+ * processor's state between disabling and restoring interrupts.
+ */
+typedef unsigned long psr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CPU_TYPES_H */
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal.h
new file mode 100644
index 00000000..658ab2a0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal.h
@@ -0,0 +1,241 @@
+/***************************************************************************//**
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Hardware abstraction layer functions.
+ *
+ * Legacy register interrupt functions
+ * Pointers are now recommended for use in drivers
+ *
+ */
+#ifndef HAL_H
+#define HAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cpu_types.h"
+#include "hw_reg_access.h"
+#include "hal/hal_assert.h"
+/***************************************************************************//**
+ * Enable all interrupts at the processor level.
+ */
+void HAL_enable_interrupts( void );
+
+/***************************************************************************//**
+ * Disable all interrupts at the processor core level.
+ * Return the interrupts enable state before disabling occurred so that it can
+ * later be restored.
+ */
+psr_t HAL_disable_interrupts( void );
+
+/***************************************************************************//**
+ * Restore the interrupts enable state at the processor core level.
+ * This function is normally passed the value returned from a previous call to
+ * HAL_disable_interrupts().
+ */
+void HAL_restore_interrupts( psr_t saved_psr );
+
+/***************************************************************************//**
+ */
+#define FIELD_OFFSET(FIELD_NAME) (FIELD_NAME##_OFFSET)
+#define FIELD_SHIFT(FIELD_NAME) (FIELD_NAME##_SHIFT)
+#define FIELD_MASK(FIELD_NAME) (FIELD_NAME##_MASK)
+
+/***************************************************************************//**
+ * The macro HAL_set_32bit_reg() allows writing a 32 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint32_t containing the value to write.
+ */
+#define HAL_set_32bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_32bit_reg() is used to read the value of a 32 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint32_t value.
+ */
+#define HAL_get_32bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)) ))
+
+/***************************************************************************//**
+ * The macro HAL_set_32bit_reg_field() is used to write a field within a
+ * 32 bits wide register. The field written can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint32_t containing the field value to write.
+ */
+#define HAL_set_32bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_32bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_32bit_reg_field() is used to read a register field from
+ * within a 32 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint32_t value.
+ */
+#define HAL_get_32bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_32bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+/***************************************************************************//**
+ * The macro HAL_set_16bit_reg() allows writing a 16 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint_fast16_t containing the value to write.
+ */
+#define HAL_set_16bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_16bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_16bit_reg() is used to read the value of a 16 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint16_t value.
+ */
+#define HAL_get_16bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_16bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
+
+/***************************************************************************//**
+ * The macro HAL_set_16bit_reg_field() is used to write a field within a
+ * 16 bits wide register. The field written can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint16_t containing the field value to write.
+ */
+#define HAL_set_16bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_16bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_16bit_reg_field() is used to read a register field from
+ * within a 8 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint16_t value.
+ */
+#define HAL_get_16bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_16bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+/***************************************************************************//**
+ * The macro HAL_set_8bit_reg() allows writing a 8 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint_fast8_t containing the value to write.
+ */
+#define HAL_set_8bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_8bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_8bit_reg() is used to read the value of a 8 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint8_t value.
+ */
+#define HAL_get_8bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_8bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
+
+/***************************************************************************//**
+ */
+#define HAL_set_8bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_8bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_8bit_reg_field() is used to read a register field from
+ * within a 8 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint8_t value.
+ */
+#define HAL_get_8bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_8bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*HAL_H*/
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_assert.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_assert.h
new file mode 100644
index 00000000..8d64b3c5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_assert.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+#ifndef HAL_ASSERT_HEADER
+#define HAL_ASSERT_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * ASSERT() implementation.
+ ******************************************************************************/
+/* Disable assertions if we do not recognize the compiler. */
+#if defined ( __GNUC__ )
+#if defined(NDEBUG)
+#define ASSERT(CHECK)
+#else
+#define ASSERT(CHECK)\
+ do { \
+ if (!(CHECK)) \
+ { \
+ __asm volatile ("ebreak"); \
+ }\
+ } while(0);
+#endif /* NDEBUG check */
+#endif /* compiler check */
+
+#if defined(NDEBUG)
+/***************************************************************************//**
+ * HAL_ASSERT() is defined out when the NDEBUG symbol is used.
+ ******************************************************************************/
+#define HAL_ASSERT(CHECK)
+
+#else
+/***************************************************************************//**
+ * Default behaviour for HAL_ASSERT() macro:
+ *------------------------------------------------------------------------------
+ The behaviour is toolchain specific and project setting specific.
+ ******************************************************************************/
+#define HAL_ASSERT(CHECK) ASSERT(CHECK);
+
+#endif /* NDEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_ASSERT_HEADER */
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_irq.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_irq.c
new file mode 100644
index 00000000..2fea28e1
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_irq.c
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Legacy interrupt control functions for the Microchip driver library hardware
+ * abstraction layer.
+ *
+ */
+#include
+#include "hal/hal.h"
+#include "mpfs_hal/common/mss_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void HAL_enable_interrupts(void) {
+ __enable_irq();
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+psr_t HAL_disable_interrupts(void) {
+ psr_t psr;
+ psr = read_csr(mstatus);
+ __disable_irq();
+ return(psr);
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void HAL_restore_interrupts(psr_t saved_psr) {
+ write_csr(mstatus, saved_psr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_version.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_version.h
new file mode 100644
index 00000000..7d4d31c8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hal_version.h
@@ -0,0 +1,50 @@
+#ifndef HAL_VERSION_H
+#define HAL_VERSION_H
+
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ *
+ */
+
+/*******************************************************************************
+ * @file mpfs_halversion.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MICROCHIP FPGA Embedded Software Hardware Abstraction layer - HAL
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HAL_VERSION_MAJOR 1
+#define HAL_VERSION_MINOR 8
+#define HAL_VERSION_PATCH 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_macros.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_macros.h
new file mode 100644
index 00000000..cab09353
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_macros.h
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * Hardware registers access macros.
+ *
+ * THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USE FOR NEW
+ * DEVELOPMENT.
+ *
+ * These macros are used to access peripheral registers. They allow access to
+ * 8, 16 and 32 bit wide registers. All accesses to peripheral registers should
+ * be done through these macros in order to ease porting across different
+ * processors/bus architectures.
+ *
+ * Some of these macros also allow access to a specific register field.
+ *
+ */
+
+#ifndef HW_MACROS_H
+#define HW_MACROS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ * 32 bits registers access:
+ */
+#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint32_t) \
+ ( \
+ (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 32 bits memory access:
+ */
+#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))
+
+#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))
+
+/*------------------------------------------------------------------------------
+ * 16 bits registers access:
+ */
+#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint16_t) \
+ ( \
+ (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 8 bits registers access:
+ */
+#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint8_t) \
+ ( \
+ (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 8 bits memory access:
+ */
+#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))
+
+#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#endif /* HW_MACROS_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_reg_access.S b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_reg_access.S
new file mode 100644
index 00000000..31352f60
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_reg_access.S
@@ -0,0 +1,214 @@
+/***************************************************************************//**
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ * Hardware registers access functions.
+ * The implementation of these function is platform and toolchain specific.
+ * The functions declared here are implemented using assembler as part of the
+ * processor/toolchain specific HAL.
+ *
+ */
+
+.section .text
+ .globl HW_set_32bit_reg
+ .globl HW_get_32bit_reg
+ .globl HW_set_32bit_reg_field
+ .globl HW_get_32bit_reg_field
+ .globl HW_set_16bit_reg
+ .globl HW_get_16bit_reg
+ .globl HW_set_16bit_reg_field
+ .globl HW_get_16bit_reg_field
+ .globl HW_set_8bit_reg
+ .globl HW_get_8bit_reg
+ .globl HW_set_8bit_reg_field
+ .globl HW_get_8bit_reg_field
+
+
+/***************************************************************************//**
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint32_t value
+ */
+HW_set_32bit_reg:
+ sw a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 32 bits value read from the peripheral register.
+ */
+HW_get_32bit_reg:
+ lw a0, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint32_t mask
+ * a3: uint32_t value
+ */
+HW_set_32bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lw t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sw t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_32bit_reg_field is used to read the content of a field out of a
+ * 32 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint32_t mask
+ *
+ * @return 32 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_32bit_reg_field:
+ lw a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+/***************************************************************************//**
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint_fast16_t value
+ */
+HW_set_16bit_reg:
+ sh a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 16 bits value read from the peripheral register.
+ */
+HW_get_16bit_reg:
+ lh a0, (a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast16_t mask
+ * a3: uint_fast16_t value
+ * @param value Value to be written in the specified field.
+ */
+HW_set_16bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lh t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sh t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_16bit_reg_field is used to read the content of a field from a
+ * 16 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast16_t mask
+ *
+ * @return 16 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_16bit_reg_field:
+ lh a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+/***************************************************************************//**
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint_fast8_t value
+ */
+HW_set_8bit_reg:
+ sb a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 8 bits value read from the peripheral register.
+ */
+HW_get_8bit_reg:
+ lb a0, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr,
+ * a1: int_fast8_t shift
+ * a2: uint_fast8_t mask
+ * a3: uint_fast8_t value
+ */
+HW_set_8bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lb t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sb t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_8bit_reg_field is used to read the content of a field from a
+ * 8 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast8_t mask
+ *
+ * @return 8 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_8bit_reg_field:
+ lb a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+.end
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_reg_access.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_reg_access.h
new file mode 100644
index 00000000..10ae5469
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/hw_reg_access.h
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Hardware registers access functions.
+ * The implementation of these function is platform and tool-chain specific.
+ * The functions declared here are implemented using assembler as part of the
+ * processor/tool-chain specific HAL.
+ *
+ */
+#ifndef HW_REG_ACCESS
+#define HW_REG_ACCESS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "cpu_types.h"
+/***************************************************************************//**
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_32bit_reg
+(
+ addr_t reg_addr,
+ uint32_t value
+);
+
+/***************************************************************************//**
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 32 bits value read from the peripheral register.
+ */
+uint32_t
+HW_get_32bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void
+HW_set_32bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint32_t mask,
+ uint32_t value
+);
+
+/***************************************************************************//**
+ * HW_get_32bit_reg_field is used to read the content of a field out of a
+ * 32 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 32 bits value containing the register field value specified
+ * as parameter.
+ */
+uint32_t
+HW_get_32bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint32_t mask
+);
+
+/***************************************************************************//**
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_16bit_reg
+(
+ addr_t reg_addr,
+ uint_fast16_t value
+);
+
+/***************************************************************************//**
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 16 bits value read from the peripheral register.
+ */
+uint16_t
+HW_get_16bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void HW_set_16bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast16_t mask,
+ uint_fast16_t value
+);
+
+/***************************************************************************//**
+ * HW_get_16bit_reg_field is used to read the content of a field from a
+ * 16 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 16 bits value containing the register field value specified
+ * as parameter.
+ */
+uint16_t HW_get_16bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast16_t mask
+);
+
+/***************************************************************************//**
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_8bit_reg
+(
+ addr_t reg_addr,
+ uint_fast8_t value
+);
+
+/***************************************************************************//**
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 8 bits value read from the peripheral register.
+ */
+uint8_t
+HW_get_8bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void HW_set_8bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast8_t mask,
+ uint_fast8_t value
+);
+
+/***************************************************************************//**
+ * HW_get_8bit_reg_field is used to read the content of a field from a
+ * 8 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 8 bits value containing the register field value specified
+ * as parameter.
+ */
+uint8_t HW_get_8bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast8_t mask
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HW_REG_ACCESS */
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/readme.md b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/readme.md
new file mode 100644
index 00000000..ce9ae8f6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/hal/readme.md
@@ -0,0 +1,41 @@
+===============================================================================
+# hal folder
+===============================================================================
+
+The HAL folder provides support code for use by the bare metal drivers for the
+fabric IP cores.
+The HAL folder contains files using a combination of C and assembly source code.
+
+The hal folder should be included in a PolarFire SoC Embedded project under the
+platform directory. See location in the drawing below.
+
+The hal folder contains:
+
+* register access functions
+* assert macros
+
+### Project directory strucutre, showing where hal folder sits.
+
+ +---------+ +-----------+
+ | src +----->|application|
+ +---------+ | +-----------+
+ |
+ | +-----------+
+ +-->|modules |
+ | +-----------+
+ |
+ | +-----------+ +---------+
+ +-->|platform +---->|config |
+ +-----------+ | +---------+
+ |
+ | +---------+
+ +->|drivers |
+ | +---------+
+ |
+ | +---------+
+ +->|hal |
+ | +---------+
+ |
+ | +---------+
+ +->|mpfs_hal |
+ +---------+
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/atomic.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/atomic.h
new file mode 100644
index 00000000..48110f00
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/atomic.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+
+#ifndef RISCV_ATOMIC_H
+#define RISCV_ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define mb() asm volatile ("fence" ::: "memory")
+#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val)
+#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr))
+
+#ifdef __riscv_atomic
+# define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp)
+# define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc)
+#else
+#define atomic_binop(ptr, inc, op) ({ \
+ long flags = disable_irqsave(); \
+ typeof(*(ptr)) res = atomic_read(ptr); \
+ atomic_set(ptr, op); \
+ enable_irqrestore(flags); \
+ res; })
+#define atomic_or(ptr, inc) atomic_binop(ptr, inc, res | (inc))
+#define atomic_swap(ptr, swp) atomic_binop(ptr, swp, (swp))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //RISCV_ATOMIC_H
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/bits.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/bits.h
new file mode 100644
index 00000000..b2df5f55
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/bits.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+#ifndef RISCV_BITS_H
+#define RISCV_BITS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define likely(x) __builtin_expect((x), 1)
+#define unlikely(x) __builtin_expect((x), 0)
+
+#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
+#define ROUNDDOWN(a, b) ((a)/(b)*(b))
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
+
+#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
+#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
+
+#define STR(x) XSTR(x)
+#define XSTR(x) #x
+
+#if __riscv_xlen == 64
+# define SLL32 sllw
+# define STORE sd
+# define LOAD ld
+# define LWU lwu
+# define LOG_REGBYTES 3
+#else
+# define SLL32 sll
+# define STORE sw
+# define LOAD lw
+# define LWU lw
+# define LOG_REGBYTES 2
+#endif
+#define REGBYTES (1 << LOG_REGBYTES)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //RISCV_BITS_H
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/encoding.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/encoding.h
new file mode 100644
index 00000000..c86fb172
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/encoding.h
@@ -0,0 +1,1532 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+
+
+#ifndef RISCV_CSR_ENCODING_H
+#define RISCV_CSR_ENCODING_H
+
+#define MSTATUS_UIE 0x00000001
+#define MSTATUS_SIE 0x00000002
+#define MSTATUS_HIE 0x00000004
+#define MSTATUS_MIE 0x00000008
+#define MSTATUS_UPIE 0x00000010
+#define MSTATUS_SPIE 0x00000020
+#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_MPIE 0x00000080
+#define MSTATUS_SPP 0x00000100
+#define MSTATUS_HPP 0x00000600
+#define MSTATUS_MPP 0x00001800
+#define MSTATUS_FS 0x00006000
+#define MSTATUS_XS 0x00018000
+#define MSTATUS_MPRV 0x00020000
+#define MSTATUS_SUM 0x00040000
+#define MSTATUS_MXR 0x00080000
+#define MSTATUS_TVM 0x00100000
+#define MSTATUS_TW 0x00200000
+#define MSTATUS_TSR 0x00400000
+#define MSTATUS32_SD 0x80000000
+#define MSTATUS64_SD 0x8000000000000000
+
+#define MCAUSE32_CAUSE 0x7FFFFFFF
+#define MCAUSE64_CAUSE 0x7FFFFFFFFFFFFFFF
+#define MCAUSE32_INT 0x80000000
+#define MCAUSE64_INT 0x8000000000000000
+
+#define SSTATUS_UIE 0x00000001
+#define SSTATUS_SIE 0x00000002
+#define SSTATUS_UPIE 0x00000010
+#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_SPP 0x00000100
+#define SSTATUS_FS 0x00006000
+#define SSTATUS_XS 0x00018000
+#define SSTATUS_SUM 0x00040000
+#define SSTATUS_MXR 0x00080000
+#define SSTATUS32_SD 0x80000000
+#define SSTATUS64_SD 0x8000000000000000
+
+#define DCSR_XDEBUGVER (3U<<30)
+#define DCSR_NDRESET (1<<29)
+#define DCSR_FULLRESET (1<<28)
+#define DCSR_EBREAKM (1<<15)
+#define DCSR_EBREAKH (1<<14)
+#define DCSR_EBREAKS (1<<13)
+#define DCSR_EBREAKU (1<<12)
+#define DCSR_STOPCYCLE (1<<10)
+#define DCSR_STOPTIME (1<<9)
+#define DCSR_CAUSE (7<<6)
+#define DCSR_DEBUGINT (1<<5)
+#define DCSR_HALT (1<<3)
+#define DCSR_STEP (1<<2)
+#define DCSR_PRV (3<<0)
+
+#define DCSR_CAUSE_NONE 0
+#define DCSR_CAUSE_SWBP 1
+#define DCSR_CAUSE_HWBP 2
+#define DCSR_CAUSE_DEBUGINT 3
+#define DCSR_CAUSE_STEP 4
+#define DCSR_CAUSE_HALT 5
+
+#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
+#define MCONTROL_SELECT (1U<<19)
+#define MCONTROL_TIMING (1U<<18)
+#define MCONTROL_ACTION (0x3fU<<12)
+#define MCONTROL_CHAIN (1U<<11)
+#define MCONTROL_MATCH (0xfU<<7)
+#define MCONTROL_M (1U<<6)
+#define MCONTROL_H (1U<<5)
+#define MCONTROL_S (1U<<4)
+#define MCONTROL_U (1U<<3)
+#define MCONTROL_EXECUTE (1U<<2)
+#define MCONTROL_STORE (1U<<1)
+#define MCONTROL_LOAD (1U<<0)
+
+#define MCONTROL_TYPE_NONE 0
+#define MCONTROL_TYPE_MATCH 2
+
+#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
+#define MCONTROL_ACTION_DEBUG_MODE 1
+#define MCONTROL_ACTION_TRACE_START 2
+#define MCONTROL_ACTION_TRACE_STOP 3
+#define MCONTROL_ACTION_TRACE_EMIT 4
+
+#define MCONTROL_MATCH_EQUAL 0
+#define MCONTROL_MATCH_NAPOT 1
+#define MCONTROL_MATCH_GE 2
+#define MCONTROL_MATCH_LT 3
+#define MCONTROL_MATCH_MASK_LOW 4
+#define MCONTROL_MATCH_MASK_HIGH 5
+
+#define MIP_SSIP (1U << IRQ_S_SOFT)
+#define MIP_HSIP (1U << IRQ_H_SOFT)
+#define MIP_MSIP (1U << IRQ_M_SOFT)
+#define MIP_STIP (1U << IRQ_S_TIMER)
+#define MIP_HTIP (1U << IRQ_H_TIMER)
+#define MIP_MTIP (1U << IRQ_M_TIMER)
+#define MIP_SEIP (1U << IRQ_S_EXT)
+#define MIP_HEIP (1U << IRQ_H_EXT)
+#define MIP_MEIP (1U << IRQ_M_EXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+#define SPTBR32_MODE 0x80000000
+#define SPTBR32_ASID 0x7FC00000
+#define SPTBR32_PPN 0x003FFFFF
+#define SPTBR64_MODE 0xF000000000000000
+#define SPTBR64_ASID 0x0FFFF00000000000
+#define SPTBR64_PPN 0x00000FFFFFFFFFFF
+
+#define SPTBR_MODE_OFF 0
+#define SPTBR_MODE_SV32 1
+#define SPTBR_MODE_SV39 8
+#define SPTBR_MODE_SV48 9
+#define SPTBR_MODE_SV57 10
+#define SPTBR_MODE_SV64 11
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_L 0x80
+#define PMP_SHIFT 2
+
+#define PMP_TOR 0x08
+#define PMP_NA4 0x10
+#define PMP_NAPOT 0x18
+
+#define IRQ_S_SOFT 1
+#define IRQ_H_SOFT 2
+#define IRQ_M_SOFT 3
+#define IRQ_S_TIMER 5
+#define IRQ_H_TIMER 6
+#define IRQ_M_TIMER 7
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10
+#define IRQ_M_EXT 11
+#define IRQ_COP 12
+#define IRQ_HOST 13
+
+#define DEFAULT_RSTVEC 0x00001000
+#define CLINT_BASE 0x02000000
+#define CLINT_SIZE 0x000c0000
+#define EXT_IO_BASE 0x40000000
+#define DRAM_BASE 0x80000000
+
+// page table entry (PTE) fields
+#define PTE_V 0x001 // Valid
+#define PTE_R 0x002 // Read
+#define PTE_W 0x004 // Write
+#define PTE_X 0x008 // Execute
+#define PTE_U 0x010 // User
+#define PTE_G 0x020 // Global
+#define PTE_A 0x040 // Accessed
+#define PTE_D 0x080 // Dirty
+#define PTE_SOFT 0x300 // Reserved for Software
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
+
+#ifdef __riscv
+
+#if __riscv_xlen == 64
+# define MSTATUS_SD MSTATUS64_SD
+# define SSTATUS_SD SSTATUS64_SD
+# define RISCV_PGLEVEL_BITS 9
+# define SPTBR_MODE SPTBR64_MODE
+# define MCAUSE_INT MCAUSE64_INT //ML added- should we be using later encoding.h?
+# define MCAUSE_CAUSE MCAUSE64_CAUSE //ML added- should we be using later encoding.h?
+#else
+# define MSTATUS_SD MSTATUS32_SD
+# define SSTATUS_SD SSTATUS32_SD
+# define RISCV_PGLEVEL_BITS 10
+# define SPTBR_MODE SPTBR32_MODE
+# define MCAUSE_INT MCAUSE32_INT //ML added- should we be using later encoding.h?
+# define MCAUSE_CAUSE MCAUSE32_CAUSE //ML added- should we be using later encoding.h?
+#endif
+#define RISCV_PGSHIFT 12
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#ifndef __ASSEMBLER__
+
+#ifdef __GNUC__
+
+#define read_reg(reg) ({ unsigned long __tmp; \
+ asm volatile ("mv %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define read_csr(reg) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define write_csr(reg, val) __extension__({ \
+ asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
+
+#define swap_csr(reg, val) ({ unsigned long __tmp; \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
+ __tmp; })
+
+#define set_csr(reg, bit) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#define clear_csr(reg, bit) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#if 0
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ asm volatile ("csrw " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+#endif
+
+#define rdtime() read_csr(time)
+#define rdcycle() read_csr(cycle)
+#define rdinstret() read_csr(instret)
+
+#endif
+
+#endif
+
+#endif
+
+#endif
+/* Automatically generated by parse-opcodes. */
+#ifndef RISCV_ENCODING_H
+#define RISCV_ENCODING_H
+#define MATCH_BEQ 0x63
+#define MASK_BEQ 0x707f
+#define MATCH_BNE 0x1063
+#define MASK_BNE 0x707f
+#define MATCH_BLT 0x4063
+#define MASK_BLT 0x707f
+#define MATCH_BGE 0x5063
+#define MASK_BGE 0x707f
+#define MATCH_BLTU 0x6063
+#define MASK_BLTU 0x707f
+#define MATCH_BGEU 0x7063
+#define MASK_BGEU 0x707f
+#define MATCH_JALR 0x67
+#define MASK_JALR 0x707f
+#define MATCH_JAL 0x6f
+#define MASK_JAL 0x7f
+#define MATCH_LUI 0x37
+#define MASK_LUI 0x7f
+#define MATCH_AUIPC 0x17
+#define MASK_AUIPC 0x7f
+#define MATCH_ADDI 0x13
+#define MASK_ADDI 0x707f
+#define MATCH_SLLI 0x1013
+#define MASK_SLLI 0xfc00707f
+#define MATCH_SLTI 0x2013
+#define MASK_SLTI 0x707f
+#define MATCH_SLTIU 0x3013
+#define MASK_SLTIU 0x707f
+#define MATCH_XORI 0x4013
+#define MASK_XORI 0x707f
+#define MATCH_SRLI 0x5013
+#define MASK_SRLI 0xfc00707f
+#define MATCH_SRAI 0x40005013
+#define MASK_SRAI 0xfc00707f
+#define MATCH_ORI 0x6013
+#define MASK_ORI 0x707f
+#define MATCH_ANDI 0x7013
+#define MASK_ANDI 0x707f
+#define MATCH_ADD 0x33
+#define MASK_ADD 0xfe00707f
+#define MATCH_SUB 0x40000033
+#define MASK_SUB 0xfe00707f
+#define MATCH_SLL 0x1033
+#define MASK_SLL 0xfe00707f
+#define MATCH_SLT 0x2033
+#define MASK_SLT 0xfe00707f
+#define MATCH_SLTU 0x3033
+#define MASK_SLTU 0xfe00707f
+#define MATCH_XOR 0x4033
+#define MASK_XOR 0xfe00707f
+#define MATCH_SRL 0x5033
+#define MASK_SRL 0xfe00707f
+#define MATCH_SRA 0x40005033
+#define MASK_SRA 0xfe00707f
+#define MATCH_OR 0x6033
+#define MASK_OR 0xfe00707f
+#define MATCH_AND 0x7033
+#define MASK_AND 0xfe00707f
+#define MATCH_ADDIW 0x1b
+#define MASK_ADDIW 0x707f
+#define MATCH_SLLIW 0x101b
+#define MASK_SLLIW 0xfe00707f
+#define MATCH_SRLIW 0x501b
+#define MASK_SRLIW 0xfe00707f
+#define MATCH_SRAIW 0x4000501b
+#define MASK_SRAIW 0xfe00707f
+#define MATCH_ADDW 0x3b
+#define MASK_ADDW 0xfe00707f
+#define MATCH_SUBW 0x4000003b
+#define MASK_SUBW 0xfe00707f
+#define MATCH_SLLW 0x103b
+#define MASK_SLLW 0xfe00707f
+#define MATCH_SRLW 0x503b
+#define MASK_SRLW 0xfe00707f
+#define MATCH_SRAW 0x4000503b
+#define MASK_SRAW 0xfe00707f
+#define MATCH_LB 0x3
+#define MASK_LB 0x707f
+#define MATCH_LH 0x1003
+#define MASK_LH 0x707f
+#define MATCH_LW 0x2003
+#define MASK_LW 0x707f
+#define MATCH_LD 0x3003
+#define MASK_LD 0x707f
+#define MATCH_LBU 0x4003
+#define MASK_LBU 0x707f
+#define MATCH_LHU 0x5003
+#define MASK_LHU 0x707f
+#define MATCH_LWU 0x6003
+#define MASK_LWU 0x707f
+#define MATCH_SB 0x23
+#define MASK_SB 0x707f
+#define MATCH_SH 0x1023
+#define MASK_SH 0x707f
+#define MATCH_SW 0x2023
+#define MASK_SW 0x707f
+#define MATCH_SD 0x3023
+#define MASK_SD 0x707f
+#define MATCH_FENCE 0xf
+#define MASK_FENCE 0x707f
+#define MATCH_FENCE_I 0x100f
+#define MASK_FENCE_I 0x707f
+#define MATCH_MUL 0x2000033
+#define MASK_MUL 0xfe00707f
+#define MATCH_MULH 0x2001033
+#define MASK_MULH 0xfe00707f
+#define MATCH_MULHSU 0x2002033
+#define MASK_MULHSU 0xfe00707f
+#define MATCH_MULHU 0x2003033
+#define MASK_MULHU 0xfe00707f
+#define MATCH_DIV 0x2004033
+#define MASK_DIV 0xfe00707f
+#define MATCH_DIVU 0x2005033
+#define MASK_DIVU 0xfe00707f
+#define MATCH_REM 0x2006033
+#define MASK_REM 0xfe00707f
+#define MATCH_REMU 0x2007033
+#define MASK_REMU 0xfe00707f
+#define MATCH_MULW 0x200003b
+#define MASK_MULW 0xfe00707f
+#define MATCH_DIVW 0x200403b
+#define MASK_DIVW 0xfe00707f
+#define MATCH_DIVUW 0x200503b
+#define MASK_DIVUW 0xfe00707f
+#define MATCH_REMW 0x200603b
+#define MASK_REMW 0xfe00707f
+#define MATCH_REMUW 0x200703b
+#define MASK_REMUW 0xfe00707f
+#define MATCH_AMOADD_W 0x202f
+#define MASK_AMOADD_W 0xf800707f
+#define MATCH_AMOXOR_W 0x2000202f
+#define MASK_AMOXOR_W 0xf800707f
+#define MATCH_AMOOR_W 0x4000202f
+#define MASK_AMOOR_W 0xf800707f
+#define MATCH_AMOAND_W 0x6000202f
+#define MASK_AMOAND_W 0xf800707f
+#define MATCH_AMOMIN_W 0x8000202f
+#define MASK_AMOMIN_W 0xf800707f
+#define MATCH_AMOMAX_W 0xa000202f
+#define MASK_AMOMAX_W 0xf800707f
+#define MATCH_AMOMINU_W 0xc000202f
+#define MASK_AMOMINU_W 0xf800707f
+#define MATCH_AMOMAXU_W 0xe000202f
+#define MASK_AMOMAXU_W 0xf800707f
+#define MATCH_AMOSWAP_W 0x800202f
+#define MASK_AMOSWAP_W 0xf800707f
+#define MATCH_LR_W 0x1000202f
+#define MASK_LR_W 0xf9f0707f
+#define MATCH_SC_W 0x1800202f
+#define MASK_SC_W 0xf800707f
+#define MATCH_AMOADD_D 0x302f
+#define MASK_AMOADD_D 0xf800707f
+#define MATCH_AMOXOR_D 0x2000302f
+#define MASK_AMOXOR_D 0xf800707f
+#define MATCH_AMOOR_D 0x4000302f
+#define MASK_AMOOR_D 0xf800707f
+#define MATCH_AMOAND_D 0x6000302f
+#define MASK_AMOAND_D 0xf800707f
+#define MATCH_AMOMIN_D 0x8000302f
+#define MASK_AMOMIN_D 0xf800707f
+#define MATCH_AMOMAX_D 0xa000302f
+#define MASK_AMOMAX_D 0xf800707f
+#define MATCH_AMOMINU_D 0xc000302f
+#define MASK_AMOMINU_D 0xf800707f
+#define MATCH_AMOMAXU_D 0xe000302f
+#define MASK_AMOMAXU_D 0xf800707f
+#define MATCH_AMOSWAP_D 0x800302f
+#define MASK_AMOSWAP_D 0xf800707f
+#define MATCH_LR_D 0x1000302f
+#define MASK_LR_D 0xf9f0707f
+#define MATCH_SC_D 0x1800302f
+#define MASK_SC_D 0xf800707f
+#define MATCH_ECALL 0x73
+#define MASK_ECALL 0xffffffff
+#define MATCH_EBREAK 0x100073
+#define MASK_EBREAK 0xffffffff
+#define MATCH_URET 0x200073
+#define MASK_URET 0xffffffff
+#define MATCH_SRET 0x10200073
+#define MASK_SRET 0xffffffff
+#define MATCH_HRET 0x20200073
+#define MASK_HRET 0xffffffff
+#define MATCH_MRET 0x30200073
+#define MASK_MRET 0xffffffff
+#define MATCH_DRET 0x7b200073
+#define MASK_DRET 0xffffffff
+#define MATCH_SFENCE_VMA 0x12000073
+#define MASK_SFENCE_VMA 0xfe007fff
+#define MATCH_WFI 0x10500073
+#define MASK_WFI 0xffffffff
+#define MATCH_CSRRW 0x1073
+#define MASK_CSRRW 0x707f
+#define MATCH_CSRRS 0x2073
+#define MASK_CSRRS 0x707f
+#define MATCH_CSRRC 0x3073
+#define MASK_CSRRC 0x707f
+#define MATCH_CSRRWI 0x5073
+#define MASK_CSRRWI 0x707f
+#define MATCH_CSRRSI 0x6073
+#define MASK_CSRRSI 0x707f
+#define MATCH_CSRRCI 0x7073
+#define MASK_CSRRCI 0x707f
+#define MATCH_FADD_S 0x53
+#define MASK_FADD_S 0xfe00007f
+#define MATCH_FSUB_S 0x8000053
+#define MASK_FSUB_S 0xfe00007f
+#define MATCH_FMUL_S 0x10000053
+#define MASK_FMUL_S 0xfe00007f
+#define MATCH_FDIV_S 0x18000053
+#define MASK_FDIV_S 0xfe00007f
+#define MATCH_FSGNJ_S 0x20000053
+#define MASK_FSGNJ_S 0xfe00707f
+#define MATCH_FSGNJN_S 0x20001053
+#define MASK_FSGNJN_S 0xfe00707f
+#define MATCH_FSGNJX_S 0x20002053
+#define MASK_FSGNJX_S 0xfe00707f
+#define MATCH_FMIN_S 0x28000053
+#define MASK_FMIN_S 0xfe00707f
+#define MATCH_FMAX_S 0x28001053
+#define MASK_FMAX_S 0xfe00707f
+#define MATCH_FSQRT_S 0x58000053
+#define MASK_FSQRT_S 0xfff0007f
+#define MATCH_FADD_D 0x2000053
+#define MASK_FADD_D 0xfe00007f
+#define MATCH_FSUB_D 0xa000053
+#define MASK_FSUB_D 0xfe00007f
+#define MATCH_FMUL_D 0x12000053
+#define MASK_FMUL_D 0xfe00007f
+#define MATCH_FDIV_D 0x1a000053
+#define MASK_FDIV_D 0xfe00007f
+#define MATCH_FSGNJ_D 0x22000053
+#define MASK_FSGNJ_D 0xfe00707f
+#define MATCH_FSGNJN_D 0x22001053
+#define MASK_FSGNJN_D 0xfe00707f
+#define MATCH_FSGNJX_D 0x22002053
+#define MASK_FSGNJX_D 0xfe00707f
+#define MATCH_FMIN_D 0x2a000053
+#define MASK_FMIN_D 0xfe00707f
+#define MATCH_FMAX_D 0x2a001053
+#define MASK_FMAX_D 0xfe00707f
+#define MATCH_FCVT_S_D 0x40100053
+#define MASK_FCVT_S_D 0xfff0007f
+#define MATCH_FCVT_D_S 0x42000053
+#define MASK_FCVT_D_S 0xfff0007f
+#define MATCH_FSQRT_D 0x5a000053
+#define MASK_FSQRT_D 0xfff0007f
+#define MATCH_FADD_Q 0x6000053
+#define MASK_FADD_Q 0xfe00007f
+#define MATCH_FSUB_Q 0xe000053
+#define MASK_FSUB_Q 0xfe00007f
+#define MATCH_FMUL_Q 0x16000053
+#define MASK_FMUL_Q 0xfe00007f
+#define MATCH_FDIV_Q 0x1e000053
+#define MASK_FDIV_Q 0xfe00007f
+#define MATCH_FSGNJ_Q 0x26000053
+#define MASK_FSGNJ_Q 0xfe00707f
+#define MATCH_FSGNJN_Q 0x26001053
+#define MASK_FSGNJN_Q 0xfe00707f
+#define MATCH_FSGNJX_Q 0x26002053
+#define MASK_FSGNJX_Q 0xfe00707f
+#define MATCH_FMIN_Q 0x2e000053
+#define MASK_FMIN_Q 0xfe00707f
+#define MATCH_FMAX_Q 0x2e001053
+#define MASK_FMAX_Q 0xfe00707f
+#define MATCH_FCVT_S_Q 0x40300053
+#define MASK_FCVT_S_Q 0xfff0007f
+#define MATCH_FCVT_Q_S 0x46000053
+#define MASK_FCVT_Q_S 0xfff0007f
+#define MATCH_FCVT_D_Q 0x42300053
+#define MASK_FCVT_D_Q 0xfff0007f
+#define MATCH_FCVT_Q_D 0x46100053
+#define MASK_FCVT_Q_D 0xfff0007f
+#define MATCH_FSQRT_Q 0x5e000053
+#define MASK_FSQRT_Q 0xfff0007f
+#define MATCH_FLE_S 0xa0000053
+#define MASK_FLE_S 0xfe00707f
+#define MATCH_FLT_S 0xa0001053
+#define MASK_FLT_S 0xfe00707f
+#define MATCH_FEQ_S 0xa0002053
+#define MASK_FEQ_S 0xfe00707f
+#define MATCH_FLE_D 0xa2000053
+#define MASK_FLE_D 0xfe00707f
+#define MATCH_FLT_D 0xa2001053
+#define MASK_FLT_D 0xfe00707f
+#define MATCH_FEQ_D 0xa2002053
+#define MASK_FEQ_D 0xfe00707f
+#define MATCH_FLE_Q 0xa6000053
+#define MASK_FLE_Q 0xfe00707f
+#define MATCH_FLT_Q 0xa6001053
+#define MASK_FLT_Q 0xfe00707f
+#define MATCH_FEQ_Q 0xa6002053
+#define MASK_FEQ_Q 0xfe00707f
+#define MATCH_FCVT_W_S 0xc0000053
+#define MASK_FCVT_W_S 0xfff0007f
+#define MATCH_FCVT_WU_S 0xc0100053
+#define MASK_FCVT_WU_S 0xfff0007f
+#define MATCH_FCVT_L_S 0xc0200053
+#define MASK_FCVT_L_S 0xfff0007f
+#define MATCH_FCVT_LU_S 0xc0300053
+#define MASK_FCVT_LU_S 0xfff0007f
+#define MATCH_FMV_X_S 0xe0000053
+#define MASK_FMV_X_S 0xfff0707f
+#define MATCH_FCLASS_S 0xe0001053
+#define MASK_FCLASS_S 0xfff0707f
+#define MATCH_FCVT_W_D 0xc2000053
+#define MASK_FCVT_W_D 0xfff0007f
+#define MATCH_FCVT_WU_D 0xc2100053
+#define MASK_FCVT_WU_D 0xfff0007f
+#define MATCH_FCVT_L_D 0xc2200053
+#define MASK_FCVT_L_D 0xfff0007f
+#define MATCH_FCVT_LU_D 0xc2300053
+#define MASK_FCVT_LU_D 0xfff0007f
+#define MATCH_FMV_X_D 0xe2000053
+#define MASK_FMV_X_D 0xfff0707f
+#define MATCH_FCLASS_D 0xe2001053
+#define MASK_FCLASS_D 0xfff0707f
+#define MATCH_FCVT_W_Q 0xc6000053
+#define MASK_FCVT_W_Q 0xfff0007f
+#define MATCH_FCVT_WU_Q 0xc6100053
+#define MASK_FCVT_WU_Q 0xfff0007f
+#define MATCH_FCVT_L_Q 0xc6200053
+#define MASK_FCVT_L_Q 0xfff0007f
+#define MATCH_FCVT_LU_Q 0xc6300053
+#define MASK_FCVT_LU_Q 0xfff0007f
+#define MATCH_FMV_X_Q 0xe6000053
+#define MASK_FMV_X_Q 0xfff0707f
+#define MATCH_FCLASS_Q 0xe6001053
+#define MASK_FCLASS_Q 0xfff0707f
+#define MATCH_FCVT_S_W 0xd0000053
+#define MASK_FCVT_S_W 0xfff0007f
+#define MATCH_FCVT_S_WU 0xd0100053
+#define MASK_FCVT_S_WU 0xfff0007f
+#define MATCH_FCVT_S_L 0xd0200053
+#define MASK_FCVT_S_L 0xfff0007f
+#define MATCH_FCVT_S_LU 0xd0300053
+#define MASK_FCVT_S_LU 0xfff0007f
+#define MATCH_FMV_S_X 0xf0000053
+#define MASK_FMV_S_X 0xfff0707f
+#define MATCH_FCVT_D_W 0xd2000053
+#define MASK_FCVT_D_W 0xfff0007f
+#define MATCH_FCVT_D_WU 0xd2100053
+#define MASK_FCVT_D_WU 0xfff0007f
+#define MATCH_FCVT_D_L 0xd2200053
+#define MASK_FCVT_D_L 0xfff0007f
+#define MATCH_FCVT_D_LU 0xd2300053
+#define MASK_FCVT_D_LU 0xfff0007f
+#define MATCH_FMV_D_X 0xf2000053
+#define MASK_FMV_D_X 0xfff0707f
+#define MATCH_FCVT_Q_W 0xd6000053
+#define MASK_FCVT_Q_W 0xfff0007f
+#define MATCH_FCVT_Q_WU 0xd6100053
+#define MASK_FCVT_Q_WU 0xfff0007f
+#define MATCH_FCVT_Q_L 0xd6200053
+#define MASK_FCVT_Q_L 0xfff0007f
+#define MATCH_FCVT_Q_LU 0xd6300053
+#define MASK_FCVT_Q_LU 0xfff0007f
+#define MATCH_FMV_Q_X 0xf6000053
+#define MASK_FMV_Q_X 0xfff0707f
+#define MATCH_FLW 0x2007
+#define MASK_FLW 0x707f
+#define MATCH_FLD 0x3007
+#define MASK_FLD 0x707f
+#define MATCH_FLQ 0x4007
+#define MASK_FLQ 0x707f
+#define MATCH_FSW 0x2027
+#define MASK_FSW 0x707f
+#define MATCH_FSD 0x3027
+#define MASK_FSD 0x707f
+#define MATCH_FSQ 0x4027
+#define MASK_FSQ 0x707f
+#define MATCH_FMADD_S 0x43
+#define MASK_FMADD_S 0x600007f
+#define MATCH_FMSUB_S 0x47
+#define MASK_FMSUB_S 0x600007f
+#define MATCH_FNMSUB_S 0x4b
+#define MASK_FNMSUB_S 0x600007f
+#define MATCH_FNMADD_S 0x4f
+#define MASK_FNMADD_S 0x600007f
+#define MATCH_FMADD_D 0x2000043
+#define MASK_FMADD_D 0x600007f
+#define MATCH_FMSUB_D 0x2000047
+#define MASK_FMSUB_D 0x600007f
+#define MATCH_FNMSUB_D 0x200004b
+#define MASK_FNMSUB_D 0x600007f
+#define MATCH_FNMADD_D 0x200004f
+#define MASK_FNMADD_D 0x600007f
+#define MATCH_FMADD_Q 0x6000043
+#define MASK_FMADD_Q 0x600007f
+#define MATCH_FMSUB_Q 0x6000047
+#define MASK_FMSUB_Q 0x600007f
+#define MATCH_FNMSUB_Q 0x600004b
+#define MASK_FNMSUB_Q 0x600007f
+#define MATCH_FNMADD_Q 0x600004f
+#define MASK_FNMADD_Q 0x600007f
+#define MATCH_C_NOP 0x1
+#define MASK_C_NOP 0xffff
+#define MATCH_C_ADDI16SP 0x6101
+#define MASK_C_ADDI16SP 0xef83
+#define MATCH_C_JR 0x8002
+#define MASK_C_JR 0xf07f
+#define MATCH_C_JALR 0x9002
+#define MASK_C_JALR 0xf07f
+#define MATCH_C_EBREAK 0x9002
+#define MASK_C_EBREAK 0xffff
+#define MATCH_C_LD 0x6000
+#define MASK_C_LD 0xe003
+#define MATCH_C_SD 0xe000
+#define MASK_C_SD 0xe003
+#define MATCH_C_ADDIW 0x2001
+#define MASK_C_ADDIW 0xe003
+#define MATCH_C_LDSP 0x6002
+#define MASK_C_LDSP 0xe003
+#define MATCH_C_SDSP 0xe002
+#define MASK_C_SDSP 0xe003
+#define MATCH_C_ADDI4SPN 0x0
+#define MASK_C_ADDI4SPN 0xe003
+#define MATCH_C_FLD 0x2000
+#define MASK_C_FLD 0xe003
+#define MATCH_C_LW 0x4000
+#define MASK_C_LW 0xe003
+#define MATCH_C_FLW 0x6000
+#define MASK_C_FLW 0xe003
+#define MATCH_C_FSD 0xa000
+#define MASK_C_FSD 0xe003
+#define MATCH_C_SW 0xc000
+#define MASK_C_SW 0xe003
+#define MATCH_C_FSW 0xe000
+#define MASK_C_FSW 0xe003
+#define MATCH_C_ADDI 0x1
+#define MASK_C_ADDI 0xe003
+#define MATCH_C_JAL 0x2001
+#define MASK_C_JAL 0xe003
+#define MATCH_C_LI 0x4001
+#define MASK_C_LI 0xe003
+#define MATCH_C_LUI 0x6001
+#define MASK_C_LUI 0xe003
+#define MATCH_C_SRLI 0x8001
+#define MASK_C_SRLI 0xec03
+#define MATCH_C_SRAI 0x8401
+#define MASK_C_SRAI 0xec03
+#define MATCH_C_ANDI 0x8801
+#define MASK_C_ANDI 0xec03
+#define MATCH_C_SUB 0x8c01
+#define MASK_C_SUB 0xfc63
+#define MATCH_C_XOR 0x8c21
+#define MASK_C_XOR 0xfc63
+#define MATCH_C_OR 0x8c41
+#define MASK_C_OR 0xfc63
+#define MATCH_C_AND 0x8c61
+#define MASK_C_AND 0xfc63
+#define MATCH_C_SUBW 0x9c01
+#define MASK_C_SUBW 0xfc63
+#define MATCH_C_ADDW 0x9c21
+#define MASK_C_ADDW 0xfc63
+#define MATCH_C_J 0xa001
+#define MASK_C_J 0xe003
+#define MATCH_C_BEQZ 0xc001
+#define MASK_C_BEQZ 0xe003
+#define MATCH_C_BNEZ 0xe001
+#define MASK_C_BNEZ 0xe003
+#define MATCH_C_SLLI 0x2
+#define MASK_C_SLLI 0xe003
+#define MATCH_C_FLDSP 0x2002
+#define MASK_C_FLDSP 0xe003
+#define MATCH_C_LWSP 0x4002
+#define MASK_C_LWSP 0xe003
+#define MATCH_C_FLWSP 0x6002
+#define MASK_C_FLWSP 0xe003
+#define MATCH_C_MV 0x8002
+#define MASK_C_MV 0xf003
+#define MATCH_C_ADD 0x9002
+#define MASK_C_ADD 0xf003
+#define MATCH_C_FSDSP 0xa002
+#define MASK_C_FSDSP 0xe003
+#define MATCH_C_SWSP 0xc002
+#define MASK_C_SWSP 0xe003
+#define MATCH_C_FSWSP 0xe002
+#define MASK_C_FSWSP 0xe003
+#define MATCH_CUSTOM0 0xb
+#define MASK_CUSTOM0 0x707f
+#define MATCH_CUSTOM0_RS1 0x200b
+#define MASK_CUSTOM0_RS1 0x707f
+#define MATCH_CUSTOM0_RS1_RS2 0x300b
+#define MASK_CUSTOM0_RS1_RS2 0x707f
+#define MATCH_CUSTOM0_RD 0x400b
+#define MASK_CUSTOM0_RD 0x707f
+#define MATCH_CUSTOM0_RD_RS1 0x600b
+#define MASK_CUSTOM0_RD_RS1 0x707f
+#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
+#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM1 0x2b
+#define MASK_CUSTOM1 0x707f
+#define MATCH_CUSTOM1_RS1 0x202b
+#define MASK_CUSTOM1_RS1 0x707f
+#define MATCH_CUSTOM1_RS1_RS2 0x302b
+#define MASK_CUSTOM1_RS1_RS2 0x707f
+#define MATCH_CUSTOM1_RD 0x402b
+#define MASK_CUSTOM1_RD 0x707f
+#define MATCH_CUSTOM1_RD_RS1 0x602b
+#define MASK_CUSTOM1_RD_RS1 0x707f
+#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
+#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM2 0x5b
+#define MASK_CUSTOM2 0x707f
+#define MATCH_CUSTOM2_RS1 0x205b
+#define MASK_CUSTOM2_RS1 0x707f
+#define MATCH_CUSTOM2_RS1_RS2 0x305b
+#define MASK_CUSTOM2_RS1_RS2 0x707f
+#define MATCH_CUSTOM2_RD 0x405b
+#define MASK_CUSTOM2_RD 0x707f
+#define MATCH_CUSTOM2_RD_RS1 0x605b
+#define MASK_CUSTOM2_RD_RS1 0x707f
+#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
+#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM3 0x7b
+#define MASK_CUSTOM3 0x707f
+#define MATCH_CUSTOM3_RS1 0x207b
+#define MASK_CUSTOM3_RS1 0x707f
+#define MATCH_CUSTOM3_RS1_RS2 0x307b
+#define MASK_CUSTOM3_RS1_RS2 0x707f
+#define MATCH_CUSTOM3_RD 0x407b
+#define MASK_CUSTOM3_RD 0x707f
+#define MATCH_CUSTOM3_RD_RS1 0x607b
+#define MASK_CUSTOM3_RD_RS1 0x707f
+#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
+#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_SSTATUS 0x100
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_SBADADDR 0x143
+#define CSR_SIP 0x144
+#define CSR_SPTBR 0x180
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MBADADDR 0x343
+#define CSR_MIP 0x344
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_SUPERVISOR_ECALL 0x9
+#define CAUSE_HYPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#endif
+#ifdef DECLARE_INSN
+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
+DECLARE_INSN(or, MATCH_OR, MASK_OR)
+DECLARE_INSN(and, MATCH_AND, MASK_AND)
+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
+DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
+DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
+DECLARE_INSN(uret, MATCH_URET, MASK_URET)
+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(hret, MATCH_HRET, MASK_HRET)
+DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
+DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
+DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)
+DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
+DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)
+DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)
+DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)
+DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)
+DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)
+DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)
+DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)
+DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)
+DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)
+DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)
+DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)
+DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)
+DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)
+DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)
+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
+DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)
+DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)
+DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)
+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
+DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
+DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)
+DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)
+DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)
+DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)
+DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
+DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)
+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
+DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
+DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
+DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
+DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
+DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
+DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
+DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
+DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)
+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
+DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
+DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
+DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
+DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
+DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
+DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
+DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
+DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
+DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)
+DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
+DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
+DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
+DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
+DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
+DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
+DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
+DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
+DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
+DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
+DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
+DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
+DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
+DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)
+DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
+DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
+DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
+DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
+DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)
+DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
+DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)
+DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)
+DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)
+DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
+DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
+DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
+DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
+DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
+DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
+DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)
+DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
+DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)
+DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
+DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
+DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)
+DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
+DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)
+DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
+DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
+DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
+DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
+DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
+DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
+DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
+DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
+DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
+DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
+DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
+DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
+DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
+DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
+DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
+DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
+DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
+DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
+DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
+DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
+DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
+DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
+DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
+DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
+#endif
+#ifdef DECLARE_CSR
+DECLARE_CSR(fflags, CSR_FFLAGS)
+DECLARE_CSR(frm, CSR_FRM)
+DECLARE_CSR(fcsr, CSR_FCSR)
+DECLARE_CSR(cycle, CSR_CYCLE)
+DECLARE_CSR(time, CSR_TIME)
+DECLARE_CSR(instret, CSR_INSTRET)
+DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)
+DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)
+DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)
+DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)
+DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)
+DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)
+DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)
+DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)
+DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)
+DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)
+DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)
+DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)
+DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)
+DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)
+DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)
+DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)
+DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)
+DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)
+DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)
+DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)
+DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)
+DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)
+DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)
+DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)
+DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)
+DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)
+DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)
+DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)
+DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
+DECLARE_CSR(sstatus, CSR_SSTATUS)
+DECLARE_CSR(sie, CSR_SIE)
+DECLARE_CSR(stvec, CSR_STVEC)
+DECLARE_CSR(scounteren, CSR_SCOUNTEREN)
+DECLARE_CSR(sscratch, CSR_SSCRATCH)
+DECLARE_CSR(sepc, CSR_SEPC)
+DECLARE_CSR(scause, CSR_SCAUSE)
+DECLARE_CSR(sbadaddr, CSR_SBADADDR)
+DECLARE_CSR(sip, CSR_SIP)
+DECLARE_CSR(sptbr, CSR_SPTBR)
+DECLARE_CSR(mstatus, CSR_MSTATUS)
+DECLARE_CSR(misa, CSR_MISA)
+DECLARE_CSR(medeleg, CSR_MEDELEG)
+DECLARE_CSR(mideleg, CSR_MIDELEG)
+DECLARE_CSR(mie, CSR_MIE)
+DECLARE_CSR(mtvec, CSR_MTVEC)
+DECLARE_CSR(mcounteren, CSR_MCOUNTEREN)
+DECLARE_CSR(mscratch, CSR_MSCRATCH)
+DECLARE_CSR(mepc, CSR_MEPC)
+DECLARE_CSR(mcause, CSR_MCAUSE)
+DECLARE_CSR(mbadaddr, CSR_MBADADDR)
+DECLARE_CSR(mip, CSR_MIP)
+DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
+DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
+DECLARE_CSR(pmpcfg2, CSR_PMPCFG2)
+DECLARE_CSR(pmpcfg3, CSR_PMPCFG3)
+DECLARE_CSR(pmpaddr0, CSR_PMPADDR0)
+DECLARE_CSR(pmpaddr1, CSR_PMPADDR1)
+DECLARE_CSR(pmpaddr2, CSR_PMPADDR2)
+DECLARE_CSR(pmpaddr3, CSR_PMPADDR3)
+DECLARE_CSR(pmpaddr4, CSR_PMPADDR4)
+DECLARE_CSR(pmpaddr5, CSR_PMPADDR5)
+DECLARE_CSR(pmpaddr6, CSR_PMPADDR6)
+DECLARE_CSR(pmpaddr7, CSR_PMPADDR7)
+DECLARE_CSR(pmpaddr8, CSR_PMPADDR8)
+DECLARE_CSR(pmpaddr9, CSR_PMPADDR9)
+DECLARE_CSR(pmpaddr10, CSR_PMPADDR10)
+DECLARE_CSR(pmpaddr11, CSR_PMPADDR11)
+DECLARE_CSR(pmpaddr12, CSR_PMPADDR12)
+DECLARE_CSR(pmpaddr13, CSR_PMPADDR13)
+DECLARE_CSR(pmpaddr14, CSR_PMPADDR14)
+DECLARE_CSR(pmpaddr15, CSR_PMPADDR15)
+DECLARE_CSR(tselect, CSR_TSELECT)
+DECLARE_CSR(tdata1, CSR_TDATA1)
+DECLARE_CSR(tdata2, CSR_TDATA2)
+DECLARE_CSR(tdata3, CSR_TDATA3)
+DECLARE_CSR(dcsr, CSR_DCSR)
+DECLARE_CSR(dpc, CSR_DPC)
+DECLARE_CSR(dscratch, CSR_DSCRATCH)
+DECLARE_CSR(mcycle, CSR_MCYCLE)
+DECLARE_CSR(minstret, CSR_MINSTRET)
+DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)
+DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)
+DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)
+DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)
+DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)
+DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)
+DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)
+DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)
+DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)
+DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)
+DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)
+DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)
+DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)
+DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)
+DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)
+DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)
+DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)
+DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)
+DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)
+DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)
+DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)
+DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)
+DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)
+DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)
+DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)
+DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
+DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
+DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
+DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
+DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
+DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
+DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
+DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)
+DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)
+DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)
+DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)
+DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)
+DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)
+DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)
+DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)
+DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)
+DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)
+DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)
+DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)
+DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)
+DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)
+DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)
+DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)
+DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)
+DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)
+DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)
+DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)
+DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)
+DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)
+DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)
+DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)
+DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)
+DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)
+DECLARE_CSR(mvendorid, CSR_MVENDORID)
+DECLARE_CSR(marchid, CSR_MARCHID)
+DECLARE_CSR(mimpid, CSR_MIMPID)
+DECLARE_CSR(mhartid, CSR_MHARTID)
+DECLARE_CSR(cycleh, CSR_CYCLEH)
+DECLARE_CSR(timeh, CSR_TIMEH)
+DECLARE_CSR(instreth, CSR_INSTRETH)
+DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)
+DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)
+DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)
+DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)
+DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)
+DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)
+DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)
+DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)
+DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)
+DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)
+DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)
+DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)
+DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)
+DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)
+DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)
+DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)
+DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)
+DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)
+DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)
+DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)
+DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)
+DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)
+DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)
+DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)
+DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)
+DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)
+DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)
+DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)
+DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)
+DECLARE_CSR(mcycleh, CSR_MCYCLEH)
+DECLARE_CSR(minstreth, CSR_MINSTRETH)
+DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)
+DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)
+DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)
+DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)
+DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)
+DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)
+DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)
+DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)
+DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)
+DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)
+DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)
+DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)
+DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)
+DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)
+DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)
+DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)
+DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)
+DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)
+DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)
+DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)
+DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)
+DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)
+DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)
+DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)
+DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)
+DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)
+DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)
+DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)
+DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
+#endif
+#ifdef DECLARE_CAUSE
+DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
+DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
+DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
+DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
+DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
+DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
+DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
+DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
+DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
+DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
+DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
+DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
+DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
+DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
+DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_assert.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_assert.h
new file mode 100644
index 00000000..ebd70632
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_assert.h
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+#ifndef HAL_ASSERT_HEADER
+#define HAL_ASSERT_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * ASSERT() implementation.
+ ******************************************************************************/
+/* Disable assertions if we do not recognize the compiler. */
+#if defined ( __GNUC__ )
+#if defined(NDEBUG)
+#define ASSERT(CHECK)
+#else
+#define ASSERT(CHECK)\
+ do { \
+ if (!(CHECK)) \
+ { \
+ __asm volatile ("ebreak"); \
+ }\
+ } while(0);
+#endif /* NDEBUG check */
+#endif /* compiler check */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_ASSERT_HEADER */
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_axiswitch.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_axiswitch.c
new file mode 100644
index 00000000..c324cdbd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_axiswitch.c
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_axiswitch.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS AXI switch configuration
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*Returns the value of AXI_HW_CFG_REG register*/
+uint32_t MSS_AXISW_get_hwcfg(void)
+{
+ return (AXISW->HWCFG);
+}
+
+/*Returns the value of AXI_VERSION_ID_REG register*/
+uint32_t MSS_AXISW_get_vid(void)
+{
+ return (AXISW->VID);
+}
+
+/*Performs write operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+
+
+ Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+
+ Burstiness peak rate and transaction rate can be configured using other APIs.
+
+ data: QoS value to be programmed
+ return value: As received form AXI_ERR_BIT in CMD register.
+
+ * */
+uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t data)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = data & AXISW_DATA_QOSVAL_MASK; /*only valid values of bits[3:0]*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_QOS_VAL |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ * Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+ *
+ * returns the data returned by AXI SWITCH read operation for QoS command
+ *
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ */
+uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t* rd_data)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) | (MSS_AXISW_QOS_VAL) | AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *rd_data = AXISW->DATA & AXISW_DATA_QOSVAL_MASK;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the peak rate and transaction rate value for the given master port
+ read/write address channel
+
+ NOTE: Peak rate and transaction rate are programmed simultaneously in one command.
+ So we must make sure that both desired valid values must be provided.
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t peak_rate,
+ mss_axisw_rate_t xct_rate)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+ AXISW->DATA = ((peak_rate) << AXISW_DATA_PEAKRT) | ((xct_rate) << AXISW_DATA_XCTRT) ;
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the peak rate and transaction rate value for the given master port
+read/write address channel
+peak_rate: returns the value of peak rate
+xct_rate: returns the value of transaction rate
+return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t* peak_rate,
+ mss_axisw_rate_t* xct_rate)
+{
+ uint32_t temp = 0u;
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ temp = AXISW->DATA;
+
+ *peak_rate = (temp & AXISW_DATA_PEAKRT_MASK) >> AXISW_DATA_PEAKRT;
+ *xct_rate = (temp & AXISW_DATA_XCTRT_MASK) >> AXISW_DATA_XCTRT;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the burstiness value for the given master port read/write address channel
+
+burstiness_val: burstiness value to be programmed
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+regulator_en: QoS regulator Enable 1= enable, 0 = disable
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t burstiness_val,
+ uint32_t regulator_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ /*Write burstiness value and enable burstiness regulator.
+ * Burstiness_val=0 is not valid.
+ Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1*/
+
+ if(burstiness_val == 0)
+ {
+ return -1;
+ }
+ else
+ {
+ AXISW->DATA = ((burstiness_val - 1u) << AXISW_DATA_BURSTI) | (regulator_en & 0x01);
+ }
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the burstiness value for the given master port read/write address channel
+
+burstiness_val: Return parameter bit 23:16 shows the burstiness value.
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t* burstiness_val)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *burstiness_val = ((AXISW->DATA & AXISW_DATA_BURSTI_MASK) >> AXISW_DATA_BURSTI) + 1u;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t slave_ready_en)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = slave_ready_en & 0x01; /*only valid value of bit0*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_SLV_RDY |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ *
+ * slave_ready_en: returns the data returned by AXI SWITCH read operation for slave ready command
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ *
+ */
+uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t* slave_ready_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_SLV_RDY) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *slave_ready_en = AXISW->DATA & 0x01;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_axiswitch.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_axiswitch.h
new file mode 100644
index 00000000..437ea9bd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_axiswitch.h
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef __MSS_AXISW_H_
+#define __MSS_AXISW_H_ 1
+
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+
+ */
+
+typedef enum {
+ MSS_AXISW_FIC0_RD_CHAN = 0x000,
+ MSS_AXISW_FIC0_WR_CHAN,
+ MSS_AXISW_FIC1_RD_CHAN,
+ MSS_AXISW_FIC1_WR_CHAN,
+ MSS_AXISW_FIC2_RD_CHAN,
+ MSS_AXISW_FIC2_WR_CHAN,
+ MSS_AXISW_ATHENA_RD_CHAN,
+ MSS_AXISW_ATHENA_WR_CHAN,
+ MSS_AXISW_GEM0_RD_CHAN,
+ MSS_AXISW_GEM0_WR_CHAN,
+ MSS_AXISW_GEM1_RD_CHAN,
+ MSS_AXISW_GEM1_WR_CHAN,
+ MSS_AXISW_MMC_RD_CHAN,
+ MSS_AXISW_MMC_WR_CHAN,
+ MSS_AXISW_USB_RD_CHAN,
+ MSS_AXISW_USB_WR_CHAN,
+ MSS_AXISW_SCB_RD_CHAN,
+ MSS_AXISW_SCB_WR_CHAN,
+ MSS_AXISW_CPLEX_D0_RD_CHAN,
+ MSS_AXISW_CPLEX_D0_WR_CHAN,
+ MSS_AXISW_CPLEX_D1_RD_CHAN,
+ MSS_AXISW_CPLEX_D1_WR_CHAN,
+ MSS_AXISW_CPLEX_F0_RD_CHAN,
+ MSS_AXISW_CPLEX_F0_WR_CHAN,
+ MSS_AXISW_CPLEX_F1_RD_CHAN,
+ MSS_AXISW_CPLEX_F1_WR_CHAN,
+ MSS_AXISW_CPLEX_NC_RD_CHAN,
+ MSS_AXISW_CPLEX_NC_WR_CHAN,
+ MSS_AXISW_TRACE_RD_CHAN,
+ MSS_AXISW_TRACE_WR_CHAN,
+} mss_axisw_mport_t;
+
+
+typedef enum {
+ MSS_AXISW_BURSTINESS_EN = 0x00,
+ MSS_AXISW_PEAKRT_XCTRT,
+ MSS_AXISW_QOS_VAL,
+ MSS_AXISW_SLV_RDY,
+} mss_axisw_cmd_t;
+
+typedef enum {
+ MSS_AXISW_MASTER_RD_CHAN = 0x00,
+ MSS_AXISW_MASTER_WR_CHAN = 0x01,
+} mss_axisw_mchan_t;
+
+/*
+The Peak rate and transaction rates are encoded as follows.
+1000_0000_0000 1/2
+0100_0000_0000 1/4
+0010_0000_0000 1/8
+0001_0000_0000 1/16
+0000_1000_0000 1/32
+0000_0100_0000 1/64
+0000_0010_0000 1/128
+0000_0001_0000 1/256
+0000_0000_1000 1/512
+0000_0000_0100 1/1024
+0000_0000_0010 1/2048
+0000_0000_0001 1/4096
+
+Programming the transaction rate as 0000_0000_0000 disables token generation and
+traffic is not regulated based on the tokens.
+
+Programming the peak rate as 0000_0000_0000 disables the peak rate control logic and
+traffic is not regulated by the peak rate logic.
+*/
+typedef enum {
+ MSS_AXISW_TXNRATE_BY4096 = 0x001,
+ MSS_AXISW_TXNRATE_BY2098 = 0x002,
+ MSS_AXISW_TXNRATE_BY1024 = 0x004,
+ MSS_AXISW_TXNRATE_BY512 = 0x008,
+ MSS_AXISW_TXNRATE_BY256 = 0x010,
+ MSS_AXISW_TXNRATE_BY128 = 0x020,
+ MSS_AXISW_TXNRATE_BY64 = 0x040,
+ MSS_AXISW_TXNRATE_BY32 = 0x080,
+ MSS_AXISW_TXNRATE_BY16 = 0x100,
+ MSS_AXISW_TXNRATE_BY8 = 0x200,
+ MSS_AXISW_TXNRATE_BY4 = 0x400,
+ MSS_AXISW_TXNRATE_BY2 = 0x800,
+ MSS_AXISW_TXNRATE_DISABLE = 0x0,
+} mss_axisw_rate_t;
+
+#define AXISW_CMD_EN 31U
+#define AXISW_CMD_EN_MASK (uint32_t)(0x01U << AXISW_CMD_EN)
+
+#define AXISW_CMD_RW 30U
+#define AXISW_CMD_RW_MASK (uint32_t)(0x01U << AXISW_CMD_RW)
+
+#define AXISW_CMD_SWRST 29U
+#define AXISW_CMD_SWRST_MASK (uint32_t)(0x01U << AXISW_CMD_SWRST)
+
+#define AXISW_CMD_ERR 28U
+#define AXISW_CMD_ERR_MASK (uint32_t)(0x01U << AXISW_CMD_ERR)
+
+//#define AXISW_CMD_MPORT 8U
+//#define AXISW_CMD_MPORT_MASK (0x0F << AXISW_CMD_MPORT)
+
+#define AXISW_CMD_RWCHAN 7U
+#define AXISW_CMD_RWCHAN_MASK (uint32_t)(0x1F << AXISW_CMD_RWCHAN)
+
+#define AXISW_CMD_CMD 0U
+#define AXISW_CMD_CMD_MASK (0x01U << AXISW_CMD_CMD)
+
+#define AXISW_DATA_PEAKRT 20U
+#define AXISW_DATA_PEAKRT_MASK (0xFFFU << AXISW_DATA_PEAKRT)
+
+#define AXISW_DATA_XCTRT 4U
+#define AXISW_DATA_XCTRT_MASK (0xFFFU << AXISW_DATA_XCTRT)
+
+#define AXISW_DATA_BURSTI 16U
+#define AXISW_DATA_BURSTI_MASK (0xFFU << AXISW_DATA_BURSTI)
+
+#define AXISW_DATA_QOSVAL 0U
+#define AXISW_DATA_QOSVAL_MASK (0xFU << AXISW_DATA_QOSVAL)
+
+typedef struct
+{
+ __IO uint32_t VID;
+ __IO uint32_t HWCFG;
+ __IO uint32_t CMD;
+ __IO uint32_t DATA;
+} AXISW_TypeDef;
+
+
+#define AXISW ((AXISW_TypeDef*)0x20004000UL)
+
+
+uint32_t MSS_AXISW_get_hwcfg(void);
+uint32_t MSS_AXISW_get_vid(void);
+uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t data);
+uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t* rd_data);
+uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t peak_rate,
+ mss_axisw_rate_t xct_rate);
+uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t* peak_rate,
+ mss_axisw_rate_t* xct_rate);
+int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t burstiness_val,
+ uint32_t regulator_en);
+uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t* burstiness_val);
+uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t slave_ready_en);
+uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t* slave_ready_en);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_AXISW_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_clint.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_clint.c
new file mode 100644
index 00000000..cd1558ac
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_clint.c
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_clint.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief CLINT access data structures and functions.
+ *
+ */
+#include
+#include "mpfs_hal/mss_hal.h"
+
+static uint64_t g_systick_increment[5] = {0ULL,0ULL,0ULL,0ULL,0ULL};
+
+/**
+ * call once at startup
+ * @return
+ */
+void reset_mtime(void)
+{
+#if ROLLOVER_TEST
+ CLINT->MTIME = 0xFFFFFFFFFFFFF000ULL;
+#else
+ CLINT->MTIME = 0ULL;
+#endif
+}
+
+/**
+ * readmtime
+ * @return mtime
+ */
+uint64_t readmtime(void)
+{
+ return (CLINT->MTIME);
+}
+
+/**
+ * Configure system tick
+ * @return SUCCESS or FAIL
+ */
+uint32_t SysTick_Config(void)
+{
+ const uint32_t tick_rate[5] = {HART0_TICK_RATE_MS, HART1_TICK_RATE_MS ,HART2_TICK_RATE_MS ,HART3_TICK_RATE_MS ,HART4_TICK_RATE_MS};
+ volatile uint32_t ret_val = ERROR;
+
+ uint64_t mhart_id = read_csr(mhartid);
+
+ /*
+ * We are assuming the tick rate is in milli-seconds
+ *
+ * convert RTC frequency into milliseconds and multiple by the tick rate
+ *
+ */
+
+ g_systick_increment[mhart_id] = ((LIBERO_SETTING_MSS_RTC_TOGGLE_CLK/1000U) * tick_rate[mhart_id]);
+
+ if (g_systick_increment[mhart_id] > 0ULL)
+ {
+
+ CLINT->MTIMECMP[mhart_id] = CLINT->MTIME + g_systick_increment[mhart_id];
+
+ set_csr(mie, MIP_MTIP); /* mie Register - Machine Timer Interrupt Enable */
+
+ __enable_irq();
+
+ ret_val = SUCCESS;
+ }
+
+ return (ret_val);
+}
+
+/**
+ * Disable system tick interrupt
+ */
+void disable_systick(void)
+{
+ clear_csr(mie, MIP_MTIP); /* mie Register - Machine Timer Interrupt Enable */
+ return;
+}
+
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for machine timer interrupts.
+ */
+void handle_m_timer_interrupt(void)
+{
+
+ volatile uint64_t hart_id = read_csr(mhartid);
+ volatile uint32_t error_loop;
+ clear_csr(mie, MIP_MTIP);
+
+ switch(hart_id)
+ {
+ case 0U:
+ SysTick_Handler_h0_IRQHandler();
+ break;
+ case 1U:
+ SysTick_Handler_h1_IRQHandler();
+ break;
+ case 2U:
+ SysTick_Handler_h2_IRQHandler();
+ break;
+ case 3U:
+ SysTick_Handler_h3_IRQHandler();
+ break;
+ case 4U:
+ SysTick_Handler_h4_IRQHandler();
+ break;
+ default:
+ while (hart_id != 0U)
+ {
+ error_loop++;
+ }
+ break;
+ }
+
+ CLINT->MTIMECMP[read_csr(mhartid)] = CLINT->MTIME + g_systick_increment[hart_id];
+
+ set_csr(mie, MIP_MTIP);
+
+}
+
+
+/**
+ *
+ */
+void handle_m_soft_interrupt(void)
+{
+ volatile uint64_t hart_id = read_csr(mhartid);
+ volatile uint32_t error_loop;
+
+ switch(hart_id)
+ {
+ case 0U:
+ Software_h0_IRQHandler();
+ break;
+ case 1U:
+ Software_h1_IRQHandler();
+ break;
+ case 2U:
+ Software_h2_IRQHandler();
+ break;
+ case 3U:
+ Software_h3_IRQHandler();
+ break;
+ case 4U:
+ Software_h4_IRQHandler();
+ break;
+ default:
+ while (hart_id != 0U)
+ {
+ error_loop++;
+ }
+ break;
+ }
+
+ /*Clear software interrupt*/
+ clear_soft_interrupt();
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_clint.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_clint.h
new file mode 100644
index 00000000..86b4a1cd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_clint.h
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_clint.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief CLINT access data structures and functions.
+ *
+ */
+#ifndef MSS_CLINT_H
+#define MSS_CLINT_H
+
+#include
+#include "encoding.h"
+#include "atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTC_PRESCALER 100U
+#define SUCCESS 0U
+#define ERROR 1U
+
+
+/*==============================================================================
+ * CLINT: Core Local Interrupter
+ */
+typedef struct CLINT_Type_t
+{
+ volatile uint32_t MSIP[5];
+ volatile uint32_t reserved1[(0x4000U - 0x14U)/4U];
+ volatile uint64_t MTIMECMP[5]; /* mtime compare value for each hart. When mtime equals this value, interrupt is generated for particular hart */
+ volatile uint32_t reserved2[((0xbff8U - 0x4028U)/4U)];
+ volatile uint64_t MTIME; /* contains the current mtime value */
+} CLINT_Type;
+
+#define CLINT ((CLINT_Type *)CLINT_BASE)
+
+
+/*==============================================================================
+ * The function raise_soft_interrupt() raises a synchronous software interrupt by
+ * writing into the MSIP register.
+ */
+static inline void raise_soft_interrupt(unsigned long hart_id)
+{
+ /*You need to make sure that the global interrupt is enabled*/
+ /*Note: set_csr(mie, MIP_MSIP) needs to be set on hart you are setting sw interrupt */
+ CLINT->MSIP[hart_id] = 0x01U; /*raise soft interrupt for hart(x) where x== hart ID*/
+ mb();
+}
+
+/*==============================================================================
+ * The function clear_soft_interrupt() clears a synchronous software interrupt by
+ * clearing the MSIP register.
+ */
+static inline void clear_soft_interrupt(void)
+{
+ volatile uint32_t reg;
+ uint64_t hart_id = read_csr(mhartid);
+ CLINT->MSIP[hart_id] = 0x00U; /*clear soft interrupt for hart0*/
+ reg = CLINT->MSIP[hart_id]; /* we read back to make sure it has been written before moving on */
+ /* todo: verify line above guaranteed and best way to achieve result */
+ (void)reg; /* use reg to avoid compiler warning */
+}
+
+/*
+ * return mtime
+ */
+uint64_t readmtime(void);
+
+/**
+ * call once at startup
+ * @return
+ */
+void reset_mtime(void);
+
+/**
+ * Configure system tick
+ * @return SUCCESS or FAIL
+ */
+uint32_t SysTick_Config(void);
+
+/**
+ * Disable system tick interrupt
+ */
+void disable_systick(void);
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for machine timer interrupts.
+ */
+void handle_m_timer_interrupt(void);
+
+/**
+ *
+ */
+void handle_m_soft_interrupt(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_CLINT_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_h2f.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_h2f.c
new file mode 100644
index 00000000..2a1c10b5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_h2f.c
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_h2f.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief H2F access data structures and functions.
+ *
+ */
+#include "mss_plic.h"
+#include "mss_h2f.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+#define H2F_MAPPING_INVALID 255U
+
+/*==============================================================================
+ * H2F_int_mapping, source to H2F output lines
+ * The internal interrupt are multiplexed to fabric I/O lines.
+ * That is, each line will contain several interrupts.
+ */
+
+const uint8_t H2F_int_mapping[BUS_ERROR_UNIT_HART_4]= { \
+
+ H2F_MAPPING_INVALID /*INVALID_IRQn = 0*/, \
+ H2F_MAPPING_INVALID /*L2_METADATA_CORR_IRQn = 1*/, \
+ H2F_MAPPING_INVALID /*L2_METADAT_UNCORR_IRQn = 2*/, \
+ H2F_MAPPING_INVALID /*L2_DATA_CORR_IRQn = 3*/, \
+ H2F_MAPPING_INVALID /*L2_DATA_UNCORR_IRQn = 4*/, \
+ H2F_MAPPING_INVALID /*DMA_CH0_DONE_IRQn = 5*/, \
+ H2F_MAPPING_INVALID /*DMA_CH0_ERR_IRQn = 6*/, \
+ H2F_MAPPING_INVALID /*DMA_CH1_DONE_IRQn = 7*/, \
+ H2F_MAPPING_INVALID /*DMA_CH1_ERR_IRQn = 8*/, \
+ H2F_MAPPING_INVALID /*DMA_CH2_DONE_IRQn = 9*/, \
+ H2F_MAPPING_INVALID /*DMA_CH2_ERR_IRQn = 10*/, \
+ H2F_MAPPING_INVALID /*DMA_CH3_DONE_IRQn = 11*/, \
+ H2F_MAPPING_INVALID /*DMA_CH3_ERR_IRQn = 12*/, \
+
+ 0x00U /*GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0 = 0 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1 = 1 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2 = 2 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3 = 3 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4 = 4 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5 = 5 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6 = 6 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7 = 7 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8 = 8 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9 = 9 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10 = 10 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11 = 11 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12 = 12 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO0_BIT14_or_GPIO2_BIT13_PLIC_13 = 13 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14 = 14 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15 = 15 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16 = 16 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17 = 17 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18 = 18 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19 = 19 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT6_or_GPIO2_BIT20_PLIC_20 = 20 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT7_or_GPIO2_BIT21_PLIC_21 = 21 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT8_or_GPIO2_BIT22_PLIC_22 = 22 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT9_or_GPIO2_BIT23_PLIC_23 = 23 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT10_or_GPIO2_BIT24_PLIC_24 = 24 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT11_or_GPIO2_BIT25_PLIC_25 = 25 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT12_or_GPIO2_BIT26_PLIC_26 = 26 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT13_or_GPIO2_BIT27_PLIC_27 = 27 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO1_BIT14_or_GPIO2_BIT28_PLIC_28 = 28 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT15_or_GPIO2_BIT29_PLIC_29 = 29 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT16_or_GPIO2_BIT30_PLIC_30 = 30 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT17_or_GPIO2_BIT31_PLIC_31 = 31 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO1_BIT18_PLIC_32 = 32 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT19_PLIC_33 = 33 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT20_PLIC_34 = 34 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT21_PLIC_35 = 35 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT22_PLIC_36 = 36 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT23_PLIC_37 = 37 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO0_NON_DIRECT_PLI =38 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_NON_DIRECT_PLIC =39 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO2_NON_DIRECT_PLIC =40 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x01U /*SPI0_PLIC =41 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*SPI1_PLIC =42 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*CAN0_PLIC =43 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*CAN1_PLIC =44 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_MAIN_PLIC =45 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_ALERT_PLIC =46 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_SUS_PLIC =47 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_MAIN_PLIC =48 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_ALERT_PLIC =49 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_SUS_PLIC =50 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_INT_PLIC =51 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE1_PLIC =52 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE2_PLIC =53 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE3_PLIC =54 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_eMAC_PLIC =55 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_MMSL_PLIC =56 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_int_PLIC =57 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE1_PLIC =58 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE2_PLIC =59 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE3_PLIC =60 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_EMAC_PLIC =61 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_MMSL_PLIC =62 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x09U /*DDRC_TRAIN_PLIC =63 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x07U /*SCB_INTERRUPT_PLIC =64 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*ECC_ERROR_PLIC =65 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*ECC_CORRECT_PLIC =66 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*RTC_WAKEUP_PLIC =67 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*RTC_MATCH_PLIC =68 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0CU /*TIMER1_PLIC =69 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0CU /*TIMER2_PLIC =70 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*ENVM_PLIC =71 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*QSPI_PLIC =72 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0EU /*USB_DMA_PLIC =73 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0EU /*USB_MC_PLIC =74 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0FU /*MMC_main_PLIC =75 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0FU /*MMC_wakeup_PLIC =76 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART0_PLIC_77 =77 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART1_PLIC =78 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART2_PLIC =79 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART3_PLIC =80 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART4_PLIC =81 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0AU /*G5C_DEVRST_PLIC =82 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x08U /*g5c_MESSAGE_PLIC =83 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_VC_INTERRUPT_PLIC =84 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_SMB_INTERRUPT_PLIC =85 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*E51_0_MAINTENACE_PLIC =86 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG0_MRVP_PLIC =87 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG1_MRVP_PLIC =88 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG2_MRVP_PLIC =89 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG3_MRVP_PLIC =90 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG4_MRVP_PLIC =91 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG0_TOUT_PLIC =92 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG1_TOUT_PLIC =93 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG2_TOUT_PLIC =94 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG3_TOUT_PLIC =95 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG4_TOUT_PLIC =96 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*G5C_MSS_SPI_PLIC =97 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*VOLT_TEMP_ALARM_PLIC =98 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_COMPLETE_PLIC =99 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_ALARM_PLIC =100 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_BUS_ERROR_PLIC =101 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_AXIC_US_PLIC =102 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_AXIC_DS_PLIC =103 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_0_PLIC = 105 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_1_PLIC = 106 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_2_PLIC = 107 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_3_PLIC = 108 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_4_PLIC = 109 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_5_PLIC = 110 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_6_PLIC = 111 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_7_PLIC = 112 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_8_PLIC = 113 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_9_PLIC = 114 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_10_PLIC = 115 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_11_PLIC = 116 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_12_PLIC = 117 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_13_PLIC = 118 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_14_PLIC = 119 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_15_PLIC = 120 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_16_PLIC = 121 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_17_PLIC = 122 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_18_PLIC = 123 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_19_PLIC = 124 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_20_PLIC = 125 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_21_PLIC = 126 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_22_PLIC = 127 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_23_PLIC = 128 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_24_PLIC = 129 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_25_PLIC = 130 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_26_PLIC = 131 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_27_PLIC = 132 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_28_PLIC = 133 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_29_PLIC = 134 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_30_PLIC = 135 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_31_PLIC = 136 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_32_PLIC = 137 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_33_PLIC = 138 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_34_PLIC = 139 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_35_PLIC = 140 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_36_PLIC = 141 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_37_PLIC = 142 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_38_PLIC = 143 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_39_PLIC = 144 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_40_PLIC = 145 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_41_PLIC = 146 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_42_PLIC = 147 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_43_PLIC = 148 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_44_PLIC = 149 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_45_PLIC = 150 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_46_PLIC = 151 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_47_PLIC = 152 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_48_PLIC = 153 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_49_PLIC = 154 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_50_PLIC = 155 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_51_PLIC = 156 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_52_PLIC = 157 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_53_PLIC = 158 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_54_PLIC = 159 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_55_PLIC = 160 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_56_PLIC = 161 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_57_PLIC = 162 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_58_PLIC = 163 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_59_PLIC = 164 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_60_PLIC = 165 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_61_PLIC = 166 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_62_PLIC = 167 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_63_PLIC = 168 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_0 = 182*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_1 = 183*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_2 = 184*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_3 = 185*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_4 = 186 */
+
+};
+
+
+/**
+ * get source to fabric signal mapping
+ * @param source_int
+ * @return
+ */
+static uint32_t get_corresponding_h2f_output(uint32_t source_int)
+{
+ uint32_t h2f_line = H2F_int_mapping[source_int];
+
+ if(h2f_line < H2F_MAPPING_INVALID) /* if no error */
+ {
+ return(0x01U << h2f_line);
+ }
+
+ return(h2f_line);
+
+}
+
+/**
+ * set H2F controller to reset to defaults- disabled
+ */
+void reset_h2f(void)
+{
+ uint8_t index = 0U;
+ H2F_CONTROLLER->ENABLE = 0U;
+ while(index < 4U)
+ {
+ H2F_CONTROLLER->PLENABLE[index] = 0U;
+ index++;
+ }
+}
+
+/**
+ * enables output which will mirror PLIC input. PLIC mapping given above for reference
+ * @param source_int
+ */
+void enable_h2f_int_output(uint32_t source_int)
+{
+
+ uint32_t output_signal = get_corresponding_h2f_output(source_int);
+
+ if(output_signal != H2F_MAPPING_INVALID)
+ {
+ source_int -= OFFSET_TO_MSS_GLOBAL_INTS;
+
+ /* enable the input */
+ H2F_CONTROLLER->PLENABLE[source_int/32U] |= (0x01U << (source_int % 32U));
+
+ /* enable the output */
+ H2F_CONTROLLER->ENABLE |= ((output_signal<<16U) | 0x01U);
+ }
+}
+
+
+/**
+ * enables output which will mirror PLIC input. PLIC mapping given above for reference
+ * @param source_int
+ */
+void disable_h2f_int_output(uint32_t source_int)
+{
+ uint32_t output_signal = get_corresponding_h2f_output(source_int);
+
+ if(output_signal != H2F_MAPPING_INVALID)
+ {
+ /* enable the input */
+ H2F_CONTROLLER->PLENABLE[source_int/32U] &= ~(source_int % 32U);
+ /* enable the output */
+ H2F_CONTROLLER->ENABLE &= ~(((output_signal<<16U)));
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_h2f.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_h2f.h
new file mode 100644
index 00000000..280e465b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_h2f.h
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_h2f.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief H2F access data structures and functions.
+ *
+ * Definitions and functions associated with host to fabric interrupt controller.
+ *
+ */
+
+#ifndef MSS_H2F_H
+#define MSS_H2F_H
+
+#include "mpfs_hal_config/mss_sw_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+H2F line Group Ored (no of interrupts ored to one output line)
+0 GPIO 41
+1 MMUART,SPI,CAN 9
+2 I2C 6
+3 MAC0 6
+4 MAC1 6
+5 WATCHDOGS 10
+6 Maintenance 3
+7 SCB 1
+8 G5C-Message 1
+9 DDRC 1
+10 G5C-DEVRST 2
+11 RTC/USOC 4
+12 TIMER 2
+13 ENVM, QSPI 2
+14 USB 2
+15 MMC/SDIO 2
+*/
+
+/*==============================================================================
+ * Host to Fabric interrupt controller
+ *
+ * For an interrupt to activate the PENABLE and appropriate HENABLE and PENABLE bits must be set.
+ *
+ * Note. Since Interrupts 127:94 are not used in the system the enable registers are non-write-able and always read as zeros.
+ *
+ */
+
+typedef struct
+{
+ volatile uint32_t ENABLE; /* bit o: Enables all the H2FINT outputs, bit 31:16 Enables individual H2F outputs */
+ volatile uint32_t H2FSTATUS; /* 15:0 Read back of the 16-bit H2F Interrupts before the H2F and global enable */
+ uint32_t filler[2U]; /* fill the gap in the memory map */
+ volatile uint32_t PLSTATUS[4U]; /* Indicates that the PLINT interrupt is active before the PLINT enable
+ i.e. direct read of the PLINT inputs [31:0] from PLSTATUS[0]
+ direct read of the PLINT inputs [63:32] from PLSTATUS[1]
+ etc */
+ volatile uint32_t PLENABLE[4U]; /* Enables PLINT interrupts PLENABLE[0] 31:0, PLENABLE[1] 63:32, 95:64, 127:96 */
+} H2F_CONTROLLER_Type;
+
+#ifndef H2F_BASE_ADDRESS
+#if (LIBERO_SETTING_APBBUS_CR & (1U<<23U))
+#define H2F_BASE_ADDRESS 0x28126000
+#else
+#define H2F_BASE_ADDRESS 0x20126000
+#endif
+#endif
+
+#define H2F_CONTROLLER ((H2F_CONTROLLER_Type *)H2F_BASE_ADDRESS)
+
+void reset_h2f(void);
+void enable_h2f_int_output(uint32_t source_int);
+void disable_h2f_int_output(uint32_t source_int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_H2F_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_hart_ints.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_hart_ints.h
new file mode 100644
index 00000000..c559d193
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_hart_ints.h
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_hart_ints.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS local interrupt definitions
+ *
+ * Definitions and functions associated with local interrupts for each hart.
+ *
+ */
+#ifndef MSS_HART_INTS_H
+#define MSS_HART_INTS_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct BEU_Type_
+{
+ volatile uint64_t CAUSE;
+ volatile uint64_t VALUE;
+ volatile uint64_t ENABLE;
+ volatile uint64_t PLIC_INT;
+ volatile uint64_t ACCRUED;
+ volatile uint64_t LOCAL_INT;
+ volatile uint64_t reserved2[((0x1000U/8U) - 0x6U)];
+} BEU_Type;
+
+typedef struct BEU_Types_
+{
+ volatile BEU_Type regs[5];
+} BEU_Types;
+
+#define MSS_BUS_ERROR_UNIT_H0 0x01700000UL
+#define MSS_BUS_ERROR_UNIT_H1 0x01701000UL
+#define MSS_BUS_ERROR_UNIT_H2 0x01702000UL
+#define MSS_BUS_ERROR_UNIT_H3 0x01703000UL
+#define MSS_BUS_ERROR_UNIT_H4 0x01704000UL
+
+#define BEU ((BEU_Types *)MSS_BUS_ERROR_UNIT_H0)
+
+/*
+ * Interrupt numbers U0
+ */
+
+#define MAINTENANCE_E51_INT 0
+#define USOC_SMB_INTERRUPT_E51_INT 1
+#define USOC_VC_INTERRUPT_E51_INT 2
+#define G5C_MESSAGE_E51_INT 3
+#define G5C_DEVRST_E51_INT 4
+#define WDOG4_TOUT_E51_INT 5
+#define WDOG3_TOUT_E51_INT 6
+#define WDOG2_TOUT_E51_INT 7
+#define WDOG1_TOUT_E51_INT 8
+#define WDOG0_TOUT_E51_INT 9
+#define WDOG0_MVRP_E51_INT 10
+#define MMUART0_E51_INT 11
+#define ENVM_E51_INT 12
+#define ECC_CORRECT_E51_INT 13
+#define ECC_ERROR_E51_INT 14
+#define scb_INTERRUPT_E51_INT 15
+#define FABRIC_F2H_32_E51_INT 16
+#define FABRIC_F2H_33_E51_INT 17
+#define FABRIC_F2H_34_E51_INT 18
+#define FABRIC_F2H_35_E51_INT 19
+#define FABRIC_F2H_36_E51_INT 20
+#define FABRIC_F2H_37_E51_INT 21
+#define FABRIC_F2H_38_E51_INT 22
+#define FABRIC_F2H_39_E51_INT 23
+#define FABRIC_F2H_40_E51_INT 24
+#define FABRIC_F2H_41_E51_INT 25
+
+#define FABRIC_F2H_42_E51_INT 26
+#define FABRIC_F2H_43_E51_INT 27
+#define FABRIC_F2H_44_E51_INT 28
+#define FABRIC_F2H_45_E51_INT 29
+#define FABRIC_F2H_46_E51_INT 30
+#define FABRIC_F2H_47_E51_INT 31
+#define FABRIC_F2H_48_E51_INT 32
+#define FABRIC_F2H_49_E51_INT 33
+#define FABRIC_F2H_50_E51_INT 34
+#define FABRIC_F2H_51_E51_INT 35
+
+#define FABRIC_F2H_52_E51_INT 36
+#define FABRIC_F2H_53_E51_INT 37
+#define FABRIC_F2H_54_E51_INT 38
+#define FABRIC_F2H_55_E51_INT 39
+#define FABRIC_F2H_56_E51_INT 40
+#define FABRIC_F2H_57_E51_INT 41
+#define FABRIC_F2H_58_E51_INT 42
+#define FABRIC_F2H_59_E51_INT 43
+#define FABRIC_F2H_60_E51_INT 44
+#define FABRIC_F2H_61_E51_INT 45
+
+#define FABRIC_F2H_62_E51_INT 46
+#define FABRIC_F2H_63_E51_INT 47
+
+#define LOCAL_INT_MAX 47U /* Highest numbered */
+#define LOCAL_INT_UNUSED 127U /* Signifies unused interrupt */
+/*
+ * Interrupts associated with
+ * MAINTENANCE_E51_INT
+ *
+ * A group of interrupt events are grouped into a single maintenance interrupt to the E51 CPU,
+ * on receiving this interrupt the E51 should read the maintenance system register to find out
+ * the interrupt source. The maintenance interrupts are defined below
+ */
+#define MAINTENANCE_E51_pll_INT 0
+#define MAINTENANCE_E51_mpu_INT 1
+#define MAINTENANCE_E51_lp_state_enter_INT 2
+#define MAINTENANCE_E51_lp_state_exit_INT 3
+#define MAINTENANCE_E51_ff_start_INT 4
+#define MAINTENANCE_E51_ff_end_INT 5
+#define MAINTENANCE_E51_fpga_on_INT 6
+#define MAINTENANCE_E51_fpga_off_INT 7
+#define MAINTENANCE_E51_scb_error_INT 8
+#define MAINTENANCE_E51_scb_fault_INT 9
+#define MAINTENANCE_E51_mesh_error_INT 10
+#define MAINTENANCE_E51_io_bank_b2_on_INT 12
+#define MAINTENANCE_E51_io_bank_b4_on_INT 13
+#define MAINTENANCE_E51_io_bank_b5_on_INT 14
+#define MAINTENANCE_E51_io_bank_b6_on_INT 15
+#define MAINTENANCE_E51_io_bank_b2_off_INT 16
+#define MAINTENANCE_E51_io_bank_b4_off_INT 17
+#define MAINTENANCE_E51_io_bank_b5_off_INT 18
+#define MAINTENANCE_E51_io_bank_b6_off_INT 19
+
+
+/*
+ * E51-0 is Maintenance Interrupt CPU needs to read status register to determine exact cause:
+ * These defines added here for clarity need to replay with status register defines
+ * for determining interrupt cause
+ */
+#ifndef FOR_CLARITY
+# define FOR_CLARITY 0
+#endif
+
+#if FOR_CLARITY
+# define mpu_fail_plic 0
+# define lp_state_enter_plic 1
+# define lp_state_exit_plic 2
+# define ff_start_plic 3
+# define ff_end_plic 4
+# define fpga_on_plic 5
+# define fpga_off_plic 6
+# define scb_error_plic 7
+# define scb_fault_plic 8
+# define mesh_fail_plic 9
+#endif
+
+/*
+ * Interrupt numbers U54's
+ */
+
+/* U0 (first U54) and U1 connected to mac0 */
+#define MAC0_INT_U54_INT 8 /* determine source mac using hart ID */
+#define MAC0_QUEUE1_U54_INT 7
+#define MAC0_QUEUE2_U54_INT 6
+#define MAC0_QUEUE3_U54_INT 5
+#define MAC0_EMAC_U54_INT 4
+#define MAC0_MMSL_U54_INT 3
+
+/* U2 and U3 connected to mac1 */
+#define MAC1_INT_U54_INT 8 /* determine source mac using hart ID */
+#define MAC1_QUEUE1_U54_INT 7
+#define MAC1_QUEUE2_U54_INT 6
+#define MAC1_QUEUE3_U54_INT 5
+#define MAC1_EMAC_U54_INT 4
+#define MAC1_MMSL_U54_INT 3
+
+/* MMUART1 connected to U54 0 */
+/* MMUART2 connected to U54 1 */
+/* MMUART3 connected to U54 2 */
+/* MMUART4 connected to U54 3 */
+#define MMUARTx_U54_INT 11 /* MMUART1 connected to U54 0 */
+#define WDOGx_MVRP_U54_INT 10 /* determine source mac using hart ID */
+#define WDOGx_TOUT_U54_INT 9 /* determine source mac using hart ID */
+
+#define H2_FABRIC_F2H_0_U54_INT 16
+#define H2_FABRIC_F2H_1_U54_INT 17
+#define H2_FABRIC_F2H_2_U54_INT 18
+#define H2_FABRIC_F2H_3_U54_INT 19
+#define H2_FABRIC_F2H_4_U54_INT 20
+#define H2_FABRIC_F2H_5_U54_INT 21
+#define H2_FABRIC_F2H_6_U54_INT 22
+#define H2_FABRIC_F2H_7_U54_INT 23
+#define H2_FABRIC_F2H_8_U54_INT 24
+#define H2_FABRIC_F2H_9_U54_INT 25
+
+#define H2_FABRIC_F2H_10_U54_INT 26
+#define H2_FABRIC_F2H_11_U54_INT 27
+#define H2_FABRIC_F2H_12_U54_INT 28
+#define H2_FABRIC_F2H_13_U54_INT 29
+#define H2_FABRIC_F2H_14_U54_INT 30
+#define H2_FABRIC_F2H_15_U54_INT 31
+#define H2_FABRIC_F2H_16_U54_INT 32
+#define H2_FABRIC_F2H_17_U54_INT 33
+#define H2_FABRIC_F2H_18_U54_INT 34
+#define H2_FABRIC_F2H_19_U54_INT 35
+
+#define H2_FABRIC_F2H_20_U54_INT 36
+#define H2_FABRIC_F2H_21_U54_INT 37
+#define H2_FABRIC_F2H_22_U54_INT 38
+#define H2_FABRIC_F2H_23_U54_INT 39
+#define H2_FABRIC_F2H_24_U54_INT 40
+#define H2_FABRIC_F2H_25_U54_INT 41
+#define H2_FABRIC_F2H_26_U54_INT 42
+#define H2_FABRIC_F2H_27_U54_INT 43
+#define H2_FABRIC_F2H_28_U54_INT 44
+#define H2_FABRIC_F2H_29_U54_INT 45
+
+#define H2_FABRIC_F2H_30_U54_INT 46
+#define H2_FABRIC_F2H_31_U54_INT 47
+
+
+void handle_m_ext_interrupt(void);
+void Software_h0_IRQHandler(void);
+void Software_h1_IRQHandler(void);
+void Software_h2_IRQHandler(void);
+void Software_h3_IRQHandler(void);
+void Software_h4_IRQHandler(void);
+void SysTick_Handler_h0_IRQHandler(void);
+void SysTick_Handler_h1_IRQHandler(void);
+void SysTick_Handler_h2_IRQHandler(void);
+void SysTick_Handler_h3_IRQHandler(void);
+void SysTick_Handler_h4_IRQHandler(void);
+
+/*
+ *
+ * Local interrupt defines
+ *
+ */
+void maintenance_e51_local_IRQHandler_0(void);
+void usoc_smb_interrupt_e51_local_IRQHandler_1(void);
+void usoc_vc_interrupt_e51_local_IRQHandler_2(void);
+void g5c_message_e51_local_IRQHandler_3(void);
+void g5c_devrst_e51_local_IRQHandler_4(void);
+void wdog4_tout_e51_local_IRQHandler_5(void);
+void wdog3_tout_e51_local_IRQHandler_6(void);
+void wdog2_tout_e51_local_IRQHandler_7(void);
+void wdog1_tout_e51_local_IRQHandler_8(void);
+void wdog0_tout_e51_local_IRQHandler_9(void);
+void wdog0_mvrp_e51_local_IRQHandler_10(void);
+void mmuart0_e51_local_IRQHandler_11(void);
+void envm_e51_local_IRQHandler_12(void);
+void ecc_correct_e51_local_IRQHandler_13(void);
+void ecc_error_e51_local_IRQHandler_14(void);
+void scb_interrupt_e51_local_IRQHandler_15(void);
+void fabric_f2h_32_e51_local_IRQHandler_16(void);
+void fabric_f2h_33_e51_local_IRQHandler_17(void);
+void fabric_f2h_34_e51_local_IRQHandler_18(void);
+void fabric_f2h_35_e51_local_IRQHandler_19(void);
+void fabric_f2h_36_e51_local_IRQHandler_20(void);
+void fabric_f2h_37_e51_local_IRQHandler_21(void);
+void fabric_f2h_38_e51_local_IRQHandler_22(void);
+void fabric_f2h_39_e51_local_IRQHandler_23(void);
+void fabric_f2h_40_e51_local_IRQHandler_24(void);
+void fabric_f2h_41_e51_local_IRQHandler_25(void);
+void fabric_f2h_42_e51_local_IRQHandler_26(void);
+void fabric_f2h_43_e51_local_IRQHandler_27(void);
+void fabric_f2h_44_e51_local_IRQHandler_28(void);
+void fabric_f2h_45_e51_local_IRQHandler_29(void);
+void fabric_f2h_46_e51_local_IRQHandler_30(void);
+void fabric_f2h_47_e51_local_IRQHandler_31(void);
+void fabric_f2h_48_e51_local_IRQHandler_32(void);
+void fabric_f2h_49_e51_local_IRQHandler_33(void);
+void fabric_f2h_50_e51_local_IRQHandler_34(void);
+void fabric_f2h_51_e51_local_IRQHandler_35(void);
+void fabric_f2h_52_e51_local_IRQHandler_36(void);
+void fabric_f2h_53_e51_local_IRQHandler_37(void);
+void fabric_f2h_54_e51_local_IRQHandler_38(void);
+void fabric_f2h_55_e51_local_IRQHandler_39(void);
+void fabric_f2h_56_e51_local_IRQHandler_40(void);
+void fabric_f2h_57_e51_local_IRQHandler_41(void);
+void fabric_f2h_58_e51_local_IRQHandler_42(void);
+void fabric_f2h_59_e51_local_IRQHandler_43(void);
+void fabric_f2h_60_e51_local_IRQHandler_44(void);
+void fabric_f2h_61_e51_local_IRQHandler_45(void);
+void fabric_f2h_62_e51_local_IRQHandler_46(void);
+void fabric_f2h_63_e51_local_IRQHandler_47(void);
+
+/*
+ * U54
+ */
+void spare_u54_local_IRQHandler_0(void);
+void spare_u54_local_IRQHandler_1(void);
+void spare_u54_local_IRQHandler_2(void);
+
+void mac_mmsl_u54_1_local_IRQHandler_3(void);
+void mac_emac_u54_1_local_IRQHandler_4(void);
+void mac_queue3_u54_1_local_IRQHandler_5(void);
+void mac_queue2_u54_1_local_IRQHandler_6(void);
+void mac_queue1_u54_1_local_IRQHandler_7(void);
+void mac_int_u54_1_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_2_local_IRQHandler_3(void);
+void mac_emac_u54_2_local_IRQHandler_4(void);
+void mac_queue3_u54_2_local_IRQHandler_5(void);
+void mac_queue2_u54_2_local_IRQHandler_6(void);
+void mac_queue1_u54_2_local_IRQHandler_7(void);
+void mac_int_u54_2_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_3_local_IRQHandler_3(void);
+void mac_emac_u54_3_local_IRQHandler_4(void);
+void mac_queue3_u54_3_local_IRQHandler_5(void);
+void mac_queue2_u54_3_local_IRQHandler_6(void);
+void mac_queue1_u54_3_local_IRQHandler_7(void);
+void mac_int_u54_3_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_4_local_IRQHandler_3(void);
+void mac_emac_u54_4_local_IRQHandler_4(void);
+void mac_queue3_u54_4_local_IRQHandler_5(void);
+void mac_queue2_u54_4_local_IRQHandler_6(void);
+void mac_queue1_u54_4_local_IRQHandler_7(void);
+void mac_int_u54_4_local_IRQHandler_8(void);
+
+void wdog_tout_u54_h1_local_IRQHandler_9(void);
+void wdog_tout_u54_h2_local_IRQHandler_9(void);
+void wdog_tout_u54_h3_local_IRQHandler_9(void);
+void wdog_tout_u54_h4_local_IRQHandler_9(void);
+void mvrp_u54_local_IRQHandler_10(void);
+void mmuart_u54_h1_local_IRQHandler_11(void);
+void mmuart_u54_h2_local_IRQHandler_11(void);
+void mmuart_u54_h3_local_IRQHandler_11(void);
+void mmuart_u54_h4_local_IRQHandler_11(void);
+void spare_u54_local_IRQHandler_12(void);
+void spare_u54_local_IRQHandler_13(void);
+void spare_u54_local_IRQHandler_14(void);
+void spare_u54_local_IRQHandler_15(void);
+void fabric_f2h_0_u54_local_IRQHandler_16(void);
+void fabric_f2h_1_u54_local_IRQHandler_17(void);
+void fabric_f2h_2_u54_local_IRQHandler_18(void);
+void fabric_f2h_3_u54_local_IRQHandler_19(void);
+void fabric_f2h_4_u54_local_IRQHandler_20(void);
+void fabric_f2h_5_u54_local_IRQHandler_21(void);
+void fabric_f2h_6_u54_local_IRQHandler_22(void);
+void fabric_f2h_7_u54_local_IRQHandler_23(void);
+void fabric_f2h_8_u54_local_IRQHandler_24(void);
+void fabric_f2h_9_u54_local_IRQHandler_25(void);
+void fabric_f2h_10_u54_local_IRQHandler_26(void);
+void fabric_f2h_11_u54_local_IRQHandler_27(void);
+void fabric_f2h_12_u54_local_IRQHandler_28(void);
+void fabric_f2h_13_u54_local_IRQHandler_29(void);
+void fabric_f2h_14_u54_local_IRQHandler_30(void);
+void fabric_f2h_15_u54_local_IRQHandler_31(void);
+void fabric_f2h_16_u54_local_IRQHandler_32(void);
+void fabric_f2h_17_u54_local_IRQHandler_33(void);
+void fabric_f2h_18_u54_local_IRQHandler_34(void);
+void fabric_f2h_19_u54_local_IRQHandler_35(void);
+void fabric_f2h_20_u54_local_IRQHandler_36(void);
+void fabric_f2h_21_u54_local_IRQHandler_37(void);
+void fabric_f2h_22_u54_local_IRQHandler_38(void);
+void fabric_f2h_23_u54_local_IRQHandler_39(void);
+void fabric_f2h_24_u54_local_IRQHandler_40(void);
+void fabric_f2h_25_u54_local_IRQHandler_41(void);
+void fabric_f2h_26_u54_local_IRQHandler_42(void);
+void fabric_f2h_27_u54_local_IRQHandler_43(void);
+void fabric_f2h_28_u54_local_IRQHandler_44(void);
+void fabric_f2h_29_u54_local_IRQHandler_45(void);
+void fabric_f2h_30_u54_local_IRQHandler_46(void);
+void fabric_f2h_31_u54_local_IRQHandler_47(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_HART_INTS_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c
new file mode 100644
index 00000000..6194ae57
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c
@@ -0,0 +1,1663 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_irq_handler_stubs.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS MSS Interrupt Function stubs.
+ *
+ * The functions below will only be linked with the application code if the user
+ * does not provide an implementation for these functions. These functions are
+ * defined with weak linking so that they can be overridden by a function with
+ * same prototype in the user's application code.
+ *
+ */
+#include
+#include "mpfs_hal/mss_hal.h"
+
+
+__attribute__((weak)) void handle_m_ext_interrupt(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h0_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h1_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h2_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h3_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h4_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h0_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h1_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h2_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h3_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h4_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) uint8_t Invalid_IRQHandler(void)
+{
+ return(0U);
+}
+#ifdef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t External_1_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_2_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_3_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t USART0_plic_4_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_5_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_6_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_7_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_8_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_9_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_10_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_11_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_12_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_13_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_14_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_15_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_16_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_17_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_18_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_19_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_20_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_21_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_22_IRQHandler(void)
+{
+ return(0U);
+}
+#endif
+
+__attribute__((weak)) uint8_t dma_ch0_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch0_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch1_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch1_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch2_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch2_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch3_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch3_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+#ifdef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t External_31_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t External_32_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_33_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_34_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_35_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_36_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_37_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_38_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_39_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_40_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_41_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_42_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_43_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_44_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_45_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_46_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_47_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_48_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_49_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_50_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_51_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_52_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t MAC0_plic_53_IRQHandler(void)
+{
+ return(0U);
+}
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t l2_metadata_corr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_metadata_uncorr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_data_corr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_data_uncorr_IRQHandler(void)
+{
+ return(0U);
+}
+#endif /* ifndef SIFIVE_HIFIVE_UNLEASHED */
+
+
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler(void)
+ {
+ return(0U);
+ }
+
+__attribute__((weak)) uint8_t gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio1_bit18_plic_32_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit19_plic_33_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit20_plic_34_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit21_plic_35_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit22_plic_36_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit23_plic_37_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio0_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio2_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t spi0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t spi1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t external_can0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t can1_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_i2c0_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_i2c0_alert_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c0_sus_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_alert_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_sus_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_int_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_emac_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_mmsl_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_int_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_emac_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_mmsl_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ddrc_train_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t scb_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ecc_error_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ecc_correct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t rtc_wakeup_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t rtc_match_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t timer1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t timer2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t envm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t qspi_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usb_dma_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usb_mc_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmc_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmc_wakeup_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart0_plic_77_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t g5c_devrst_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t g5c_message_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usoc_vc_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usoc_smb_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t e51_0_Maintence_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t wdog0_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog1_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog2_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog3_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog4_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog0_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog1_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog2_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog3_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog4_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t g5c_mss_spi_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t volt_temp_alarm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_complete_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_alarm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_bus_error_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t usoc_axic_us_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t usoc_axic_ds_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t reserved_104_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+
+__attribute__((weak)) uint8_t fabric_f2h_0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_5_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_6_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_7_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_8_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_9_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_10_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_11_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_12_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_13_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_14_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_15_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_16_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_17_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_18_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_19_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_20_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_21_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_22_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_23_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_24_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_25_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_26_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_27_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_28_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_29_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_30_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_31_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_32_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_33_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_34_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_35_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_36_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_37_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_38_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_39_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_40_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_41_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_42_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_43_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_44_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_45_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_46_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_47_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_48_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_49_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_50_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_51_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_52_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_53_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_54_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_55_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_56_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_57_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_58_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_59_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_60_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_61_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_62_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_63_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+/* Local interrupt stubs */
+__attribute__((weak)) void maintenance_e51_local_IRQHandler_0(void)
+{
+}
+__attribute__((weak)) void usoc_smb_interrupt_e51_local_IRQHandler_1(void)
+{
+}
+__attribute__((weak)) void usoc_vc_interrupt_e51_local_IRQHandler_2(void)
+{
+}
+__attribute__((weak)) void g5c_message_e51_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void g5c_devrst_e51_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void wdog4_tout_e51_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void wdog3_tout_e51_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void wdog2_tout_e51_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void wdog1_tout_e51_local_IRQHandler_8(void)
+{
+}
+__attribute__((weak)) void wdog0_tout_e51_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog0_mvrp_e51_local_IRQHandler_10(void)
+{
+}
+
+__attribute__((weak)) void mmuart0_e51_local_IRQHandler_11(void)
+{
+}
+
+__attribute__((weak)) void envm_e51_local_IRQHandler_12(void)
+{
+}
+
+__attribute__((weak)) void ecc_correct_e51_local_IRQHandler_13(void)
+{
+}
+
+__attribute__((weak)) void ecc_error_e51_local_IRQHandler_14(void)
+{
+}
+
+__attribute__((weak)) void scb_interrupt_e51_local_IRQHandler_15(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_32_e51_local_IRQHandler_16(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_33_e51_local_IRQHandler_17(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_34_e51_local_IRQHandler_18(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_35_e51_local_IRQHandler_19(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_36_e51_local_IRQHandler_20(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_37_e51_local_IRQHandler_21(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_38_e51_local_IRQHandler_22(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_39_e51_local_IRQHandler_23(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_40_e51_local_IRQHandler_24(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_41_e51_local_IRQHandler_25(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_42_e51_local_IRQHandler_26(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_43_e51_local_IRQHandler_27(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_44_e51_local_IRQHandler_28(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_45_e51_local_IRQHandler_29(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_46_e51_local_IRQHandler_30(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_47_e51_local_IRQHandler_31(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_48_e51_local_IRQHandler_32(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_49_e51_local_IRQHandler_33(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_50_e51_local_IRQHandler_34(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_51_e51_local_IRQHandler_35(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_52_e51_local_IRQHandler_36(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_53_e51_local_IRQHandler_37(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_54_e51_local_IRQHandler_38(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_55_e51_local_IRQHandler_39(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_56_e51_local_IRQHandler_40(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_57_e51_local_IRQHandler_41(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_58_e51_local_IRQHandler_42(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_59_e51_local_IRQHandler_43(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_60_e51_local_IRQHandler_44(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_61_e51_local_IRQHandler_45(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_62_e51_local_IRQHandler_46(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_63_e51_local_IRQHandler_47(void)
+{
+}
+
+
+/*
+ * U54
+ */
+__attribute__((weak)) void spare_u54_local_IRQHandler_0(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_1(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_2(void)
+{
+}
+
+/* Ethernet MACs - GEM0 is on U54s 1 and 2, GEM1 is on U54s 3 and 4 */
+
+/* U54 1 */
+__attribute__((weak)) void mac_mmsl_u54_1_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_1_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_1_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_1_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_1_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_1_local_IRQHandler_8(void)
+{
+}
+
+/* U54 2 */
+__attribute__((weak)) void mac_mmsl_u54_2_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_2_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_2_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_2_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_2_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_2_local_IRQHandler_8(void)
+{
+}
+
+/* U54 3 */
+__attribute__((weak)) void mac_mmsl_u54_3_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_3_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_3_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_3_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_3_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_3_local_IRQHandler_8(void)
+{
+}
+
+/* U54 4 */
+__attribute__((weak)) void mac_mmsl_u54_4_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_4_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_4_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_4_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_4_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_4_local_IRQHandler_8(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h1_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h2_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h3_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h4_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void mvrp_u54_local_IRQHandler_10(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h1_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h2_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h3_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h4_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_12(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_13(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_14(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_15(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_0_u54_local_IRQHandler_16(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_1_u54_local_IRQHandler_17(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_2_u54_local_IRQHandler_18(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_3_u54_local_IRQHandler_19(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_4_u54_local_IRQHandler_20(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_5_u54_local_IRQHandler_21(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_6_u54_local_IRQHandler_22(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_7_u54_local_IRQHandler_23(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_8_u54_local_IRQHandler_24(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_9_u54_local_IRQHandler_25(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_10_u54_local_IRQHandler_26(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_11_u54_local_IRQHandler_27(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_12_u54_local_IRQHandler_28(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_13_u54_local_IRQHandler_29(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_14_u54_local_IRQHandler_30(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_15_u54_local_IRQHandler_31(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_16_u54_local_IRQHandler_32(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_17_u54_local_IRQHandler_33(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_18_u54_local_IRQHandler_34(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_19_u54_local_IRQHandler_35(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_20_u54_local_IRQHandler_36(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_21_u54_local_IRQHandler_37(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_22_u54_local_IRQHandler_38(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_23_u54_local_IRQHandler_39(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_24_u54_local_IRQHandler_40(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_25_u54_local_IRQHandler_41(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_26_u54_local_IRQHandler_42(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_27_u54_local_IRQHandler_43(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_28_u54_local_IRQHandler_44(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_29_u54_local_IRQHandler_45(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_30_u54_local_IRQHandler_46(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_31_u54_local_IRQHandler_47(void)
+{
+}
+#endif /* ifndef SIFIVE_HIFIVE_UNLEASHED */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_l2_cache.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_l2_cache.c
new file mode 100644
index 00000000..d51efed0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_l2_cache.c
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_l2_cache.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief The code in this file is executed before any code/data sections are
+ * copied. This code must not rely sdata/data section content. Hence, global
+ * variables should not be used unless they are constants.
+ *
+ */
+/*==============================================================================
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "mss_l2_cache.h"
+
+/*==============================================================================
+ * Local defines
+ */
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+static const uint64_t g_init_marker = INIT_MARKER;
+#endif
+
+/*==============================================================================
+ * Local functions.
+ */
+static void check_config_l2_scratchpad(void);
+
+
+/*==============================================================================
+ * This code should only be executed from E51 to be functional.
+ * Configure the L2 cache memory:
+ * - Set the number of cache ways used as cache based on the MSS Configurator
+ * settings.
+ * - Configure some of the enabled ways as scratchpad based on linker
+ * configuration and space allocated by configurator.
+ */
+__attribute__((weak)) void config_l2_cache(void)
+{
+ ASSERT(LIBERO_SETTING_WAY_ENABLE < 16U);
+
+ /*
+ * Set the number of ways that will be shared between cache and scratchpad.
+ */
+ CACHE_CTRL->WAY_ENABLE = LIBERO_SETTING_WAY_ENABLE;
+
+ /*
+ * shutdown L2 as directed
+ */
+ SYSREG->L2_SHUTDOWN_CR = LIBERO_SETTING_L2_SHUTDOWN_CR;
+
+ /* The scratchpad has already been set-up, first check enough space before copying */
+ check_config_l2_scratchpad();
+
+ /* If you are not using scratchpad, no need to include the following code */
+
+ ASSERT(LIBERO_SETTING_WAY_ENABLE >= LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS);
+
+
+
+ /*
+ * Compute the mask used to specify ways that will be used by the
+ * scratchpad.
+ */
+
+ uint32_t scratchpad_ways_mask = 0U;
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+ uint32_t inc;
+ uint32_t seed_ways_mask = 0x1U << LIBERO_SETTING_WAY_ENABLE;
+ for(inc = 0; inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++inc)
+ {
+ scratchpad_ways_mask |= (seed_ways_mask >> inc) ;
+ }
+#else
+ (void)scratchpad_ways_mask;
+#endif
+
+ /*
+ * Make sure ways are masked if being used as scratchpad
+ */
+ ASSERT((LIBERO_SETTING_WAY_MASK_DMA & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_E51_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_E51_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_1_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_2_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_3_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_4_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_1_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_2_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_3_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_4_ICACHE & scratchpad_ways_mask) == 0UL);
+
+ /*
+ * Setup all masters, apart from one we are using to setup scratch
+ */
+ CACHE_CTRL->WAY_MASK_DMA = LIBERO_SETTING_WAY_MASK_DMA;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_0;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_1;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_2;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_3;
+ CACHE_CTRL->WAY_MASK_E51_ICACHE = LIBERO_SETTING_WAY_MASK_E51_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_1_DCACHE = LIBERO_SETTING_WAY_MASK_U54_1_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_1_ICACHE = LIBERO_SETTING_WAY_MASK_U54_1_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_2_DCACHE = LIBERO_SETTING_WAY_MASK_U54_2_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_2_ICACHE = LIBERO_SETTING_WAY_MASK_U54_2_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_3_DCACHE = LIBERO_SETTING_WAY_MASK_U54_3_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_3_ICACHE = LIBERO_SETTING_WAY_MASK_U54_3_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_4_DCACHE = LIBERO_SETTING_WAY_MASK_U54_4_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_4_ICACHE = LIBERO_SETTING_WAY_MASK_U54_4_ICACHE;
+
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+ /*
+ * Assign ways to Zero Device
+ */
+ uint64_t * p_scratchpad = (uint64_t *)ZERO_DEVICE_BOTTOM;
+ uint32_t ways_inc;
+ uint64_t current_way = 0x1U << (((LIBERO_SETTING_WAY_ENABLE + 1U) - LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS) );
+ for(ways_inc = 0; ways_inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++ways_inc)
+ {
+ /*
+ * Populate the scratchpad memory one way at a time.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way;
+ mb();
+ /*
+ * Write to the first 64-bit location of each cache block.
+ */
+ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc)
+ {
+ *p_scratchpad = g_init_marker + inc;
+ p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH;
+ }
+ current_way = current_way << 1U;
+ mb();
+ }
+#endif /* (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0) */
+ /*
+ * Prevent E51 from evicting from scratchpad ways.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = LIBERO_SETTING_WAY_MASK_E51_DCACHE;
+ mb();
+
+}
+
+
+/*==============================================================================
+ * Configure the L2 scratchpad based on linker symbols:
+ * __l2_scratchpad_vma_start
+ * __l2_scratchpad_vma_end
+ *
+ * These linker symbols specify the start address and length of the scratchpad.
+ * The scratchpad must be located within the Zero Device memory range.
+ */
+static void check_config_l2_scratchpad(void)
+{
+ extern char __l2_scratchpad_vma_start;
+ extern char __l2_scratchpad_vma_end;
+
+ uint8_t n_scratchpad_ways;
+ const uint64_t end = (const uint64_t)&__l2_scratchpad_vma_end;
+ const uint64_t start = (const uint64_t)&__l2_scratchpad_vma_start;
+ uint64_t modulo;
+
+ ASSERT(start >= (uint64_t)ZERO_DEVICE_BOTTOM);
+ ASSERT(end < (uint64_t)ZERO_DEVICE_TOP);
+ ASSERT(end >= start);
+
+ /*
+ * Figure out how many cache ways will be required from linker script
+ * symbols.
+ */
+ n_scratchpad_ways = (uint8_t)((end - start) / WAY_BYTE_LENGTH);
+ modulo = (end - start) % WAY_BYTE_LENGTH;
+ if(modulo > 0)
+ {
+ ++n_scratchpad_ways;
+ }
+
+ ASSERT(LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS >= n_scratchpad_ways);
+}
+
+#if 0 // todo - remove, no longer used
+
+
+/*==============================================================================
+ * Reserve a number of cache ways to be used as scratchpad memory.
+ *
+ * @param nways
+ * Number of ways to be used as scratchpad. One way is 128Kbytes.
+ *
+ * @param scratchpad_start
+ * Start address within the Zero Device memory range in which the scratchpad
+ * will be located.
+ */
+static void reserve_scratchpad_ways(uint8_t nways, uint64_t * scratchpad_start)
+{
+ uint8_t way_enable;
+ uint64_t available_ways = 1;
+ uint64_t scratchpad_ways = 0;
+ uint64_t non_scratchpad_ways;
+ uint32_t inc;
+
+ ASSERT(scratchpad_start >= (uint64_t *)ZERO_DEVICE_BOTTOM);
+ ASSERT(scratchpad_start < (uint64_t *)ZERO_DEVICE_TOP);
+
+ /*
+ * Ensure at least one way remains available as cache.
+ */
+ way_enable = CACHE_CTRL->WAY_ENABLE;
+ ASSERT(nways <= way_enable);
+ if(nways <= way_enable)
+ {
+ /*
+ * Compute the mask used to specify ways that will be used by the
+ * scratchpad.
+ */
+
+ for(inc = 0; inc < way_enable; ++inc)
+ {
+ available_ways = (available_ways << 1) | (uint64_t)0x01;
+ if(inc < nways)
+ {
+ scratchpad_ways = (scratchpad_ways << 1) | (uint64_t)0x01;
+ }
+ }
+
+ /*
+ * Prevent other masters from evicting cache lines from scratchpad ways.
+ * Only allow E51 to evict from scratchpad ways.
+ */
+ non_scratchpad_ways = available_ways & ~scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_DMA = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_E51_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_1_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_1_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_2_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_2_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_3_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_3_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_4_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_4_ICACHE = non_scratchpad_ways;
+
+ /*
+ * Assign ways to Zero Device
+ */
+ uint64_t * p_scratchpad = scratchpad_start;
+ int ways_inc;
+ uint64_t current_way = 1;
+ for(ways_inc = 0; ways_inc < nways; ++ways_inc)
+ {
+ /*
+ * Populate the scratchpad memory one way at a time.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way;
+ /*
+ * Write to the first 64-bit location of each cache block.
+ */
+ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc)
+ {
+ *p_scratchpad = g_init_marker + inc;
+ p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH;
+ }
+ current_way = current_way << 1U;
+ mb();
+ }
+
+ /*
+ * Prevent E51 from evicting from scratchpad ways.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = non_scratchpad_ways;
+ }
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_l2_cache.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_l2_cache.h
new file mode 100644
index 00000000..16d618d6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_l2_cache.h
@@ -0,0 +1,532 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_l2_cache.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MACROs defines and prototypes associated with L2 Cache
+ *
+ */
+#ifndef MSS_L2_CACHE_H
+#define MSS_L2_CACHE_H
+
+#include
+#include "encoding.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following defines will be present in configurator generated xml Q1 2021
+ * In the interim, you can manually edit if required.
+ */
+#if !defined (LIBERO_SETTING_WAY_ENABLE)
+/*Way indexes less than or equal to this register value may be used by the
+cache. E.g. set to 0x7, will allocate 8 cache ways, 0-7 to cache, and leave
+8-15 as LIM. Note 1: Way 0 is always allocated as cache. Note 2: each way is
+128KB. */
+#define LIBERO_SETTING_WAY_ENABLE 0x00000007UL
+ /* WAY_ENABLE [0:8] RW value= 0x7 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_DMA)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_DMA 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_0)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_1)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_2)
+/*Way mask registerAXI slave port 2. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_3)
+/*Way mask register AXI slave port 3. Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_DCACHE)
+/*Way mask register E51 data cache (hart0). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_ICACHE)
+/*Way mask registerE52 instruction cache (hart0). Set field to zero to disable
+way from this master. The available cache ways are 0 to number set in
+WAY_ENABLE register. If using scratch pad memory, the ways you want reserved
+for scrathpad are not available for selection, you must set to 0. e.g. If three
+ways reserved for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set
+to zero for all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_DCACHE)
+/*Way mask register data cache (hart1). Set field to zero to disable way from
+this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_ICACHE)
+/*Way mask register instruction cache (hart1). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_DCACHE)
+/*Way mask register data cache (hart2). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_ICACHE)
+/*Way mask register instruction cache (hart2). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_DCACHE)
+/*Way mask register data cache (hart3). Set field to 1 to disable way from this
+master.Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_ICACHE)
+/*Way mask register instruction cache(hart3). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_DCACHE)
+/*Way mask register data cache (hart4). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_ICACHE)
+/*Way mask register instruction cache (hart4). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS)
+/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
+2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
+for scratchpad start at way 0, and work up. */
+#define LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS 0x00000000UL
+ /* NUM_OF_WAYS [0:8] RW value= 0x0 */
+#endif
+
+
+#if !defined (LIBERO_SETTING_L2_SHUTDOWN_CR)
+/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
+2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
+for scratchpad start at way 0, and work up. */
+#define LIBERO_SETTING_L2_SHUTDOWN_CR 0x00000000UL
+ /* NUM_OF_WAYS [0:8] RW value= 0x0 */
+#endif
+
+
+
+/*==============================================================================
+ * Define describing cache characteristics.
+ */
+#define MAX_WAY_ENABLE 15
+#define NB_SETS 512
+#define NB_BANKS 4
+#define CACHE_BLOCK_BYTE_LENGTH 64
+#define UINT64_BYTE_LENGTH 8
+#define WAY_BYTE_LENGTH (CACHE_BLOCK_BYTE_LENGTH * NB_SETS * NB_BANKS)
+
+#define ZERO_DEVICE_BOTTOM 0x0A000000ULL
+#define ZERO_DEVICE_TOP 0x0C000000ULL
+
+#define CACHE_CTRL_BASE 0x02010000ULL
+
+#define INIT_MARKER 0xC0FFEEBEC0010000ULL
+
+#define SHUTDOWN_CACHE_CC24_00_07_MASK 0x01
+#define SHUTDOWN_CACHE_CC24_08_15_MASK 0x02
+#define SHUTDOWN_CACHE_CC24_16_23_MASK 0x04
+#define SHUTDOWN_CACHE_CC24_24_31_MASK 0x08
+
+
+/*==============================================================================
+ * Cache controller registers definitions
+ */
+#define RO volatile const
+#define RW volatile
+#define WO volatile
+
+typedef struct {
+ RO uint8_t BANKS;
+ RO uint8_t WAYS;
+ RO uint8_t SETS;
+ RO uint8_t BYTES;
+} CACHE_CONFIG_typedef;
+
+typedef struct {
+ CACHE_CONFIG_typedef CONFIG;
+ RO uint32_t RESERVED;
+ RW uint8_t WAY_ENABLE;
+ RO uint8_t RESERVED0[55];
+
+ RW uint32_t ECC_INJECT_ERROR;
+ RO uint32_t RESERVED1[47];
+
+ RO uint64_t ECC_DIR_FIX_ADDR;
+ RO uint32_t ECC_DIR_FIX_COUNT;
+ RO uint32_t RESERVED2[13];
+
+ RO uint64_t ECC_DATA_FIX_ADDR;
+ RO uint32_t ECC_DATA_FIX_COUNT;
+ RO uint32_t RESERVED3[5];
+
+ RO uint64_t ECC_DATA_FAIL_ADDR;
+ RO uint32_t ECC_DATA_FAIL_COUNT;
+ RO uint32_t RESERVED4[37];
+
+ WO uint64_t FLUSH64;
+ RO uint64_t RESERVED5[7];
+
+ WO uint32_t FLUSH32;
+ RO uint32_t RESERVED6[367];
+
+ RW uint64_t WAY_MASK_DMA;
+
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_0;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_1;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_2;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_3;
+
+ RW uint64_t WAY_MASK_E51_DCACHE;
+ RW uint64_t WAY_MASK_E51_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_1_DCACHE;
+ RW uint64_t WAY_MASK_U54_1_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_2_DCACHE;
+ RW uint64_t WAY_MASK_U54_2_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_3_DCACHE;
+ RW uint64_t WAY_MASK_U54_3_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_4_DCACHE;
+ RW uint64_t WAY_MASK_U54_4_ICACHE;
+} CACHE_CTRL_typedef;
+
+#define CACHE_CTRL ((volatile CACHE_CTRL_typedef *) CACHE_CTRL_BASE)
+
+void config_l2_cache(void);
+uint8_t check_num_scratch_ways(uint64_t *start, uint64_t *end);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_L2_CACHE_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mpu.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mpu.c
new file mode 100644
index 00000000..1e5b55e7
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mpu.c
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_mpu.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS MPU driver for configuring access regions for the
+ * external masters.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+static uint64_t pmp_get_napot_base_and_range(uint64_t reg, uint64_t *range);
+
+uint8_t num_pmp_lut[10U] = {16U,16U,8U,4U,8U,8U,4U,4U,8U,2U};
+
+/**
+ * \brief MPU configuration from Libero for FIC0
+ *
+ */
+const uint64_t mpu_fic0_values[] = {
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP7,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP8,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP9,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP10,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP11,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP12,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP13,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP14,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP15
+};
+
+/**
+ * \brief MPU configuration from Libero for FIC1
+ *
+ */
+const uint64_t mpu_fic1_values[] = {
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP7,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP8,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP9,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP10,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP11,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP12,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP13,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP14,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP15
+};
+
+/**
+ * \brief MPU configuration from Libero for FIC2
+ *
+ */
+const uint64_t mpu_fic2_values[] = {
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for ATHENA
+ *
+ */
+const uint64_t mpu_crypto_values[] = {
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP0,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP1,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP2,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for GEM0
+ *
+ */
+const uint64_t mpu_gem0_values[] = {
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP0,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP1,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP2,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP3,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP4,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP5,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP6,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for GEM1
+ *
+ */
+const uint64_t mpu_gem1_values[] = {
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP0,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP1,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP2,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP3,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP4,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP5,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP6,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for MMC
+ *
+ */
+const uint64_t mpu_mmc_values[] = {
+ LIBERO_SETTING_MMC_MPU_CFG_PMP0,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP1,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP2,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for SCB
+ *
+ */
+const uint64_t mpu_scb_values[] = {
+ LIBERO_SETTING_SCB_MPU_CFG_PMP0,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP1,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP2,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP3,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP4,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP5,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP6,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for USB
+ *
+ */
+const uint64_t mpu_usb_values[] = {
+ LIBERO_SETTING_USB_MPU_CFG_PMP0,
+ LIBERO_SETTING_USB_MPU_CFG_PMP1,
+ LIBERO_SETTING_USB_MPU_CFG_PMP2,
+ LIBERO_SETTING_USB_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for TRACE
+ *
+ */
+const uint64_t mpu_trace_values[] = {
+ LIBERO_SETTING_TRACE_MPU_CFG_PMP0,
+ LIBERO_SETTING_TRACE_MPU_CFG_PMP1,
+};
+
+
+/***************************************************************************//**
+ * MSS_MPU_auto_configure()
+ * Set MPU's up with configuration from Libero
+ *
+ *
+ * @return
+ */
+uint8_t mpu_configure(void)
+{
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC0)->PMPCFG)),
+ &(mpu_fic0_values),
+ sizeof(mpu_fic0_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC1)->PMPCFG)),
+ &(mpu_fic1_values),
+ sizeof(mpu_fic1_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC2)->PMPCFG)),
+ &(mpu_fic2_values),
+ sizeof(mpu_fic2_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_CRYPTO)->PMPCFG)),
+ &(mpu_crypto_values),
+ sizeof(mpu_crypto_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_GEM0)->PMPCFG)),
+ &(mpu_gem0_values),
+ sizeof(mpu_gem0_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_GEM1)->PMPCFG)),
+ &(mpu_gem1_values),
+ sizeof(mpu_gem1_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_USB)->PMPCFG)),
+ &(mpu_usb_values),
+ sizeof(mpu_usb_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_MMC)->PMPCFG)),
+ &(mpu_mmc_values),
+ sizeof(mpu_mmc_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_SCB)->PMPCFG)),
+ &(mpu_scb_values),
+ sizeof(mpu_scb_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_TRACE)->PMPCFG)),
+ &(mpu_trace_values),
+ sizeof(mpu_trace_values));
+
+ return(0);
+}
+
+
+
+
+
+/***************************************************************************//**
+*/
+uint8_t MSS_MPU_configure(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t base,
+ uint64_t size,
+ uint8_t permission,
+ mss_mpu_addrm_t matching_mode,
+ uint8_t lock_en)
+{
+ uint64_t temp = size, cnt=0ULL;
+ uint64_t range;
+
+ /*size must be minimum 4k
+ Size must be power of 2
+ different masters have different number of regions*/
+ if((size >= 4096ULL) && (0U == (size & (size - 1U))) && (pmp_region < num_pmp_lut[master_port]))
+ {
+ while((0 == (temp & 0x01U)))
+ {
+ cnt++;
+ temp >>= 1U;
+ }
+
+ range = (1ULL << (cnt-1U))-1U;
+
+ MSS_MPU(master_port)->PMPCFG[pmp_region].raw = (base | range) >> 2U;
+
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode = (uint8_t)(permission |
+ (uint8_t)(matching_mode << 3U) |
+ (lock_en << 0x7U));
+
+ return ((uint8_t)0);
+ }
+ else
+ {
+ return ((uint8_t)1);
+ }
+}
+
+uint8_t MSS_MPU_get_config(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t* base,
+ uint64_t* size,
+ uint8_t* permission,
+ mss_mpu_addrm_t* matching_mode,
+ uint8_t* lock_en)
+{
+ uint64_t reg;
+
+ /*All AXI external masters dont have same number of PMP regions*/
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ reg = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.pmp;
+ *base = pmp_get_napot_base_and_range(reg, size);
+
+ reg = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode;
+ *lock_en = ( reg >> 0x7U) & 0x1U;
+ *matching_mode = (mss_mpu_addrm_t)( (reg >> 3ULL) & 0x3U);
+ *permission = reg & 0x7U;
+
+ return ((uint8_t)0);
+ }
+ else
+ {
+ return ((uint8_t)1);
+ }
+}
+
+static uint64_t pmp_get_napot_base_and_range(uint64_t reg, uint64_t *range)
+{
+ /* construct a mask of all bits bar the top bit */
+ uint64_t mask = 0U;
+ uint64_t base = reg;
+ uint64_t numbits = (sizeof(uint64_t) * 8U) + 2U;
+ mask = (mask - 1U) >> 1U;
+
+ while (mask)
+ {
+ if ((reg & mask) == mask)
+ {
+ /* this is the mask to use */
+ base = reg & ~mask;
+ break;
+ }
+ mask >>= 1U;
+ numbits--;
+ }
+
+ *range = (1LU << numbits);
+ return (base << 2U);
+}
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mpu.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mpu.h
new file mode 100644
index 00000000..6b4e1abb
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mpu.h
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_mpu.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS MPU driver APIs for configuring access regions for
+ * the external masters.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_MPU_H
+#define MSS_MPU_H
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+/***************************************************************************//**
+
+ */
+#define MPU_MODE_READ_ACCESS (1U << 0U)
+#define MPU_MODE_WRITE_ACCESS (1U << 1U)
+#define MPU_MODE_EXEC_ACCESS (1U << 2U)
+
+typedef enum {
+ MSS_MPU_FIC0 = 0x00,
+ MSS_MPU_FIC1,
+ MSS_MPU_FIC2,
+ MSS_MPU_CRYPTO,
+ MSS_MPU_GEM0,
+ MSS_MPU_GEM1,
+ MSS_MPU_USB,
+ MSS_MPU_MMC,
+ MSS_MPU_SCB,
+ MSS_MPU_TRACE,
+ MSS_MPU_SEG0,
+ MSS_MPU_SEG1,
+} mss_mpu_mport_t;
+
+typedef enum {
+ MSS_MPU_AM_OFF = 0x00U,
+ MSS_MPU_AM_NAPOT = 0x03U,
+} mss_mpu_addrm_t;
+
+typedef enum {
+ MSS_MPU_PMP_REGION0 = 0x00,
+ MSS_MPU_PMP_REGION1,
+ MSS_MPU_PMP_REGION2,
+ MSS_MPU_PMP_REGION3,
+ MSS_MPU_PMP_REGION4,
+ MSS_MPU_PMP_REGION5,
+ MSS_MPU_PMP_REGION6,
+ MSS_MPU_PMP_REGION7,
+ MSS_MPU_PMP_REGION8,
+ MSS_MPU_PMP_REGION9,
+ MSS_MPU_PMP_REGION10,
+ MSS_MPU_PMP_REGION11,
+ MSS_MPU_PMP_REGION12,
+ MSS_MPU_PMP_REGION13,
+ MSS_MPU_PMP_REGION14,
+ MSS_MPU_PMP_REGION15,
+} mss_mpu_pmp_region_t;
+
+extern uint8_t num_pmp_lut[10];
+
+#ifndef __I
+#define __I const volatile
+#endif
+#ifndef __IO
+#define __IO volatile
+#endif
+#ifndef __O
+#define __O volatile
+#endif
+
+
+typedef struct {
+ union {
+ struct
+ {
+ __IO uint64_t pmp : 38;
+ __IO uint64_t rsrvd : 18;
+ __IO uint64_t mode : 8;
+ } MPUCFG_TypeDef;
+ uint64_t raw;
+ };
+} MPU_CFG;
+
+typedef struct
+{
+ __IO uint64_t addr : 38;
+ __IO uint64_t rw : 1;
+ __IO uint64_t id : 4;
+ __IO uint64_t failed : 1;
+ __IO uint64_t padding : (64-44);
+} MPU_FailStatus_TypeDef;
+
+typedef struct
+{
+ MPU_CFG PMPCFG[16U];
+ __IO MPU_FailStatus_TypeDef STATUS;
+} MPU_TypeDef;
+
+
+
+#define MSS_MPU(master) ( (MPU_TypeDef*) (0x20005000UL + ((master) << 8U)))
+
+
+uint8_t mpu_configure(void);
+
+
+uint8_t MSS_MPU_configure(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t base,
+ uint64_t size,
+ uint8_t permission,
+ mss_mpu_addrm_t matching_mode,
+ uint8_t lock_en);
+
+uint8_t MSS_MPU_get_config(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t* base,
+ uint64_t* size,
+ uint8_t* permission,
+ mss_mpu_addrm_t* matching_mode,
+ uint8_t* lock_en);
+
+static inline uint8_t MSS_MPU_lock_region(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= (0x1U << 7U);
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+/*permission value could be bitwise or of:
+ * MPU_MODE_READ_ACCESS
+ * MPU_MODE_WRITE_ACCESS
+ * MPU_MODE_EXEC_ACCESS
+ *
+ * */
+static inline uint8_t MSS_MPU_set_permission(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint8_t permission)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= permission;
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+static inline uint8_t MSS_MPU_get_permission(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint8_t* permission)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ *permission = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode & 0x7U;
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+/*read the Fail status register when there is a MPU access failure.
+ See the return type MPU_FailStatus_TypeDef for the details of the STATUS bitfield.
+ The status failed bit(offset 42) needs to be reset using the corresponding bit
+ in SYSREG->mpu_violation_sr
+ */
+static inline MPU_FailStatus_TypeDef MSS_MPU_get_failstatus(mss_mpu_mport_t master_port)
+{
+ return (MSS_MPU(master_port)->STATUS);
+}
+
+#endif /* ! SIFIVE_HIFIVE_UNLEASHED */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_MPU_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mtrap.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mtrap.c
new file mode 100644
index 00000000..2226d7bf
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mtrap.c
@@ -0,0 +1,783 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ *
+ * @file mss_mtrap.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief trap functions
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+void handle_local_interrupt(uint8_t interrupt_no);
+void handle_m_soft_interrupt(void);
+void handle_m_timer_interrupt(void);
+void illegal_insn_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void misaligned_store_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void misaligned_load_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void pmp_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void trap_from_machine_mode(uintptr_t * regs, uintptr_t dummy, uintptr_t mepc);
+void bad_trap(uintptr_t* regs, uintptr_t dummy, uintptr_t mepc);
+
+
+void bad_trap(uintptr_t* regs, uintptr_t dummy, uintptr_t mepc)
+{
+ (void)regs;
+ (void)dummy;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void misaligned_store_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void misaligned_load_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void illegal_insn_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void pmp_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for external interrupts.
+ */
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+uint8_t (*ext_irq_handler_table[PLIC_NUM_SOURCES])(void) =
+{
+ Invalid_IRQHandler,
+ l2_metadata_corr_IRQHandler,
+ l2_metadata_uncorr_IRQHandler,
+ l2_data_corr_IRQHandler,
+ l2_data_uncorr_IRQHandler,
+ dma_ch0_DONE_IRQHandler,
+ dma_ch0_ERR_IRQHandler,
+ dma_ch1_DONE_IRQHandler,
+ dma_ch1_ERR_IRQHandler,
+ dma_ch2_DONE_IRQHandler,
+ dma_ch2_ERR_IRQHandler,
+ dma_ch3_DONE_IRQHandler,
+ dma_ch3_ERR_IRQHandler,
+ gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler,
+ gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler,
+ gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler,
+ gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler,
+ gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler,
+ gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler,
+ gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler,
+ gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler,
+ gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler,
+ gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler,
+ gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler,
+ gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler,
+ gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler,
+
+ gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler,
+ gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler,
+ gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler,
+ gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler,
+ gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler,
+ gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler,
+ gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler,
+ gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler,
+ gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler,
+ gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler,
+ gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler,
+ gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler,
+ gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler,
+ gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler,
+ gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler,
+
+ gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler,
+ gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler,
+ gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler,
+ gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler,
+
+ gpio1_bit18_plic_32_IRQHandler,
+ gpio1_bit19_plic_33_IRQHandler,
+ gpio1_bit20_plic_34_IRQHandler,
+ gpio1_bit21_plic_35_IRQHandler,
+ gpio1_bit22_plic_36_IRQHandler,
+ gpio1_bit23_plic_37_IRQHandler,
+
+ gpio0_non_direct_plic_IRQHandler,
+ gpio1_non_direct_plic_IRQHandler,
+ gpio2_non_direct_plic_IRQHandler,
+
+ spi0_plic_IRQHandler,
+ spi1_plic_IRQHandler,
+ external_can0_plic_IRQHandler,
+ can1_IRQHandler,
+ External_i2c0_main_plic_IRQHandler,
+ External_i2c0_alert_plic_IRQHandler,
+ i2c0_sus_plic_IRQHandler,
+ i2c1_main_plic_IRQHandler,
+ i2c1_alert_plic_IRQHandler,
+ i2c1_sus_plic_IRQHandler,
+ mac0_int_plic_IRQHandler,
+ mac0_queue1_plic_IRQHandler,
+ mac0_queue2_plic_IRQHandler,
+ mac0_queue3_plic_IRQHandler,
+ mac0_emac_plic_IRQHandler,
+ mac0_mmsl_plic_IRQHandler,
+ mac1_int_plic_IRQHandler,
+ mac1_queue1_plic_IRQHandler,
+ mac1_queue2_plic_IRQHandler,
+ mac1_queue3_plic_IRQHandler,
+ mac1_emac_plic_IRQHandler,
+ mac1_mmsl_plic_IRQHandler,
+ ddrc_train_plic_IRQHandler,
+ scb_interrupt_plic_IRQHandler,
+ ecc_error_plic_IRQHandler,
+ ecc_correct_plic_IRQHandler,
+ rtc_wakeup_plic_IRQHandler,
+ rtc_match_plic_IRQHandler,
+ timer1_plic_IRQHandler,
+ timer2_plic_IRQHandler,
+ envm_plic_IRQHandler,
+ qspi_plic_IRQHandler,
+ usb_dma_plic_IRQHandler,
+ usb_mc_plic_IRQHandler,
+ mmc_main_plic_IRQHandler,
+ mmc_wakeup_plic_IRQHandler,
+ mmuart0_plic_77_IRQHandler,
+ mmuart1_plic_IRQHandler,
+ mmuart2_plic_IRQHandler,
+ mmuart3_plic_IRQHandler,
+ mmuart4_plic_IRQHandler,
+
+ g5c_devrst_plic_IRQHandler,
+ g5c_message_plic_IRQHandler,
+ usoc_vc_interrupt_plic_IRQHandler,
+ usoc_smb_interrupt_plic_IRQHandler,
+ e51_0_Maintence_plic_IRQHandler,
+
+ wdog0_mvrp_plic_IRQHandler,
+ wdog1_mvrp_plic_IRQHandler, /*100 contains multiple interrupts- */
+ wdog2_mvrp_plic_IRQHandler,
+ wdog3_mvrp_plic_IRQHandler,
+ wdog4_mvrp_plic_IRQHandler,
+ wdog0_tout_plic_IRQHandler,
+ wdog1_tout_plic_IRQHandler,
+ wdog2_tout_plic_IRQHandler,
+ wdog3_tout_plic_IRQHandler,
+ wdog4_tout_plic_IRQHandler,
+
+ g5c_mss_spi_plic_IRQHandler,
+ volt_temp_alarm_plic_IRQHandler,
+ athena_complete_plic_IRQHandler,
+ athena_alarm_plic_IRQHandler,
+ athena_bus_error_plic_IRQHandler,
+ usoc_axic_us_plic_IRQHandler,
+ usoc_axic_ds_plic_IRQHandler,
+
+ reserved_104_plic_IRQHandler,
+
+ fabric_f2h_0_plic_IRQHandler,
+ fabric_f2h_1_plic_IRQHandler,
+ fabric_f2h_2_plic_IRQHandler,
+ fabric_f2h_3_plic_IRQHandler,
+ fabric_f2h_4_plic_IRQHandler,
+ fabric_f2h_5_plic_IRQHandler,
+ fabric_f2h_6_plic_IRQHandler,
+ fabric_f2h_7_plic_IRQHandler,
+ fabric_f2h_8_plic_IRQHandler,
+ fabric_f2h_9_plic_IRQHandler,
+
+ fabric_f2h_10_plic_IRQHandler,
+ fabric_f2h_11_plic_IRQHandler,
+ fabric_f2h_12_plic_IRQHandler,
+ fabric_f2h_13_plic_IRQHandler,
+ fabric_f2h_14_plic_IRQHandler,
+ fabric_f2h_15_plic_IRQHandler,
+ fabric_f2h_16_plic_IRQHandler,
+ fabric_f2h_17_plic_IRQHandler,
+ fabric_f2h_18_plic_IRQHandler,
+ fabric_f2h_19_plic_IRQHandler,
+
+ fabric_f2h_20_plic_IRQHandler,
+ fabric_f2h_21_plic_IRQHandler,
+ fabric_f2h_22_plic_IRQHandler,
+ fabric_f2h_23_plic_IRQHandler,
+ fabric_f2h_24_plic_IRQHandler,
+ fabric_f2h_25_plic_IRQHandler,
+ fabric_f2h_26_plic_IRQHandler,
+ fabric_f2h_27_plic_IRQHandler,
+ fabric_f2h_28_plic_IRQHandler,
+ fabric_f2h_29_plic_IRQHandler,
+
+ fabric_f2h_30_plic_IRQHandler,
+ fabric_f2h_31_plic_IRQHandler,
+
+ fabric_f2h_32_plic_IRQHandler,
+ fabric_f2h_33_plic_IRQHandler,
+ fabric_f2h_34_plic_IRQHandler,
+ fabric_f2h_35_plic_IRQHandler,
+ fabric_f2h_36_plic_IRQHandler,
+ fabric_f2h_37_plic_IRQHandler,
+ fabric_f2h_38_plic_IRQHandler,
+ fabric_f2h_39_plic_IRQHandler,
+ fabric_f2h_40_plic_IRQHandler,
+ fabric_f2h_41_plic_IRQHandler,
+
+ fabric_f2h_42_plic_IRQHandler,
+ fabric_f2h_43_plic_IRQHandler,
+ fabric_f2h_44_plic_IRQHandler,
+ fabric_f2h_45_plic_IRQHandler,
+ fabric_f2h_46_plic_IRQHandler,
+ fabric_f2h_47_plic_IRQHandler,
+ fabric_f2h_48_plic_IRQHandler,
+ fabric_f2h_49_plic_IRQHandler,
+ fabric_f2h_50_plic_IRQHandler,
+ fabric_f2h_51_plic_IRQHandler,
+
+ fabric_f2h_52_plic_IRQHandler,
+ fabric_f2h_53_plic_IRQHandler,
+ fabric_f2h_54_plic_IRQHandler,
+ fabric_f2h_55_plic_IRQHandler,
+ fabric_f2h_56_plic_IRQHandler,
+ fabric_f2h_57_plic_IRQHandler,
+ fabric_f2h_58_plic_IRQHandler,
+ fabric_f2h_59_plic_IRQHandler,
+ fabric_f2h_60_plic_IRQHandler,
+ fabric_f2h_61_plic_IRQHandler,
+
+ fabric_f2h_62_plic_IRQHandler,
+ fabric_f2h_63_plic_IRQHandler,
+
+ bus_error_unit_hart_0_plic_IRQHandler,
+ bus_error_unit_hart_1_plic_IRQHandler,
+ bus_error_unit_hart_2_plic_IRQHandler,
+ bus_error_unit_hart_3_plic_IRQHandler,
+ bus_error_unit_hart_4_plic_IRQHandler
+};
+
+#define E51_LOCAL_NUM_SOURCES 48U
+
+
+void (*local_irq_handler_e51_table[E51_LOCAL_NUM_SOURCES])(void) =
+{
+ maintenance_e51_local_IRQHandler_0, /* reference multiple interrupts */
+ usoc_smb_interrupt_e51_local_IRQHandler_1,
+ usoc_vc_interrupt_e51_local_IRQHandler_2,
+ g5c_message_e51_local_IRQHandler_3,
+ g5c_devrst_e51_local_IRQHandler_4,
+ wdog4_tout_e51_local_IRQHandler_5,
+ wdog3_tout_e51_local_IRQHandler_6,
+ wdog2_tout_e51_local_IRQHandler_7,
+ wdog1_tout_e51_local_IRQHandler_8,
+ wdog0_tout_e51_local_IRQHandler_9,
+ wdog0_mvrp_e51_local_IRQHandler_10,
+ mmuart0_e51_local_IRQHandler_11,
+ envm_e51_local_IRQHandler_12,
+ ecc_correct_e51_local_IRQHandler_13,
+ ecc_error_e51_local_IRQHandler_14,
+ scb_interrupt_e51_local_IRQHandler_15,
+ fabric_f2h_32_e51_local_IRQHandler_16,
+ fabric_f2h_33_e51_local_IRQHandler_17,
+ fabric_f2h_34_e51_local_IRQHandler_18,
+ fabric_f2h_35_e51_local_IRQHandler_19,
+ fabric_f2h_36_e51_local_IRQHandler_20,
+ fabric_f2h_37_e51_local_IRQHandler_21,
+ fabric_f2h_38_e51_local_IRQHandler_22,
+ fabric_f2h_39_e51_local_IRQHandler_23,
+ fabric_f2h_40_e51_local_IRQHandler_24,
+ fabric_f2h_41_e51_local_IRQHandler_25,
+
+ fabric_f2h_42_e51_local_IRQHandler_26,
+ fabric_f2h_43_e51_local_IRQHandler_27,
+ fabric_f2h_44_e51_local_IRQHandler_28,
+ fabric_f2h_45_e51_local_IRQHandler_29,
+ fabric_f2h_46_e51_local_IRQHandler_30,
+ fabric_f2h_47_e51_local_IRQHandler_31,
+ fabric_f2h_48_e51_local_IRQHandler_32,
+ fabric_f2h_49_e51_local_IRQHandler_33,
+ fabric_f2h_50_e51_local_IRQHandler_34,
+ fabric_f2h_51_e51_local_IRQHandler_35,
+
+ fabric_f2h_52_e51_local_IRQHandler_36,
+ fabric_f2h_53_e51_local_IRQHandler_37,
+ fabric_f2h_54_e51_local_IRQHandler_38,
+ fabric_f2h_55_e51_local_IRQHandler_39,
+ fabric_f2h_56_e51_local_IRQHandler_40,
+ fabric_f2h_57_e51_local_IRQHandler_41,
+ fabric_f2h_58_e51_local_IRQHandler_42,
+ fabric_f2h_59_e51_local_IRQHandler_43,
+ fabric_f2h_60_e51_local_IRQHandler_44,
+ fabric_f2h_61_e51_local_IRQHandler_45,
+
+ fabric_f2h_62_e51_local_IRQHandler_46,
+ fabric_f2h_63_e51_local_IRQHandler_47
+};
+
+
+typedef void (*local_int_p_t)(void);
+
+/* U54 1 */
+local_int_p_t local_irq_handler_u54_1_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_1_local_IRQHandler_3,
+ mac_emac_u54_1_local_IRQHandler_4,
+ mac_queue3_u54_1_local_IRQHandler_5,
+ mac_queue2_u54_1_local_IRQHandler_6,
+ mac_queue1_u54_1_local_IRQHandler_7,
+ mac_int_u54_1_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h1_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h1_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 2 */
+local_int_p_t local_irq_handler_u54_2_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_2_local_IRQHandler_3,
+ mac_emac_u54_2_local_IRQHandler_4,
+ mac_queue3_u54_2_local_IRQHandler_5,
+ mac_queue2_u54_2_local_IRQHandler_6,
+ mac_queue1_u54_2_local_IRQHandler_7,
+ mac_int_u54_2_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h2_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h2_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 3 */
+local_int_p_t local_irq_handler_u54_3_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_3_local_IRQHandler_3,
+ mac_emac_u54_3_local_IRQHandler_4,
+ mac_queue3_u54_3_local_IRQHandler_5,
+ mac_queue2_u54_3_local_IRQHandler_6,
+ mac_queue1_u54_3_local_IRQHandler_7,
+ mac_int_u54_3_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h3_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h3_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 4 */
+local_int_p_t local_irq_handler_u54_4_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_4_local_IRQHandler_3,
+ mac_emac_u54_4_local_IRQHandler_4,
+ mac_queue3_u54_4_local_IRQHandler_5,
+ mac_queue2_u54_4_local_IRQHandler_6,
+ mac_queue1_u54_4_local_IRQHandler_7,
+ mac_int_u54_4_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h4_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h4_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+local_int_p_t *local_int_mux[5] =
+{
+ local_irq_handler_e51_table,
+ local_irq_handler_u54_1_table,
+ local_irq_handler_u54_2_table,
+ local_irq_handler_u54_3_table,
+ local_irq_handler_u54_4_table
+};
+
+#else
+uint8_t (*ext_irq_handler_table[PLIC_NUM_SOURCES])(void) =
+{
+ Invalid_IRQHandler,
+ External_1_IRQHandler,
+ External_2_IRQHandler,
+ External_3_IRQHandler,
+ USART0_plic_4_IRQHandler,
+ External_5_IRQHandler,
+ External_6_IRQHandler,
+ External_7_IRQHandler,
+ External_8_IRQHandler,
+ External_9_IRQHandler,
+ External_10_IRQHandler,
+ External_11_IRQHandler,
+ External_12_IRQHandler,
+ External_13_IRQHandler,
+ External_14_IRQHandler,
+ External_15_IRQHandler,
+ External_16_IRQHandler,
+ External_17_IRQHandler,
+ External_18_IRQHandler,
+ External_19_IRQHandler,
+ External_20_IRQHandler,
+ External_21_IRQHandler,
+ External_22_IRQHandler,
+ dma_ch0_DONE_IRQHandler,
+ dma_ch0_ERR_IRQHandler,
+ dma_ch1_DONE_IRQHandler,
+ dma_ch1_ERR_IRQHandler,
+ dma_ch2_DONE_IRQHandler,
+ dma_ch2_ERR_IRQHandler,
+ dma_ch3_DONE_IRQHandler,
+ dma_ch3_ERR_IRQHandler,
+ External_31_IRQHandler,
+ External_32_IRQHandler,
+ External_33_IRQHandler,
+ External_34_IRQHandler,
+ External_35_IRQHandler,
+ External_36_IRQHandler,
+ External_37_IRQHandler,
+ External_38_IRQHandler,
+ External_39_IRQHandler,
+ External_40_IRQHandler,
+ External_41_IRQHandler,
+ External_42_IRQHandler,
+ External_43_IRQHandler,
+ External_44_IRQHandler,
+ External_45_IRQHandler,
+ External_46_IRQHandler,
+ External_47_IRQHandler,
+ External_48_IRQHandler,
+ External_49_IRQHandler,
+ External_50_IRQHandler,
+ External_51_IRQHandler,
+ External_52_IRQHandler,
+ MAC0_plic_53_IRQHandler
+
+};
+#endif
+/*------------------------------------------------------------------------------
+ *
+ */
+void handle_m_ext_interrupt(void)
+{
+
+ volatile uint32_t int_num = PLIC_ClaimIRQ();
+
+ if (INVALID_IRQn == int_num)
+ {
+ return;
+ }
+
+ uint8_t disable = EXT_IRQ_KEEP_ENABLED;
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ disable = ext_irq_handler_table[int_num /* + OFFSET_TO_MSS_GLOBAL_INTS Think this was required in early bitfile */]();
+#else
+ disable = ext_irq_handler_table[int_num]();
+#endif
+
+ PLIC_CompleteIRQ(int_num);
+
+ if(EXT_IRQ_DISABLE == disable)
+ {
+ PLIC_DisableIRQ((PLIC_IRQn_Type)int_num);
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void handle_local_interrupt(uint8_t interrupt_no)
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED /* no local interrupts on unleashed */
+ uint64_t mhart_id = read_csr(mhartid);
+ uint8_t local_interrupt_no = (uint8_t)(interrupt_no - 16U);
+ local_int_p_t *local_int_table = local_int_mux[mhart_id];
+
+ (*local_int_table[local_interrupt_no])();
+
+#endif
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void trap_from_machine_mode(uintptr_t * regs, uintptr_t dummy, uintptr_t mepc)
+{
+ volatile uintptr_t mcause = read_csr(mcause);
+
+ if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) > 15U)&& ((mcause & MCAUSE_CAUSE) < 64U))
+ {
+ handle_local_interrupt((uint8_t)(mcause & MCAUSE_CAUSE));
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT))
+ {
+ handle_m_ext_interrupt();
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_SOFT))
+ {
+ handle_m_soft_interrupt();
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER))
+ {
+ handle_m_timer_interrupt();
+ }
+ else
+ {
+ uint32_t i = 0U;
+ while(1)
+ {
+ /* wait for watchdog */
+ i++; /* added some code as SC debugger hangs if in loop doing nothing */
+ if(i == 0x1000U)
+ {
+ i = mcause; /* so mcause is not optimised out */
+ }
+ }
+ switch(mcause)
+ {
+
+ case CAUSE_LOAD_PAGE_FAULT:
+ break;
+ case CAUSE_STORE_PAGE_FAULT:
+ break;
+ case CAUSE_FETCH_ACCESS:
+ break;
+ case CAUSE_LOAD_ACCESS:
+ break;
+ case CAUSE_STORE_ACCESS:
+ break;
+ default:
+ bad_trap(regs, dummy, mepc);
+ break;
+ }
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mtrap.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mtrap.h
new file mode 100644
index 00000000..3d68eb12
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_mtrap.h
@@ -0,0 +1,92 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+#ifndef RISCV_MTRAP_H
+#define RISCV_MTRAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ASSEMBLER__
+#define read_const_csr(reg) ({ unsigned long __tmp; \
+ asm ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+#endif
+
+#define IPI_SOFT 0x01
+#define IPI_FENCE_I 0x02
+#define IPI_SFENCE_VMA 0x04
+
+#define MACHINE_STACK_SIZE (RISCV_PGSIZE) /* this is 4k for HLS and 4k for the stack*/
+#define MENTRY_HLS_OFFSET (INTEGER_CONTEXT_SIZE + SOFT_FLOAT_CONTEXT_SIZE)
+#define MENTRY_FRAME_SIZE (MENTRY_HLS_OFFSET + HLS_SIZE)
+#define MENTRY_IPI_OFFSET (MENTRY_HLS_OFFSET)
+#define MENTRY_IPI_PENDING_OFFSET (MENTRY_HLS_OFFSET + REGBYTES)
+
+#ifdef __riscv_flen
+# define SOFT_FLOAT_CONTEXT_SIZE (0)
+#else
+# define SOFT_FLOAT_CONTEXT_SIZE (8 * 32)
+#endif
+
+#define HLS_SIZE (64)
+#define INTEGER_CONTEXT_SIZE (32 * REGBYTES)
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ volatile uint32_t * ipi;
+ volatile int mipi_pending;
+ volatile int padding;
+ volatile uint64_t * timecmp;
+ volatile uint32_t * plic_m_thresh;
+ volatile uintptr_t * plic_m_ie;
+ volatile uint32_t * plic_s_thresh;
+ volatile uintptr_t * plic_s_ie;
+} hls_t;
+
+/* This code relies on the stack being allocated on a 4K boundary */
+/* also can not be bigger than 4k */
+#define MACHINE_STACK_TOP() ({ \
+ register uintptr_t sp asm ("sp"); \
+ (void *)((sp + RISCV_PGSIZE) & -RISCV_PGSIZE); })
+
+// hart-local storage
+#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
+#define OTHER_HLS(id) ((hls_t*)((void *)HLS() + RISCV_PGSIZE * ((id) - read_const_csr(mhartid))))
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*RISCV_MTRAP_H*/
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_peripherals.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_peripherals.c
new file mode 100644
index 00000000..307cd0ee
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_peripherals.c
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_peripherals.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS functions related to peripherals.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+const uint32_t LIBERO_SETTING_CONTEXT_EN[][2U] = {
+ {LIBERO_SETTING_CONTEXT_A_EN,
+ LIBERO_SETTING_CONTEXT_B_EN},
+ {LIBERO_SETTING_CONTEXT_A_EN_FIC,
+ LIBERO_SETTING_CONTEXT_B_EN_FIC},
+};
+
+/* offsets used in PERIPHERAL_SETUP array */
+#define PERIPHERAL_INDEX_OFFSET 0U /* used for sanity check */
+#define CONTEXT_EN_INDEX_OFFSET 1U
+#define CONTEXT_MASK_INDEX_OFFSET 2U
+#define CONTEXT_SUBCLK_INDEX_OFFSET 3U
+
+const uint32_t PERIPHERAL_SETUP[][4U] = {
+ {MSS_PERIPH_MMUART0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART0,SUBBLK_CLOCK_CR_MMUART0_MASK},
+ {MSS_PERIPH_MMUART1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART1,SUBBLK_CLOCK_CR_MMUART1_MASK},
+ {MSS_PERIPH_MMUART2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART2,SUBBLK_CLOCK_CR_MMUART2_MASK},
+ {MSS_PERIPH_MMUART3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART3,SUBBLK_CLOCK_CR_MMUART3_MASK},
+ {MSS_PERIPH_MMUART4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART4,SUBBLK_CLOCK_CR_MMUART4_MASK},
+ {MSS_PERIPH_WDOG0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG0,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG1,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG2,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG3,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG4,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_SPI0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI0,SUBBLK_CLOCK_CR_SPI0_MASK},
+ {MSS_PERIPH_SPI1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI1,SUBBLK_CLOCK_CR_SPI1_MASK},
+ {MSS_PERIPH_I2C0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C0,SUBBLK_CLOCK_CR_I2C0_MASK},
+ {MSS_PERIPH_I2C1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C1,SUBBLK_CLOCK_CR_I2C1_MASK},
+ {MSS_PERIPH_CAN0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN0,SUBBLK_CLOCK_CR_CAN0_MASK},
+ {MSS_PERIPH_CAN1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN1,SUBBLK_CLOCK_CR_CAN1_MASK},
+ {MSS_PERIPH_MAC0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC0,SUBBLK_CLOCK_CR_MAC0_MASK},
+ {MSS_PERIPH_MAC1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC1,SUBBLK_CLOCK_CR_MAC1_MASK},
+ {MSS_PERIPH_TIMER,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_TIMER,SUBBLK_CLOCK_CR_TIMER_MASK},
+ {MSS_PERIPH_GPIO0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO0,SUBBLK_CLOCK_CR_GPIO0_MASK},
+ {MSS_PERIPH_GPIO1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO1,SUBBLK_CLOCK_CR_GPIO1_MASK},
+ {MSS_PERIPH_GPIO2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO2,SUBBLK_CLOCK_CR_GPIO2_MASK},
+ {MSS_PERIPH_RTC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_RTC,SUBBLK_CLOCK_CR_RTC_MASK},
+ {MSS_PERIPH_H2FINT,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_H2FINT, SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_CRYPTO,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CRYPTO,SUBBLK_CLOCK_CR_ATHENA_MASK},
+ {MSS_PERIPH_USB,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_USB,SUBBLK_CLOCK_CR_USB_MASK},
+ {MSS_PERIPH_QSPIXIP,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_QSPIXIP,SUBBLK_CLOCK_CR_QSPI_MASK},
+ {MSS_PERIPH_ATHENA,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_ATHENA,SUBBLK_CLOCK_CR_ATHENA_MASK},
+ {MSS_PERIPH_TRACE,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_MAILBOX_SC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_EMMC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_CFM,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CFM,SUBBLK_CLOCK_CR_CFM_MASK},
+ {MSS_PERIPH_FIC0,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC0,SUBBLK_CLOCK_CR_FIC0_MASK},
+ {MSS_PERIPH_FIC1,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC1,SUBBLK_CLOCK_CR_FIC1_MASK},
+ {MSS_PERIPH_FIC2,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC2,SUBBLK_CLOCK_CR_FIC2_MASK},
+ {MSS_PERIPH_FIC3,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC3,SUBBLK_CLOCK_CR_FIC3_MASK}
+};
+
+/**
+ * If contexts set-up, verify allowed access to peripheral
+ * @param option - Two option, , FIC enables set separately. CONTEXT_EN_INDEX_FIC or CONTEXT_EN_INDEX
+ * @param periph_context_mask See CONTEXT_EN_MASK_ defines for options
+ * @param hart The hart ID of origin of request.
+ * @return
+ */
+static inline uint8_t verify_context_enable(uint8_t option, uint32_t periph_context_mask , uint32_t hart)
+{
+ uint8_t result = 1U;
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ if (hart != (uint8_t) 0U)
+ {
+ if (LIBERO_SETTING_CONTEXT_A_HART_EN & hart )
+ {
+ if (LIBERO_SETTING_CONTEXT_EN[option][0U] & periph_context_mask)
+ {
+ result = 0U;
+ }
+ }
+
+ if (LIBERO_SETTING_CONTEXT_B_HART_EN & hart )
+ {
+ if (LIBERO_SETTING_CONTEXT_EN[option][1U] & periph_context_mask)
+ {
+ result = 0U;
+ }
+ }
+ }
+ else
+ {
+ hart = 0U;
+ }
+#else
+ (void)hart;
+ (void)periph_context_mask;
+ (void)option;
+ result = 0U;
+#endif
+ return result;
+}
+
+/**
+ * Turn on/off mss peripheral as required
+ * @param peripheral_mask
+ * @param req_state
+ */
+static inline void peripheral_on_off(uint32_t peripheral_mask , PERIPH_RESET_STATE req_state)
+{
+ if (req_state == PERIPHERAL_OFF)
+ {
+ /* Turn off clock */
+ SYSREG->SUBBLK_CLOCK_CR &= (uint32_t)~(peripheral_mask);
+ /* Hold in reset */
+ SYSREG->SOFT_RESET_CR |= (uint32_t)(peripheral_mask);
+ }
+ else
+ {
+ /* Turn on clock */
+ SYSREG->SUBBLK_CLOCK_CR |= (peripheral_mask);
+ /* Remove soft reset */
+ SYSREG->SOFT_RESET_CR &= (uint32_t)~(peripheral_mask);
+ }
+}
+
+
+/***************************************************************************//**
+ * See mss_peripherals.h for details of how to use this function.
+ */
+__attribute__((weak)) uint8_t mss_config_clk_rst(mss_peripherals peripheral, uint8_t hart, PERIPH_RESET_STATE req_state)
+{
+ uint8_t result = 1U;
+
+ ASSERT(PERIPHERAL_SETUP[peripheral][PERIPHERAL_INDEX_OFFSET] == peripheral);
+
+ result = verify_context_enable(PERIPHERAL_SETUP[peripheral][CONTEXT_EN_INDEX_OFFSET], PERIPHERAL_SETUP[peripheral][CONTEXT_MASK_INDEX_OFFSET] , hart);
+
+ if (result == 0U)
+ {
+ peripheral_on_off(PERIPHERAL_SETUP[peripheral][CONTEXT_SUBCLK_INDEX_OFFSET] , req_state);
+ }
+ return result;
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_peripherals.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_peripherals.h
new file mode 100644
index 00000000..0f6f217c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_peripherals.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_peripherals.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS fumnctions related to MSS peripherals.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_PERIPHERALS_H
+#define MSS_PERIPHERALS_H
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_CONTEXT_A_EN)
+#define LIBERO_SETTING_CONTEXT_A_EN 0x00000000UL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_EN)
+#define LIBERO_SETTING_CONTEXT_B_EN 0x00000000UL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_A_EN_FIC)
+#define LIBERO_SETTING_CONTEXT_A_EN_FIC 0x0000000FUL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_EN_FIC)
+#define LIBERO_SETTING_CONTEXT_B_EN_FIC 0x0000000FUL
+#endif
+
+/***************************************************************************//**
+
+ */
+typedef enum PERIPH_RESET_STATE_
+{
+
+ PERIPHERAL_ON = 0x00, /*!< 0 RST and clk ON */
+ PERIPHERAL_OFF = 0x01, /*!< 1 RST and clk OFF */
+} PERIPH_RESET_STATE;
+
+#define CONTEXT_EN_INDEX 0x00U
+#define CONTEXT_EN_INDEX_FIC 0x01U
+#define SUBBLK_CLOCK_NA_MASK 0x00U
+
+typedef enum mss_peripherals_ {
+ MSS_PERIPH_MMUART0 = 0U,
+ MSS_PERIPH_MMUART1 = 1U,
+ MSS_PERIPH_MMUART2 = 2U,
+ MSS_PERIPH_MMUART3 = 3U,
+ MSS_PERIPH_MMUART4 = 4U,
+ MSS_PERIPH_WDOG0 = 5U,
+ MSS_PERIPH_WDOG1 = 6U,
+ MSS_PERIPH_WDOG2 = 7U,
+ MSS_PERIPH_WDOG3 = 8U,
+ MSS_PERIPH_WDOG4 = 9U,
+ MSS_PERIPH_SPI0 = 10U,
+ MSS_PERIPH_SPI1 = 11U,
+ MSS_PERIPH_I2C0 = 12U,
+ MSS_PERIPH_I2C1 = 13U,
+ MSS_PERIPH_CAN0 = 14U,
+ MSS_PERIPH_CAN1 = 15U,
+ MSS_PERIPH_MAC0 = 16U,
+ MSS_PERIPH_MAC1 = 17U,
+ MSS_PERIPH_TIMER = 18U,
+ MSS_PERIPH_GPIO0 = 19U,
+ MSS_PERIPH_GPIO1 = 20U,
+ MSS_PERIPH_GPIO2 = 21U,
+ MSS_PERIPH_RTC = 22U,
+ MSS_PERIPH_H2FINT = 23U,
+ MSS_PERIPH_CRYPTO = 24U,
+ MSS_PERIPH_USB = 25U,
+ MSS_PERIPH_QSPIXIP = 26U,
+ MSS_PERIPH_ATHENA = 27U,
+ MSS_PERIPH_TRACE = 28U,
+ MSS_PERIPH_MAILBOX_SC = 29U,
+ MSS_PERIPH_EMMC = 30U,
+ MSS_PERIPH_CFM = 31U,
+ MSS_PERIPH_FIC0 = 32U,
+ MSS_PERIPH_FIC1 = 33U,
+ MSS_PERIPH_FIC2 = 34U,
+ MSS_PERIPH_FIC3 = 35U
+} mss_peripherals;
+
+
+/***************************************************************************//**
+ This function is used to turn on or off a peripheral. If contexts have been
+ configured, these will be checked to see if peripheral should be controlled
+ from a particular context.
+
+ @param peripheral
+ See enum mss_peripherals for list of peripherals
+
+ @param hart
+ Origin hart of this request
+
+ @req_state
+ Turn peripheral on or off:
+ - PERIPHERAL_ON
+ - PERIPHERAL_OFF
+ Example:
+ @code
+ uint8_t err_status;
+ err_status = mss_config_clk_rst(MSS_PERIPH_MMUART0, (uint8_t) origin_hart_ID, PERIPHERAL_ON);
+
+ if(0U != err_status)
+ {
+ print_uart0("\n\r Context not allowed to access UART0 from hart:%d\n\nr", origin_hart_ID);
+ }
+ @endcode
+ */
+uint8_t mss_config_clk_rst(mss_peripherals peripheral, uint8_t hart, PERIPH_RESET_STATE req_state);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_PERIPHERALS_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_plic.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_plic.c
new file mode 100644
index 00000000..15297e97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_plic.c
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_plic.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PLIC and PRCI access data structures and functions.
+ *
+ * PLIC related data which cannot be placed in mss_plic.h
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const unsigned long plic_hart_lookup[5U] = {0U, 1U, 3U, 5U, 7U};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_plic.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_plic.h
new file mode 100644
index 00000000..16c16029
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_plic.h
@@ -0,0 +1,1026 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_plic.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PLIC and PRCI access data structures and functions.
+ *
+ * Definitions and functions associated with PLIC interrupts.
+ *
+ */
+#ifndef MSS_PLIC_H
+#define MSS_PLIC_H
+
+#include
+#ifndef CONFIG_OPENSBI
+#include "encoding.h"
+#endif
+
+#include "mss_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *Return value from External IRQ handler. This will be used to disable the
+ *Return External interrupt.
+ */
+#define EXT_IRQ_KEEP_ENABLED 0U
+#define EXT_IRQ_DISABLE 1U
+
+/*------------------------------------------------------------------------------
+ *
+ */
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+uint8_t Invalid_IRQHandler(void);
+uint8_t l2_metadata_corr_IRQHandler(void);
+uint8_t l2_metadata_uncorr_IRQHandler(void);
+uint8_t l2_data_corr_IRQHandler(void);
+uint8_t l2_data_uncorr_IRQHandler(void);
+uint8_t dma_ch0_DONE_IRQHandler(void);
+uint8_t dma_ch0_ERR_IRQHandler(void);
+uint8_t dma_ch1_DONE_IRQHandler(void);
+uint8_t dma_ch1_ERR_IRQHandler(void);
+uint8_t dma_ch2_DONE_IRQHandler(void);
+uint8_t dma_ch2_ERR_IRQHandler(void);
+uint8_t dma_ch3_DONE_IRQHandler(void);
+uint8_t dma_ch3_ERR_IRQHandler(void);
+uint8_t gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler(void);
+uint8_t gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler(void);
+uint8_t gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler(void);
+uint8_t gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler(void);
+uint8_t gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler(void);
+uint8_t gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler(void);
+uint8_t gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler(void);
+uint8_t gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler(void);
+uint8_t gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler(void);
+uint8_t gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler(void);
+uint8_t gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler(void);
+uint8_t gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler(void);
+uint8_t gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler(void);
+
+uint8_t gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler(void);
+uint8_t gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler(void);
+uint8_t gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler(void);
+uint8_t gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler(void);
+uint8_t gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler(void);
+uint8_t gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler(void);
+uint8_t gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler(void);
+uint8_t gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler(void);
+uint8_t gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler(void);
+uint8_t gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler(void);
+uint8_t gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler(void);
+uint8_t gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler(void);
+uint8_t gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler(void);
+uint8_t gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler(void);
+uint8_t gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler(void);
+
+uint8_t gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler(void);
+uint8_t gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler(void);
+uint8_t gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler(void);
+uint8_t gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler(void);
+
+uint8_t gpio1_bit18_plic_32_IRQHandler(void);
+uint8_t gpio1_bit19_plic_33_IRQHandler(void);
+uint8_t gpio1_bit20_plic_34_IRQHandler(void);
+uint8_t gpio1_bit21_plic_35_IRQHandler(void);
+uint8_t gpio1_bit22_plic_36_IRQHandler(void);
+uint8_t gpio1_bit23_plic_37_IRQHandler(void);
+
+uint8_t gpio0_non_direct_plic_IRQHandler(void);
+uint8_t gpio1_non_direct_plic_IRQHandler(void);
+uint8_t gpio2_non_direct_plic_IRQHandler(void);
+
+uint8_t spi0_plic_IRQHandler(void);
+uint8_t spi1_plic_IRQHandler(void);
+uint8_t external_can0_plic_IRQHandler(void);
+uint8_t can1_IRQHandler(void);
+uint8_t External_i2c0_main_plic_IRQHandler(void);
+uint8_t External_i2c0_alert_plic_IRQHandler(void);
+uint8_t i2c0_sus_plic_IRQHandler(void);
+uint8_t i2c1_main_plic_IRQHandler(void);
+uint8_t i2c1_alert_plic_IRQHandler(void);
+uint8_t i2c1_sus_plic_IRQHandler(void);
+uint8_t mac0_int_plic_IRQHandler(void);
+uint8_t mac0_queue1_plic_IRQHandler(void);
+uint8_t mac0_queue2_plic_IRQHandler(void);
+uint8_t mac0_queue3_plic_IRQHandler(void);
+uint8_t mac0_emac_plic_IRQHandler(void);
+uint8_t mac0_mmsl_plic_IRQHandler(void);
+uint8_t mac1_int_plic_IRQHandler(void);
+uint8_t mac1_queue1_plic_IRQHandler(void);
+uint8_t mac1_queue2_plic_IRQHandler(void);
+uint8_t mac1_queue3_plic_IRQHandler(void);
+uint8_t mac1_emac_plic_IRQHandler(void);
+uint8_t mac1_mmsl_plic_IRQHandler(void);
+uint8_t ddrc_train_plic_IRQHandler(void);
+uint8_t scb_interrupt_plic_IRQHandler(void);
+uint8_t ecc_error_plic_IRQHandler(void);
+uint8_t ecc_correct_plic_IRQHandler(void);
+uint8_t rtc_wakeup_plic_IRQHandler(void);
+uint8_t rtc_match_plic_IRQHandler(void);
+uint8_t timer1_plic_IRQHandler(void);
+uint8_t timer2_plic_IRQHandler(void);
+uint8_t envm_plic_IRQHandler(void);
+uint8_t qspi_plic_IRQHandler(void);
+uint8_t usb_dma_plic_IRQHandler(void);
+uint8_t usb_mc_plic_IRQHandler(void);
+uint8_t mmc_main_plic_IRQHandler(void);
+uint8_t mmc_wakeup_plic_IRQHandler(void);
+uint8_t mmuart0_plic_77_IRQHandler(void);
+uint8_t mmuart1_plic_IRQHandler(void);
+uint8_t mmuart2_plic_IRQHandler(void);
+uint8_t mmuart3_plic_IRQHandler(void);
+uint8_t mmuart4_plic_IRQHandler(void);
+uint8_t g5c_devrst_plic_IRQHandler(void);
+uint8_t g5c_message_plic_IRQHandler(void);
+uint8_t usoc_vc_interrupt_plic_IRQHandler(void);
+uint8_t usoc_smb_interrupt_plic_IRQHandler(void);
+uint8_t e51_0_Maintence_plic_IRQHandler(void);
+
+uint8_t wdog0_mvrp_plic_IRQHandler(void);
+uint8_t wdog1_mvrp_plic_IRQHandler(void);
+uint8_t wdog2_mvrp_plic_IRQHandler(void);
+uint8_t wdog3_mvrp_plic_IRQHandler(void);
+uint8_t wdog4_mvrp_plic_IRQHandler(void);
+uint8_t wdog0_tout_plic_IRQHandler(void);
+uint8_t wdog1_tout_plic_IRQHandler(void);
+uint8_t wdog2_tout_plic_IRQHandler(void);
+uint8_t wdog3_tout_plic_IRQHandler(void);
+uint8_t wdog4_tout_plic_IRQHandler(void);
+uint8_t g5c_mss_spi_plic_IRQHandler(void);
+uint8_t volt_temp_alarm_plic_IRQHandler(void);
+
+uint8_t athena_complete_plic_IRQHandler(void);
+uint8_t athena_alarm_plic_IRQHandler(void);
+uint8_t athena_bus_error_plic_IRQHandler(void);
+uint8_t usoc_axic_us_plic_IRQHandler(void);
+uint8_t usoc_axic_ds_plic_IRQHandler(void);
+
+uint8_t reserved_104_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_0_plic_IRQHandler(void);
+uint8_t fabric_f2h_1_plic_IRQHandler(void);
+uint8_t fabric_f2h_2_plic_IRQHandler(void);
+uint8_t fabric_f2h_3_plic_IRQHandler(void);
+uint8_t fabric_f2h_4_plic_IRQHandler(void);
+uint8_t fabric_f2h_5_plic_IRQHandler(void);
+uint8_t fabric_f2h_6_plic_IRQHandler(void);
+uint8_t fabric_f2h_7_plic_IRQHandler(void);
+uint8_t fabric_f2h_8_plic_IRQHandler(void);
+uint8_t fabric_f2h_9_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_10_plic_IRQHandler(void);
+uint8_t fabric_f2h_11_plic_IRQHandler(void);
+uint8_t fabric_f2h_12_plic_IRQHandler(void);
+uint8_t fabric_f2h_13_plic_IRQHandler(void);
+uint8_t fabric_f2h_14_plic_IRQHandler(void);
+uint8_t fabric_f2h_15_plic_IRQHandler(void);
+uint8_t fabric_f2h_16_plic_IRQHandler(void);
+uint8_t fabric_f2h_17_plic_IRQHandler(void);
+uint8_t fabric_f2h_18_plic_IRQHandler(void);
+uint8_t fabric_f2h_19_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_20_plic_IRQHandler(void);
+uint8_t fabric_f2h_21_plic_IRQHandler(void);
+uint8_t fabric_f2h_22_plic_IRQHandler(void);
+uint8_t fabric_f2h_23_plic_IRQHandler(void);
+uint8_t fabric_f2h_24_plic_IRQHandler(void);
+uint8_t fabric_f2h_25_plic_IRQHandler(void);
+uint8_t fabric_f2h_26_plic_IRQHandler(void);
+uint8_t fabric_f2h_27_plic_IRQHandler(void);
+uint8_t fabric_f2h_28_plic_IRQHandler(void);
+uint8_t fabric_f2h_29_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_30_plic_IRQHandler(void);
+uint8_t fabric_f2h_31_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_32_plic_IRQHandler(void);
+uint8_t fabric_f2h_33_plic_IRQHandler(void);
+uint8_t fabric_f2h_34_plic_IRQHandler(void);
+uint8_t fabric_f2h_35_plic_IRQHandler(void);
+uint8_t fabric_f2h_36_plic_IRQHandler(void);
+uint8_t fabric_f2h_37_plic_IRQHandler(void);
+uint8_t fabric_f2h_38_plic_IRQHandler(void);
+uint8_t fabric_f2h_39_plic_IRQHandler(void);
+uint8_t fabric_f2h_40_plic_IRQHandler(void);
+uint8_t fabric_f2h_41_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_42_plic_IRQHandler(void);
+uint8_t fabric_f2h_43_plic_IRQHandler(void);
+uint8_t fabric_f2h_44_plic_IRQHandler(void);
+uint8_t fabric_f2h_45_plic_IRQHandler(void);
+uint8_t fabric_f2h_46_plic_IRQHandler(void);
+uint8_t fabric_f2h_47_plic_IRQHandler(void);
+uint8_t fabric_f2h_48_plic_IRQHandler(void);
+uint8_t fabric_f2h_49_plic_IRQHandler(void);
+uint8_t fabric_f2h_50_plic_IRQHandler(void);
+uint8_t fabric_f2h_51_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_52_plic_IRQHandler(void);
+uint8_t fabric_f2h_53_plic_IRQHandler(void);
+uint8_t fabric_f2h_54_plic_IRQHandler(void);
+uint8_t fabric_f2h_55_plic_IRQHandler(void);
+uint8_t fabric_f2h_56_plic_IRQHandler(void);
+uint8_t fabric_f2h_57_plic_IRQHandler(void);
+uint8_t fabric_f2h_58_plic_IRQHandler(void);
+uint8_t fabric_f2h_59_plic_IRQHandler(void);
+uint8_t fabric_f2h_60_plic_IRQHandler(void);
+uint8_t fabric_f2h_61_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_62_plic_IRQHandler(void);
+uint8_t fabric_f2h_63_plic_IRQHandler(void);
+
+uint8_t bus_error_unit_hart_0_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_1_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_2_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_3_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_4_plic_IRQHandler(void);
+
+
+#else
+uint8_t Invalid_IRQHandler(void);
+uint8_t External_1_IRQHandler(void);
+uint8_t External_2_IRQHandler(void);
+uint8_t External_3_IRQHandler(void);
+uint8_t USART0_plic_4_IRQHandler(void);
+uint8_t External_5_IRQHandler(void);
+uint8_t External_6_IRQHandler(void);
+uint8_t External_7_IRQHandler(void);
+uint8_t External_8_IRQHandler(void);
+uint8_t External_9_IRQHandler(void);
+uint8_t External_10_IRQHandler(void);
+uint8_t External_11_IRQHandler(void);
+uint8_t External_12_IRQHandler(void);
+uint8_t External_13_IRQHandler(void);
+uint8_t External_14_IRQHandler(void);
+uint8_t External_15_IRQHandler(void);
+uint8_t External_16_IRQHandler(void);
+uint8_t External_17_IRQHandler(void);
+uint8_t External_18_IRQHandler(void);
+uint8_t External_19_IRQHandler(void);
+uint8_t External_20_IRQHandler(void);
+uint8_t External_21_IRQHandler(void);
+uint8_t External_22_IRQHandler(void);
+uint8_t dma_ch0_DONE_IRQHandler(void);
+uint8_t dma_ch0_ERR_IRQHandler(void);
+uint8_t dma_ch1_DONE_IRQHandler(void);
+uint8_t dma_ch1_ERR_IRQHandler(void);
+uint8_t dma_ch2_DONE_IRQHandler(void);
+uint8_t dma_ch2_ERR_IRQHandler(void);
+uint8_t dma_ch3_DONE_IRQHandler(void);
+uint8_t dma_ch3_ERR_IRQHandler(void);
+uint8_t External_31_IRQHandler(void);
+uint8_t External_32_IRQHandler(void);
+uint8_t External_33_IRQHandler(void);
+uint8_t External_34_IRQHandler(void);
+uint8_t External_35_IRQHandler(void);
+uint8_t External_36_IRQHandler(void);
+uint8_t External_37_IRQHandler(void);
+uint8_t External_38_IRQHandler(void);
+uint8_t External_39_IRQHandler(void);
+uint8_t External_40_IRQHandler(void);
+uint8_t External_41_IRQHandler(void);
+uint8_t External_42_IRQHandler(void);
+uint8_t External_43_IRQHandler(void);
+uint8_t External_44_IRQHandler(void);
+uint8_t External_45_IRQHandler(void);
+uint8_t External_46_IRQHandler(void);
+uint8_t External_47_IRQHandler(void);
+uint8_t External_48_IRQHandler(void);
+uint8_t External_49_IRQHandler(void);
+uint8_t External_50_IRQHandler(void);
+uint8_t External_51_IRQHandler(void);
+uint8_t External_52_IRQHandler(void);
+uint8_t MAC0_plic_53_IRQHandler(void);
+
+#endif
+
+/***************************************************************************//**
+ * PLIC source Interrupt numbers:
+ */
+/* See section on PLIC Interrupt Sources in User Guide */
+#define OFFSET_TO_MSS_GLOBAL_INTS 13U
+typedef enum
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ INVALID_IRQn = 0,
+ L2_METADATA_CORR_IRQn = 1,
+ L2_METADAT_UNCORR_IRQn = 2,
+ L2_DATA_CORR_IRQn = 3,
+ L2_DATA_UNCORR_IRQn = 4,
+ DMA_CH0_DONE_IRQn = 5,
+ DMA_CH0_ERR_IRQn = 6,
+ DMA_CH1_DONE_IRQn = 7,
+ DMA_CH1_ERR_IRQn = 8,
+ DMA_CH2_DONE_IRQn = 9,
+ DMA_CH2_ERR_IRQn = 10,
+ DMA_CH3_DONE_IRQn = 11,
+ DMA_CH3_ERR_IRQn = 12,
+ /* see GPIO Interrupt Multiplexing in the User Guide */
+ GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0 = 0 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1 = 1 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2 = 2 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3 = 3 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4 = 4 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5 = 5 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6 = 6 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7 = 7 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8 = 8 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9 = 9 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10 = 10 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11 = 11 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12 = 12 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO0_BIT13_or_GPIO2_BIT13_PLIC_13 = 13 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14 = 14 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15 = 15 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16 = 16 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17 = 17 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18 = 18 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19 = 19 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT6_or_GPIO2_BIT20_PLIC_20 = 20 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT7_or_GPIO2_BIT21_PLIC_21 = 21 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT8_or_GPIO2_BIT22_PLIC_22 = 22 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT9_or_GPIO2_BIT23_PLIC_23 = 23 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT10_or_GPIO2_BIT24_PLIC_24 = 24 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT11_or_GPIO2_BIT25_PLIC_25 = 25 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT12_or_GPIO2_BIT26_PLIC_26 = 26 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT13_or_GPIO2_BIT27_PLIC_27 = 27 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO1_BIT14_or_GPIO2_BIT28_PLIC_28 = 28 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT15_or_GPIO2_BIT29_PLIC_29 = 29 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT16_or_GPIO2_BIT30_PLIC_30 = 30 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT17_or_GPIO2_BIT31_PLIC_31 = 31 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO1_BIT18_PLIC_32 = 32 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT19_PLIC_33 = 33 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT20_PLIC_34 = 34 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT21_PLIC_35 = 35 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT22_PLIC_36 = 36 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT23_PLIC_37 = 37 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO0_NON_DIRECT_PLIC = 38 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_NON_DIRECT_PLIC = 39 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO2_NON_DIRECT_PLIC = 40 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ SPI0_PLIC = 41 + OFFSET_TO_MSS_GLOBAL_INTS,
+ SPI1_PLIC = 42 + OFFSET_TO_MSS_GLOBAL_INTS,
+ CAN0_PLIC = 43 + OFFSET_TO_MSS_GLOBAL_INTS,
+ CAN1_PLIC = 44 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_MAIN_PLIC = 45 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_ALERT_PLIC = 46 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_SUS_PLIC = 47 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_MAIN_PLIC = 48 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_ALERT_PLIC = 49 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_SUS_PLIC = 50 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_INT_PLIC = 51 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE1_PLIC = 52 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE2_PLIC = 53 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE3_PLIC = 54 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_EMAC_PLIC = 55 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_MMSL_PLIC = 56 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_INT_PLIC = 57 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE1_PLIC = 58 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE2_PLIC = 59 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE3_PLIC = 60 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_EMAC_PLIC = 61 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_MMSL_PLIC = 62 + OFFSET_TO_MSS_GLOBAL_INTS,
+ DDRC_TRAIN_PLIC = 63 + OFFSET_TO_MSS_GLOBAL_INTS,
+ SCB_INTERRUPT_PLIC = 64 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ECC_ERROR_PLIC = 65 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ECC_CORRECT_PLIC = 66 + OFFSET_TO_MSS_GLOBAL_INTS,
+ RTC_WAKEUP_PLIC = 67 + OFFSET_TO_MSS_GLOBAL_INTS,
+ RTC_MATCH_PLIC = 68 + OFFSET_TO_MSS_GLOBAL_INTS,
+ TIMER1_PLIC = 69 + OFFSET_TO_MSS_GLOBAL_INTS,
+ TIMER2_PLIC = 70 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ENVM_PLIC = 71 + OFFSET_TO_MSS_GLOBAL_INTS,
+ QSPI_PLIC = 72 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USB_DMA_PLIC = 73 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USB_MC_PLIC = 74 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMC_main_PLIC = 75 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMC_wakeup_PLIC = 76 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART0_PLIC_77 = 77 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART1_PLIC = 78 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART2_PLIC = 79 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART3_PLIC = 80 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART4_PLIC = 81 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ G5C_DEVRST_PLIC = 82 + OFFSET_TO_MSS_GLOBAL_INTS,
+ g5c_MESSAGE_PLIC = 83 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_VC_INTERRUPT_PLIC = 84 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_SMB_INTERRUPT_PLIC = 85 + OFFSET_TO_MSS_GLOBAL_INTS,
+ /* contains multiple interrupts- */
+ E51_0_MAINTENACE_PLIC = 86 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ WDOG0_MRVP_PLIC = 87 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG1_MRVP_PLIC = 88 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG2_MRVP_PLIC = 89 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG3_MRVP_PLIC = 90 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG4_MRVP_PLIC = 91 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG0_TOUT_PLIC = 92 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG1_TOUT_PLIC = 93 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG2_TOUT_PLIC = 94 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG3_TOUT_PLIC = 95 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG4_TOUT_PLIC = 96 + OFFSET_TO_MSS_GLOBAL_INTS,
+ G5C_MSS_SPI_PLIC = 97 + OFFSET_TO_MSS_GLOBAL_INTS,
+ VOLT_TEMP_ALARM_PLIC = 98 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_COMPLETE_PLIC = 99 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_ALARM_PLIC = 100 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_BUS_ERROR_PLIC = 101 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_AXIC_US_PLIC = 102 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_AXIC_DS_PLIC = 103 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_0_PLIC = 105 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_1_PLIC = 106 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_2_PLIC = 107 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_3_PLIC = 108 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_4_PLIC = 109 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_5_PLIC = 110 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_6_PLIC = 111 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_7_PLIC = 112 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_8_PLIC = 113 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_9_PLIC = 114 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_10_PLIC = 115 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_11_PLIC = 116 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_12_PLIC = 117 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_13_PLIC = 118 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_14_PLIC = 119 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_15_PLIC = 120 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_16_PLIC = 121 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_17_PLIC = 122 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_18_PLIC = 123 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_19_PLIC = 124 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_20_PLIC = 125 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_21_PLIC = 126 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_22_PLIC = 127 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_23_PLIC = 128 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_24_PLIC = 129 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_25_PLIC = 130 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_26_PLIC = 131 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_27_PLIC = 132 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_28_PLIC = 133 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_29_PLIC = 134 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_30_PLIC = 135 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_31_PLIC = 136 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_32_PLIC = 137 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_33_PLIC = 138 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_34_PLIC = 139 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_35_PLIC = 140 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_36_PLIC = 141 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_37_PLIC = 142 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_38_PLIC = 143 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_39_PLIC = 144 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_40_PLIC = 145 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_41_PLIC = 146 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_42_PLIC = 147 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_43_PLIC = 148 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_44_PLIC = 149 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_45_PLIC = 150 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_46_PLIC = 151 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_47_PLIC = 152 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_48_PLIC = 153 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_49_PLIC = 154 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_50_PLIC = 155 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_51_PLIC = 156 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_52_PLIC = 157 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_53_PLIC = 158 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_54_PLIC = 159 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_55_PLIC = 160 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_56_PLIC = 161 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_57_PLIC = 162 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_58_PLIC = 163 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_59_PLIC = 164 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_60_PLIC = 165 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_61_PLIC = 166 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_62_PLIC = 167 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_63_PLIC = 168 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ BUS_ERROR_UNIT_HART_0 = 182,
+ BUS_ERROR_UNIT_HART_1 = 183,
+ BUS_ERROR_UNIT_HART_2 = 184,
+ BUS_ERROR_UNIT_HART_3 = 185,
+ BUS_ERROR_UNIT_HART_4 = 186
+
+#else
+ INVALID_IRQn = 0,
+ L2Cache_0_PLIC_1 = 1,
+ L2Cache_1_PLIC_2 = 2,
+ L2Cache_2__PLIC_3 = 3,
+ USART0_PLIC_4 = 4,
+ USART1_PLIC_5 = 5,
+ QSPI_12_PLIC_6 = 6,
+
+ gpio_PLIC_7 = 7,
+ gpio_PLIC_8 = 8,
+ gpio_PLIC_9 = 9,
+ gpio_10 = 10,
+ gpio_11 = 11,
+ gpio_12 = 12,
+ gpio_PLIC_13 = 13,
+ gpio_PLIC_14 = 14,
+ gpio_PLIC_15 = 15,
+ gpio_PLIC_16 = 16,
+ gpio_PLIC_17 = 17,
+ gpio_PLIC_18 = 18,
+ gpio_PLIC_19 = 19,
+ gpio_PLIC_20 = 20,
+ gpio_PLIC_21 = 21,
+ gpio_PLIC_22 = 22,
+
+ dma_PLIC_23 = 23,
+ dma_PLIC_24 = 24,
+ dma_PLIC_25 = 25,
+ dma_PLIC_26 = 26,
+ dma_PLIC_27 = 27,
+ dma_PLIC_28 = 28,
+ dma_PLIC_29 = 29,
+ dma_PLIC_30 = 30,
+
+ ddr_subsytem_PLIC_31 = 31,
+
+ chiplink_msi_PLIC_32 = 32,
+ chiplink_msi_PLIC_33 = 33,
+ chiplink_msi_PLIC_34 = 34,
+ chiplink_msi_PLIC_35 = 35,
+ chiplink_msi_PLIC_36 = 36,
+ chiplink_msi_PLIC_37 = 37,
+ chiplink_msi_PLIC_38 = 38,
+ chiplink_msi_PLIC_39 = 39,
+ chiplink_msi_PLIC_40 = 40,
+ chiplink_msi_PLIC_41 = 41,
+
+ pwm0_PLIC_42 = 42,
+ pwm0_PLIC_43 = 43,
+ pwm0_PLIC_44 = 44,
+ pwm0_PLIC_45 = 45,
+
+ pwm1_PLIC_46 = 46,
+ pwm1_PLIC_47 = 47,
+ pwm1_PLIC_48 = 48,
+ pwm1_PLIC_49 = 49,
+
+ i2c_PLIC_50 = 50,
+ QSPI0_PLIC_51 = 51,
+ QSPI1_PLIC_52 = 52,
+ ethernet_PLIC_53 = 53
+
+#endif
+
+} PLIC_IRQn_Type;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define MAX_PLIC_INT BUS_ERROR_UNIT_HART_4
+#else
+#define MAX_PLIC_INT ethernet_PLIC_53
+#endif
+
+/***************************************************************************//**
+ * E51-0 is Maintenance Interrupt, CPU needs to read status register to
+ * determine exact cause:
+ * This structure added here for clarity, need to replay with status register
+ * defines for determining interrupt cause
+ */
+typedef enum
+{
+ mpu_fail_plic =0,
+ lp_state_enter_plic =1,
+ lp_state_exit_plic =2,
+ ff_start_plic =3,
+ ff_end_plic =4,
+ fpga_on_plic =5,
+ fpga_off_plic =6,
+ scb_error_plic =7,
+ scb_fault_plic =8,
+ mesh_fail_plic =9
+} PLIC_IRQ86_Type;
+
+typedef struct
+{
+ volatile uint32_t PRIORITY_THRESHOLD;
+ volatile uint32_t CLAIM_COMPLETE;
+ volatile uint32_t reserved[(0x1000/4)-2];
+} IRQ_Target_Type;
+
+typedef struct
+{
+ volatile uint32_t ENABLES[32U];
+} Target_Enables_Type;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define PLIC_SET_UP_REGISTERS 6U
+#else
+#define PLIC_SET_UP_REGISTERS 2U
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define PLIC_NUM_SOURCES 187U
+#else
+#define PLIC_NUM_SOURCES 54U /* 53 actual, source 0 is not used */
+#endif
+
+#define PLIC_NUM_PRIORITIES 7U
+#define NUM_CLAIM_REGS 9U
+
+
+/* The FU540-C000 has 53 interrupt sources. */
+ typedef struct
+{
+ volatile uint32_t RESERVED0;
+ /*-------------------- Source Priority --------------------*/
+ volatile uint32_t SOURCE_PRIORITY[PLIC_NUM_SOURCES];
+ volatile uint32_t RESERVED1[(0x1000 / 4) - (PLIC_NUM_SOURCES + 1)];
+ /*-------------------- Pending array --------------------*/
+ volatile const uint32_t PENDING_ARRAY[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED2[(0x1000/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart0 Mode Enables--------------------*/
+ volatile uint32_t HART0_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED3[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart1 Mode Enables--------------------*/
+ volatile uint32_t HART1_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED4a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART1_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED4[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart2 Mode Enables--------------------*/
+ volatile uint32_t HART2_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED5a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART2_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED5[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart3 Mode Enables--------------------*/
+ volatile uint32_t HART3_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED6a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART3_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED6[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart4 Mode Enables--------------------*/
+ volatile uint32_t HART4_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED7a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART4_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED7[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ volatile uint32_t RESERVED8[(0x0C200000 - 0x0C002480)/4];
+
+ /*--- Target Priority threshold and claim/complete---------*/
+ IRQ_Target_Type TARGET[NUM_CLAIM_REGS]; /* See PLIC Register Map or
+ TARGET_OFFSET defines below
+ for offset details */
+
+} PLIC_Type;
+
+#define TARGET_OFFSET_HART0_M 0U
+#define TARGET_OFFSET_HART1_M 1U
+#define TARGET_OFFSET_HART1_S 2U
+#define TARGET_OFFSET_HART2_M 3U
+#define TARGET_OFFSET_HART2_S 4U
+#define TARGET_OFFSET_HART3_M 5U
+#define TARGET_OFFSET_HART3_S 6U
+#define TARGET_OFFSET_HART4_M 7U
+#define TARGET_OFFSET_HART4_S 8U
+
+extern const unsigned long plic_hart_lookup[5U];
+
+/***************************************************************************//**
+ * PLIC: Platform Level Interrupt Controller
+ */
+#define PLIC_BASE_ADDR 0x0C000000UL
+
+#define PLIC ((PLIC_Type * const)PLIC_BASE_ADDR)
+
+/*-------------------------------------------------------------------------*//**
+ * The function PLIC_init() initializes the PLIC controller and enables the
+ * global external interrupt bit.
+ */
+
+/*-----------------Hart Mode Enables--------------------*/
+
+static inline void PLIC_init(void)
+{
+ uint32_t inc;
+ uint64_t hart_id = read_csr(mhartid);
+
+ /* Disable all interrupts for the current hart. */
+ switch(hart_id)
+ {
+ case 0:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART0_MMODE_ENA[inc] = 0U;
+ }
+
+ /* Set the threshold to zero.
+ * PLIC provides context based threshold register for the settings of a
+ * interrupt priority threshold of each context. The threshold register
+ * is a WARL field. The PLIC will mask all PLIC interrupts of a priority
+ * less than or equal to threshold. For example, a threshold value of zero
+ * permits all interrupts with non-zero priority.*/
+
+ PLIC->TARGET[TARGET_OFFSET_HART0_M].PRIORITY_THRESHOLD = 0U;
+ break;
+ case 1:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART1_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART1_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART1_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 2:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART2_MMODE_ENA[inc] = 0U;
+ PLIC->HART2_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART2_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART2_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 3:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART3_MMODE_ENA[inc] = 0U;
+ PLIC->HART3_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART3_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART3_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 4:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART4_MMODE_ENA[inc] = 0U;
+ PLIC->HART4_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART4_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART4_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ default:
+ break;
+ }
+
+ /* Enable machine external interrupts. */
+ set_csr(mie, MIP_MEIP);
+}
+
+
+
+/***************************************************************************//**
+ * The function PLIC_EnableIRQ() enables the external interrupt for the
+ * interrupt number indicated by the parameter IRQn.
+ */
+static inline void PLIC_EnableIRQ(PLIC_IRQn_Type IRQn)
+{
+ uint32_t current;
+ uint64_t hart_id = read_csr(mhartid);
+
+ switch(hart_id)
+ {
+ case 0:
+ current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 1:
+ current = PLIC->HART1_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART1_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 2:
+ current = PLIC->HART2_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART2_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 3:
+ current = PLIC->HART3_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART3_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 4:
+ current = PLIC->HART4_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART4_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ default:
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_DisableIRQ() disables the external interrupt for the
+ * interrupt number indicated by the parameter IRQn.
+
+ * NOTE:
+ * This function can be used to disable the external interrupt from outside
+ * external interrupt handler function.
+ * This function MUST NOT be used from within the External Interrupt
+ * handler.
+ * If you wish to disable the external interrupt while the interrupt handler
+ * for that external interrupt is executing then you must use the return
+ * value EXT_IRQ_DISABLE to return from the extern interrupt handler.
+ */
+static inline void PLIC_DisableIRQ(PLIC_IRQn_Type IRQn)
+{
+ uint32_t current;
+ uint64_t hart_id = read_csr(mhartid);
+
+ switch(hart_id)
+ {
+ case 0:
+ current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 1:
+ current = PLIC->HART1_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART1_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 2:
+ current = PLIC->HART2_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART2_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 3:
+ current = PLIC->HART3_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART3_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 4:
+ current = PLIC->HART4_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART4_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ default:
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_SetPriority() sets the priority for the external interrupt
+ * for the interrupt number indicated by the parameter IRQn.
+ */
+static inline void PLIC_SetPriority(PLIC_IRQn_Type IRQn, uint32_t priority)
+{
+ if((IRQn > INVALID_IRQn) && (IRQn < PLIC_NUM_SOURCES))
+ {
+ PLIC->SOURCE_PRIORITY[IRQn-1] = priority;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_GetPriority() returns the priority for the external
+ * interrupt for the interrupt number indicated by the parameter IRQn.
+ */
+static inline uint32_t PLIC_GetPriority(PLIC_IRQn_Type IRQn)
+{
+ uint32_t ret_val = 0U;
+
+ if((IRQn > INVALID_IRQn) && (IRQn < PLIC_NUM_SOURCES))
+ {
+ ret_val = PLIC->SOURCE_PRIORITY[IRQn-1];
+ }
+
+ return(ret_val);
+}
+
+
+static inline uint32_t PLIC_pending(PLIC_IRQn_Type IRQn)
+{
+ return (PLIC->PENDING_ARRAY[IRQn/32U] & (0x01U<<(IRQn%32U)));
+}
+
+/***************************************************************************//**
+ * The function PLIC_ClaimIRQ() claims the interrupt from the PLIC controller.
+ */
+static inline uint32_t PLIC_ClaimIRQ(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ return (PLIC->TARGET[plic_hart_lookup[hart_id]].CLAIM_COMPLETE);
+}
+
+/***************************************************************************//**
+ * The function PLIC_CompleteIRQ() indicates to the PLIC controller the
+ * interrupt is processed and claim is complete.
+ */
+static inline void PLIC_CompleteIRQ(uint32_t source)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ ASSERT(source <= MAX_PLIC_INT);
+
+ PLIC->TARGET[plic_hart_lookup[hart_id]].CLAIM_COMPLETE = source;
+}
+
+/***************************************************************************//**
+ *
+ * The function PLIC_SetPriority_Threshold() sets the threshold for a particular
+ * hart. The default threshold on reset is 0.
+ * The PFSoC Core Complex supports setting of an interrupt priority threshold
+ * via the threshold register. The threshold is a WARL field, where the PFSoC
+ * Core Complex supports a maximum threshold of 7.
+ * The PFSoC Core Complex will mask all PLIC interrupts of a priority less than
+ * or equal to threshold. For example, a threshold value of zero permits all
+ * interrupts with non-zero priority, whereas a value of 7 masks all
+ * interrupts.
+ */
+static inline void PLIC_SetPriority_Threshold(uint32_t threshold)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ ASSERT(threshold <= 7);
+
+ PLIC->TARGET[plic_hart_lookup[hart_id]].PRIORITY_THRESHOLD = threshold;
+}
+
+/***************************************************************************//**
+ * PLIC_ClearPendingIRQ(void)
+ * This is only called by the startup hart and only once
+ * Clears any pending interrupts as PLIC can be in unknown state on startup
+ */
+static inline void PLIC_ClearPendingIRQ(void)
+{
+ volatile uint32_t int_num = PLIC_ClaimIRQ();
+ volatile int32_t wait_possible_int;
+
+ while ( int_num != INVALID_IRQn)
+ {
+ PLIC_CompleteIRQ(int_num);
+ wait_possible_int = 0xFU;
+ while (wait_possible_int)
+ {
+ wait_possible_int--;
+ }
+ int_num = PLIC_ClaimIRQ(); /* obtain interrupt, auto clears */
+ }
+}
+
+/***************************************************************************//**
+ * This function is only called from one hart on startup
+ */
+static inline void PLIC_init_on_reset(void)
+{
+ uint32_t inc;
+
+ /* default all priorities so effectively disabled */
+ for(inc = 0U; inc < PLIC_NUM_SOURCES; ++inc)
+ {
+ /* priority must be greater than threshold to be enabled, so setting to
+ * 7 disables */
+ PLIC->SOURCE_PRIORITY[inc] = 0U;
+ }
+
+ for(inc = 0U; inc < NUM_CLAIM_REGS; ++inc)
+ {
+ PLIC->TARGET[inc].PRIORITY_THRESHOLD = 7U;
+ }
+
+ /* and clear all the enables */
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART0_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_SMODE_ENA[inc] = 0U;
+ PLIC->HART2_MMODE_ENA[inc] = 0U;
+ PLIC->HART2_SMODE_ENA[inc] = 0U;
+ PLIC->HART3_MMODE_ENA[inc] = 0U;
+ PLIC->HART3_SMODE_ENA[inc] = 0U;
+ PLIC->HART4_MMODE_ENA[inc] = 0U;
+ PLIC->HART4_SMODE_ENA[inc] = 0U;
+ }
+
+ /* clear any pending interrupts- in case already there */
+ PLIC_ClearPendingIRQ();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_PLIC_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_pmp.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_pmp.c
new file mode 100644
index 00000000..2e21f5bb
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_pmp.c
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_pmp.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PMP configuration using MSS configurator values.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+/**
+ * \brief PMP configuration from Libero
+ *
+ */
+const uint64_t pmp_values[][18] = {
+ /* hart 0 */
+ {LIBERO_SETTING_HART0_CSR_PMPCFG0,
+ LIBERO_SETTING_HART0_CSR_PMPCFG2,
+ LIBERO_SETTING_HART0_CSR_PMPADDR0,
+ LIBERO_SETTING_HART0_CSR_PMPADDR1,
+ LIBERO_SETTING_HART0_CSR_PMPADDR2,
+ LIBERO_SETTING_HART0_CSR_PMPADDR3,
+ LIBERO_SETTING_HART0_CSR_PMPADDR4,
+ LIBERO_SETTING_HART0_CSR_PMPADDR5,
+ LIBERO_SETTING_HART0_CSR_PMPADDR6,
+ LIBERO_SETTING_HART0_CSR_PMPADDR7,
+ LIBERO_SETTING_HART0_CSR_PMPADDR8,
+ LIBERO_SETTING_HART0_CSR_PMPADDR9,
+ LIBERO_SETTING_HART0_CSR_PMPADDR10,
+ LIBERO_SETTING_HART0_CSR_PMPADDR11,
+ LIBERO_SETTING_HART0_CSR_PMPADDR12,
+ LIBERO_SETTING_HART0_CSR_PMPADDR13,
+ LIBERO_SETTING_HART0_CSR_PMPADDR14,
+ LIBERO_SETTING_HART0_CSR_PMPADDR15},
+ /* hart 1 */
+ {LIBERO_SETTING_HART1_CSR_PMPCFG0,
+ LIBERO_SETTING_HART1_CSR_PMPCFG2,
+ LIBERO_SETTING_HART1_CSR_PMPADDR0,
+ LIBERO_SETTING_HART1_CSR_PMPADDR1,
+ LIBERO_SETTING_HART1_CSR_PMPADDR2,
+ LIBERO_SETTING_HART1_CSR_PMPADDR3,
+ LIBERO_SETTING_HART1_CSR_PMPADDR4,
+ LIBERO_SETTING_HART1_CSR_PMPADDR5,
+ LIBERO_SETTING_HART1_CSR_PMPADDR6,
+ LIBERO_SETTING_HART1_CSR_PMPADDR7,
+ LIBERO_SETTING_HART1_CSR_PMPADDR8,
+ LIBERO_SETTING_HART1_CSR_PMPADDR9,
+ LIBERO_SETTING_HART1_CSR_PMPADDR10,
+ LIBERO_SETTING_HART1_CSR_PMPADDR11,
+ LIBERO_SETTING_HART1_CSR_PMPADDR12,
+ LIBERO_SETTING_HART1_CSR_PMPADDR13,
+ LIBERO_SETTING_HART1_CSR_PMPADDR14,
+ LIBERO_SETTING_HART1_CSR_PMPADDR15},
+ /* hart 2 */
+ {LIBERO_SETTING_HART2_CSR_PMPCFG0,
+ LIBERO_SETTING_HART2_CSR_PMPCFG2,
+ LIBERO_SETTING_HART2_CSR_PMPADDR0,
+ LIBERO_SETTING_HART2_CSR_PMPADDR1,
+ LIBERO_SETTING_HART2_CSR_PMPADDR2,
+ LIBERO_SETTING_HART2_CSR_PMPADDR3,
+ LIBERO_SETTING_HART2_CSR_PMPADDR4,
+ LIBERO_SETTING_HART2_CSR_PMPADDR5,
+ LIBERO_SETTING_HART2_CSR_PMPADDR6,
+ LIBERO_SETTING_HART2_CSR_PMPADDR7,
+ LIBERO_SETTING_HART2_CSR_PMPADDR8,
+ LIBERO_SETTING_HART2_CSR_PMPADDR9,
+ LIBERO_SETTING_HART2_CSR_PMPADDR10,
+ LIBERO_SETTING_HART2_CSR_PMPADDR11,
+ LIBERO_SETTING_HART2_CSR_PMPADDR12,
+ LIBERO_SETTING_HART2_CSR_PMPADDR13,
+ LIBERO_SETTING_HART2_CSR_PMPADDR14,
+ LIBERO_SETTING_HART2_CSR_PMPADDR15},
+ /* hart 3 */
+ {LIBERO_SETTING_HART3_CSR_PMPCFG0,
+ LIBERO_SETTING_HART3_CSR_PMPCFG2,
+ LIBERO_SETTING_HART3_CSR_PMPADDR0,
+ LIBERO_SETTING_HART3_CSR_PMPADDR1,
+ LIBERO_SETTING_HART3_CSR_PMPADDR2,
+ LIBERO_SETTING_HART3_CSR_PMPADDR3,
+ LIBERO_SETTING_HART3_CSR_PMPADDR4,
+ LIBERO_SETTING_HART3_CSR_PMPADDR5,
+ LIBERO_SETTING_HART3_CSR_PMPADDR6,
+ LIBERO_SETTING_HART3_CSR_PMPADDR7,
+ LIBERO_SETTING_HART3_CSR_PMPADDR8,
+ LIBERO_SETTING_HART3_CSR_PMPADDR9,
+ LIBERO_SETTING_HART3_CSR_PMPADDR10,
+ LIBERO_SETTING_HART3_CSR_PMPADDR11,
+ LIBERO_SETTING_HART3_CSR_PMPADDR12,
+ LIBERO_SETTING_HART3_CSR_PMPADDR13,
+ LIBERO_SETTING_HART3_CSR_PMPADDR14,
+ LIBERO_SETTING_HART3_CSR_PMPADDR15},
+ /* hart 4 */
+ {LIBERO_SETTING_HART4_CSR_PMPCFG0,
+ LIBERO_SETTING_HART4_CSR_PMPCFG2,
+ LIBERO_SETTING_HART4_CSR_PMPADDR0,
+ LIBERO_SETTING_HART4_CSR_PMPADDR1,
+ LIBERO_SETTING_HART4_CSR_PMPADDR2,
+ LIBERO_SETTING_HART4_CSR_PMPADDR3,
+ LIBERO_SETTING_HART4_CSR_PMPADDR4,
+ LIBERO_SETTING_HART4_CSR_PMPADDR5,
+ LIBERO_SETTING_HART4_CSR_PMPADDR6,
+ LIBERO_SETTING_HART4_CSR_PMPADDR7,
+ LIBERO_SETTING_HART4_CSR_PMPADDR8,
+ LIBERO_SETTING_HART4_CSR_PMPADDR9,
+ LIBERO_SETTING_HART4_CSR_PMPADDR10,
+ LIBERO_SETTING_HART4_CSR_PMPADDR11,
+ LIBERO_SETTING_HART4_CSR_PMPADDR12,
+ LIBERO_SETTING_HART4_CSR_PMPADDR13,
+ LIBERO_SETTING_HART4_CSR_PMPADDR14,
+ LIBERO_SETTING_HART4_CSR_PMPADDR15},
+};
+
+/**
+ * pmp_configure()
+ * Set PMP's up with configuration from Libero
+ * @param hart_id hart Id
+ * @return
+ */
+uint8_t pmp_configure(uint8_t hart_id) /* set-up with settings from Libero */
+{
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ uint64_t pmp0cfg;
+#endif
+ /* make sure enables are off */
+ write_csr(pmpcfg0, 0);
+ write_csr(pmpcfg2, 0);
+ /* set required addressing */
+ write_csr(pmpaddr0, pmp_values[hart_id][2]);
+ write_csr(pmpaddr1, pmp_values[hart_id][3]);
+ write_csr(pmpaddr2, pmp_values[hart_id][4]);
+ write_csr(pmpaddr3, pmp_values[hart_id][5]);
+ write_csr(pmpaddr4, pmp_values[hart_id][6]);
+ write_csr(pmpaddr5, pmp_values[hart_id][7]);
+ write_csr(pmpaddr6, pmp_values[hart_id][8]);
+ write_csr(pmpaddr7, pmp_values[hart_id][9]);
+ write_csr(pmpaddr8, pmp_values[hart_id][10]);
+ write_csr(pmpaddr9, pmp_values[hart_id][11]);
+ write_csr(pmpaddr10, pmp_values[hart_id][12]);
+ write_csr(pmpaddr11, pmp_values[hart_id][13]);
+ write_csr(pmpaddr12, pmp_values[hart_id][14]);
+ write_csr(pmpaddr13, pmp_values[hart_id][15]);
+ write_csr(pmpaddr14, pmp_values[hart_id][16]);
+ write_csr(pmpaddr15, pmp_values[hart_id][17]);
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ pmp0cfg = pmp_values[hart_id][0];
+ pmp_master_configs(hart_id, &pmp0cfg);
+ write_csr(pmpcfg0, pmp0cfg);
+ write_csr(pmpcfg2, pmp_values[hart_id][1]);
+#endif
+
+ return(0);
+}
+
+/*-------------------------------------------------------------------------*//**
+ Please note the first four PMP's are set to zero by MSS Configurator v2021.1
+ These will need to be set by the HSS. The first three relate to HSS footprint
+ The PMP4 is used to open a hole for debug region.
+
+ | PMP | cfg | L | XWR | Detail |
+ |-----|-----------|-----|----------------------------------------------------|
+ | 0 | 0x18 | N | | 256KB | Closes access for s and U mode |
+ | 1 | 0x98 | Y | X R | 256KB | Opens up area for m-mode only |
+ | 2 | 0x98 | Y | XRW | 64KB | OpenSBI scratch per scratch |
+ | 3 | 0x98 | Y | XRW | 4KB | Open window for debug |
+ | .. | .. | .. | .. | .. | .. |
+ | 15 | 0x18 | Y | | - | Close everything not opened |
+
+ @param pmp0cfg return with config for first four PMP's
+
+ */
+__attribute__((weak)) void pmp_master_configs(uint8_t hart_id, uint64_t * pmp0cfg)
+{
+ if ( hart_id == 0U )
+ {
+ *pmp0cfg = LIBERO_SETTING_HART0_CSR_PMPCFG0;
+ write_csr(pmpaddr0, pmp_values[hart_id][2]);
+ write_csr(pmpaddr1, pmp_values[hart_id][3]);
+ write_csr(pmpaddr2, pmp_values[hart_id][4]);
+ write_csr(pmpaddr3, pmp_values[hart_id][5]);
+ }
+ else
+ {
+ /*
+ * Example of closed memory map, must be created based on HSS footprint
+ */
+#define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG0 0x2007FFFULL /* 256K LIM */
+#define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG1 0x200FFFFULL /* 512K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_LIM_EG0 0x2007FFFULL /* 256K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_LIM_EG1 0x200FFFFULL /* 512K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG 0x280FFFFULL /* 512K SCRATCHPAD */
+#define OPEN_CONTEXT_ACCESS_LIM_PMP2_H1 0x2011FFFULL /* 64K LIM */
+#define OPEN_CONTEXT_ACCESS_LIM_PMP2_H2 0x2015FFFULL /* 64K LIM */
+#define OPEN_DEBUG_ACCESS_PMP3 0x1FFULL
+#define HSS_CLOSED_CFG_MASK ~0xFFFFFFFFULL
+#define HSS_CLOSED_CFG 0x9F9F9D18ULL
+ /*
+ * We will open 512K LIM and scratchpad in weak pmp_master_configs()
+ * for all harts.
+ */
+#define LIM_512K_FROM_BASE 0x200FFFFULL /* 512K LIM */
+#define SCRATCH_512K_FROM_BASE 0x280FFFFULL /* 512K LIM */
+ *pmp0cfg &= HSS_CLOSED_CFG_MASK;
+ *pmp0cfg |= 0x9F009F9FULL; /* open 0,1 and 3 to allow open access */
+ write_csr(pmpaddr0, OPEN_M_ACCESS_HSS_PMP1_LIM_EG1);
+ write_csr(pmpaddr1, OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG);
+ write_csr(pmpaddr2, 0ULL);
+ write_csr(pmpaddr3, OPEN_DEBUG_ACCESS_PMP3);
+ }
+
+ /*
+ *
+ */
+#define LOCAL_PMP_SETTINGS
+#ifdef LOCAL_PMP_SETTINGS
+
+#endif
+ return;
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_pmp.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_pmp.h
new file mode 100644
index 00000000..d4319a04
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_pmp.h
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_pmp.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PMP configuration using MSS configurator values.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_PMP_H
+#define MSS_PMP_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MEM_CONFIGS_ENABLED)
+#define LIBERO_SETTING_MEM_CONFIGS_ENABLED 0ULL
+/* Enabled when bit set to 1 */
+/* PMP [0:0] RW value= 0x0 */
+/* MPU [1:0] RW value= 0x0 */
+#endif
+#define PMP_ENABLED_MASK 1UL
+#define MPU_ENABLED_MASK 2UL
+
+/*
+ * Bit offsets associated with LIBERO_SETTING_CONTEXT_A_HART_EN and
+ * LIBERO_SETTING_CONTEXT_B_HART_EN
+ */
+#define CONTEXT_EN_MASK_MMUART0 (1U<<0)
+#define CONTEXT_EN_MASK_MMUART1 (1U<<1)
+#define CONTEXT_EN_MASK_MMUART2 (1U<<2)
+#define CONTEXT_EN_MASK_MMUART3 (1U<<3)
+#define CONTEXT_EN_MASK_MMUART4 (1U<<4)
+#define CONTEXT_EN_MASK_WDOG0 (1U<<5)
+#define CONTEXT_EN_MASK_WDOG1 (1U<<6)
+#define CONTEXT_EN_MASK_WDOG2 (1U<<7)
+#define CONTEXT_EN_MASK_WDOG3 (1U<<8)
+#define CONTEXT_EN_MASK_WDOG4 (1U<<9)
+#define CONTEXT_EN_MASK_SPI0 (1U<<10)
+#define CONTEXT_EN_MASK_SPI1 (1U<<11)
+#define CONTEXT_EN_MASK_I2C0 (1U<<12)
+#define CONTEXT_EN_MASK_I2C1 (1U<<13)
+#define CONTEXT_EN_MASK_CAN0 (1U<<14)
+#define CONTEXT_EN_MASK_CAN1 (1U<<15)
+#define CONTEXT_EN_MASK_MAC0 (1U<<16)
+#define CONTEXT_EN_MASK_MAC1 (1U<<17)
+#define CONTEXT_EN_MASK_TIMER (1U<<18)
+#define CONTEXT_EN_MASK_GPIO0 (1U<<19)
+#define CONTEXT_EN_MASK_GPIO1 (1U<<20)
+#define CONTEXT_EN_MASK_GPIO2 (1U<<21)
+#define CONTEXT_EN_MASK_RTC (1U<<22)
+#define CONTEXT_EN_MASK_H2FINT (1U<<23)
+#define CONTEXT_EN_MASK_CRYPTO (1U<<24)
+#define CONTEXT_EN_MASK_USB (1U<<25)
+#define CONTEXT_EN_MASK_QSPIXIP (1U<<26)
+#define CONTEXT_EN_MASK_ATHENA (1U<<27)
+#define CONTEXT_EN_MASK_TRACE (1U<<28)
+#define CONTEXT_EN_MASK_MAILBOX_SC (1U<<29)
+#define CONTEXT_EN_MASK_MMC (1U<<30)
+#define CONTEXT_EN_MASK_CFM (1U<<31)
+
+/*
+ * Bit offsets associated with LIBERO_SETTING_CONTEXT_A_FIC_EN and
+ * LIBERO_SETTING_CONTEXT_B_FIC_EN
+ */
+#define CONTEXT_EN_MASK_FIC0 (1U<<0)
+#define CONTEXT_EN_MASK_FIC1 (1U<<1)
+#define CONTEXT_EN_MASK_FIC2 (1U<<2)
+#define CONTEXT_EN_MASK_FIC3 (1U<<3)
+
+
+uint8_t pmp_configure(uint8_t hart_id);
+void pmp_master_configs(uint8_t hart_id, uint64_t * pmp0cfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_PMP_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_seg.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_seg.h
new file mode 100644
index 00000000..32534501
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_seg.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ *
+ * @file mss_seg.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief segmentation block defines
+ *
+ * These blocks allow the DDR memory to be allocated to cached, non-cached
+ * regions and trace depending on the amount of DDR memory physically connected.
+ * Conceptually an address offset is added/subtracted from the DDR address
+ * provided by the Core Complex to point at a base address in the DDR memory.
+ *
+ * The AXI bus simply passes through the segmentation block, and the address
+ * is modified.
+ *
+ * There are two segmentation blocks, they are grouped into the same address
+ * ranges as the MPU blocks. Each one has seven 32-segmentation registers, but
+ * only two in SEG0 and five in SEG1 are actually implemented.
+ *
+ * DDRC blocker - blocks writes to DDR before it is set-up
+ * SEG0.CFG[7]
+ * Is cleared at reset. When written to '1' disables the blocker function
+ * Is allowing the L2 cache controller to access the DDRC.
+ * Is Once written to '1' the register cannot be written to 0, only an MSS reset
+ * Is will clear the register
+ *
+ */
+
+#ifndef MSS_SEG_H
+#define MSS_SEG_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ union {
+ struct {
+ volatile int32_t offset : 15;
+ volatile int32_t rsrvd : 16;
+ volatile int32_t locked : 1;
+ } CFG;
+ uint32_t raw;
+ } u[8u];
+
+ uint32_t fill[64U-8U];
+
+} seg_t;
+
+#define SEG ((seg_t*) 0x20005d00)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MSS_SEG_H*/
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_sysreg.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_sysreg.h
new file mode 100644
index 00000000..7a255e25
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_sysreg.h
@@ -0,0 +1,4069 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/**************************************************************************
+ *
+ * @file mss_sysreg.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Hardware register definitions.
+
+ *
+ */
+#ifndef MSS_SYSREG_H
+#define MSS_SYSREG_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* IO definitions (access restrictions to peripheral registers) */
+ /**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+ IO Type Qualifiers are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+
+ */
+#ifndef __I
+ #ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permis
+ sions */
+ #else
+ #define __I volatile const /*!< Defines 'read only' permis
+ sions */
+ #endif
+#endif
+#ifndef __O
+ #define __O volatile /*!< Defines 'write only' permi
+ ssions */
+#endif
+#ifndef __IO
+ #define __IO volatile /*!< Defines 'read / write' per
+ missions */
+#endif
+ /* following defines should be used for structure members */
+#ifndef __IM
+ #define __IM volatile const /*! Defines 'read only' structu
+ re member permissions */
+#endif
+#ifndef __OM
+ #define __OM volatile /*! Defines 'write only' struct
+ ure member permissions */
+#endif
+#ifndef __IOM
+ #define __IOM volatile /*! Defines 'read / write' stru
+ cture member permissions */
+#endif
+
+/* Defines all Top Register offsets*/
+/* Date of Source Revision File: 12-Jul-18*/
+/* PROTOCOL=MSS; BASE=32'h20012000*/
+/* Hardware Base Address*/
+#define BASE32_ADDR_MSS_SYSREG 0x20002000
+
+
+/*Register for software use*/
+#define TEMP0_OFFSET 0x0
+ /* Scratch register for CPUS*/
+ #define TEMP0_DATA_OFFSET 0x0
+ #define TEMP0_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Register for software use*/
+#define TEMP1_OFFSET 0x4
+ /* Scratch register for CPUS*/
+ #define TEMP1_DATA_OFFSET 0x0
+ #define TEMP1_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Master clock configuration*/
+#define CLOCK_CONFIG_CR_OFFSET 0x8
+ /* "Sets the master synchronous clock divider bits [1:0] CPU clock divi
+ der (Reset=/1 =0)bits [3:2] AXI clock divider (Reset=/
+ 1 =0)bits [5:4] AHB/APB clock divider (Reset=/2 =1)00=/1 01=/2 10=/4 11
+ =/8 (AHB/APB divider may not be set to /1)Note at reset MSS corner clock i
+ s 80MHz therefore divider is set to divide by 1"*/
+ #define CLOCK_CONFIG_CR_DIVIDER_OFFSET 0x0
+ #define CLOCK_CONFIG_CR_DIVIDER_MASK (0x3F << 0x0)
+ /* When '1' requests G5_control to enable the 1mHz (2MHz) on-chip oscil
+ lator*/
+ #define CLOCK_CONFIG_CR_ENABLE_1MHZ_OFFSET 0x8
+ #define CLOCK_CONFIG_CR_ENABLE_1MHZ_MASK (0x01 << 0x8)
+
+/*RTC clock divider*/
+#define RTC_CLOCK_CR_OFFSET 0xC
+ /* "Sets the division ratio to create the internal RTC clock from the
+ reference clock. The defaults sets the reference clock to 1MHz assuming the
+ reference clock is 100Mhz.If the reference clock is 125MHz then 125 will c
+ reate a 1MHz clockMax divider value is 4095 and value must be an integer.RT
+ C clock must be less 2X the AXI clock rate."*/
+ #define RTC_CLOCK_CR_PERIOD_OFFSET 0x0
+ #define RTC_CLOCK_CR_PERIOD_MASK (0xFFF << 0x0)
+ /* RTC Clock enable. When chaning the divider the enable should be trur
+ ned off first the divider changed and the enable turned back on.*/
+ #define RTC_CLOCK_CR_ENABLE_OFFSET 0x10
+ #define RTC_CLOCK_CR_ENABLE_MASK (0x01 << 0x10)
+
+/*Fabric Reset mask*/
+#define FABRIC_RESET_CR_OFFSET 0x10
+ /* Blocks the fabric Reset input preventing the fabric reseting the MSS
+ */
+ #define FABRIC_RESET_CR_ENABLE_OFFSET 0x0
+ #define FABRIC_RESET_CR_ENABLE_MASK (0x01 << 0x0)
+
+/**/
+#define BOOT_FAIL_CR_OFFSET 0x14
+ /* Written by firmware to indicate that the boot process failed drives
+ the fab_boot_fail signal to the fabric. Is cleared by the fabric asserting
+ fab_boot_fail_clear*/
+ #define BOOT_FAIL_CR_BOOT_OFFSET 0x0
+ #define BOOT_FAIL_CR_BOOT_MASK (0x01 << 0x0)
+
+/*Configuration lock*/
+#define CONFIG_LOCK_CR_OFFSET 0x1C
+ /* When written to '1' will cause all RWC registers to lock until a mas
+ ter reset occurs.*/
+ #define CONFIG_LOCK_CR_LOCK_OFFSET 0x0
+ #define CONFIG_LOCK_CR_LOCK_MASK (0x01 << 0x0)
+
+/*Indicates which reset caused the last reset. After a reset occurs registe
+ r should be read and then zero written to allow the next reset event to be
+ correctly captured.*/
+#define RESET_SR_OFFSET 0x20
+ /* Reset was caused by the SCB periphery reset signal*/
+ #define RESET_SR_SCB_PERIPH_RESET_OFFSET 0x0
+ #define RESET_SR_SCB_PERIPH_RESET_MASK (0x01 << 0x0)
+ /* Reset was caused by the SCB MSS reset register*/
+ #define RESET_SR_SCB_MSS_RESET_OFFSET 0x1
+ #define RESET_SR_SCB_MSS_RESET_MASK (0x01 << 0x1)
+ /* Reset was caused by the SCB CPU reset register*/
+ #define RESET_SR_SCB_CPU_RESET_OFFSET 0x2
+ #define RESET_SR_SCB_CPU_RESET_MASK (0x01 << 0x2)
+ /* Reset was caused by the Risc-V Debugger*/
+ #define RESET_SR_DEBUGER_RESET_OFFSET 0x3
+ #define RESET_SR_DEBUGER_RESET_MASK (0x01 << 0x3)
+ /* Reset was caused by the fabric*/
+ #define RESET_SR_FABRIC_RESET_OFFSET 0x4
+ #define RESET_SR_FABRIC_RESET_MASK (0x01 << 0x4)
+ /* Reset was caused by the watchdog*/
+ #define RESET_SR_WDOG_RESET_OFFSET 0x5
+ #define RESET_SR_WDOG_RESET_MASK (0x01 << 0x5)
+ /* Indicates that fabric asserted the GPIO reset inputs*/
+ #define RESET_SR_GPIO_RESET_OFFSET 0x6
+ #define RESET_SR_GPIO_RESET_MASK (0x01 << 0x6)
+ /* Indicates that SCB bus reset occurred (which causes warm reset of MS
+ S)*/
+ #define RESET_SR_SCB_BUS_RESET_OFFSET 0x7
+ #define RESET_SR_SCB_BUS_RESET_MASK (0x01 << 0x7)
+
+/*Indicates the device status in particular the state of the FPGA fabric an
+ d the MSS IO banks*/
+#define DEVICE_STATUS_OFFSET 0x24
+ /* Indicates the status of the core_up input from G5 Control.*/
+ #define DEVICE_STATUS_CORE_UP_OFFSET 0x0
+ #define DEVICE_STATUS_CORE_UP_MASK (0x01 << 0x0)
+ /* Indicates the status of the lp_state input from G5 Control.*/
+ #define DEVICE_STATUS_LP_STATE_OFFSET 0x1
+ #define DEVICE_STATUS_LP_STATE_MASK (0x01 << 0x1)
+ /* Indicates the status of the ff_in_progress input from G5 Control.*/
+ #define DEVICE_STATUS_FF_IN_PROGRESS_OFFSET 0x2
+ #define DEVICE_STATUS_FF_IN_PROGRESS_MASK (0x01 << 0x2)
+ /* Indicates the status of the flash_valid input from G5 Control.*/
+ #define DEVICE_STATUS_FLASH_VALID_OFFSET 0x3
+ #define DEVICE_STATUS_FLASH_VALID_MASK (0x01 << 0x3)
+ /* Power status of IO bank 2*/
+ #define DEVICE_STATUS_IO_BANK_B2_STATUS_OFFSET 0x8
+ #define DEVICE_STATUS_IO_BANK_B2_STATUS_MASK (0x01 << 0x8)
+ /* Power status of IO bank 4*/
+ #define DEVICE_STATUS_IO_BANK_B4_STATUS_OFFSET 0x9
+ #define DEVICE_STATUS_IO_BANK_B4_STATUS_MASK (0x01 << 0x9)
+ /* Power status of IO bank 5*/
+ #define DEVICE_STATUS_IO_BANK_B5_STATUS_OFFSET 0xA
+ #define DEVICE_STATUS_IO_BANK_B5_STATUS_MASK (0x01 << 0xA)
+ /* Power status of IO bank 6*/
+ #define DEVICE_STATUS_IO_BANK_B6_STATUS_OFFSET 0xB
+ #define DEVICE_STATUS_IO_BANK_B6_STATUS_MASK (0x01 << 0xB)
+ /* Indicates the status of the io_en input from G5 Control.*/
+ #define DEVICE_STATUS_IO_EN_OFFSET 0xC
+ #define DEVICE_STATUS_IO_EN_MASK (0x01 << 0xC)
+
+/*MSS Build Info*/
+#define MSS_BUILD_OFFSET 0x28
+ #define MSS_BUILD_REVISION_OFFSET 0x0
+ #define MSS_BUILD_REVISION_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-1 Fabric interrupt enable*/
+#define FAB_INTEN_U54_1_OFFSET 0x40
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_1_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_1_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-2 Fabric interrupt enable*/
+#define FAB_INTEN_U54_2_OFFSET 0x44
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_2_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_2_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-3 Fabric interrupt enable*/
+#define FAB_INTEN_U54_3_OFFSET 0x48
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_3_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_3_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-4 Fabric interrupt enable*/
+#define FAB_INTEN_U54_4_OFFSET 0x4C
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_4_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_4_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*Allows the Ethernat interrupts to be directly routed to the U54 CPUS.*/
+#define FAB_INTEN_MISC_OFFSET 0x50
+ /* Enables the Ethernet MAC0 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC0_U54_1_OFFSET 0x0
+ #define FAB_INTEN_MISC_MAC0_U54_1_MASK (0x01 << 0x0)
+ /* Enables the Ethernet MAC0 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC0_U54_2_OFFSET 0x1
+ #define FAB_INTEN_MISC_MAC0_U54_2_MASK (0x01 << 0x1)
+ /* Enables the Ethernet MAC1 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC1_U54_3_OFFSET 0x2
+ #define FAB_INTEN_MISC_MAC1_U54_3_MASK (0x01 << 0x2)
+ /* Enables the Ethernet MAC1 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC1_U54_4_OFFSET 0x3
+ #define FAB_INTEN_MISC_MAC1_U54_4_MASK (0x01 << 0x3)
+
+/*Switches GPIO interrupt from PAD to Fabric GPIO*/
+#define GPIO_INTERRUPT_FAB_CR_OFFSET 0x54
+ /* Setting these bits will disable the Pad interrupt and enable the fabric
+ GPIO interrupt for bits 31:0. When the bit is set the Pad interrupt will
+ be ORED into the GPIO0 & GPIO1 non-direct interrupts. When the bit is
+ not set the Fabric interrupt is ORED into the GPIO2 non-direct interrupt.
+ To prevent ORING then the interrupt should not be enabled in the GPIO block
+ */
+ #define GPIO_INTERRUPT_FAB_CR_SELECT_OFFSET 0x0
+ #define GPIO_INTERRUPT_FAB_CR_SELECT_MASK (0xFFFFFFFF << 0x0)
+
+/*"AMP Mode peripheral mapping register. When the register bit is '0' the p
+ eripheral is mapped into the 0x2000000 address range using AXI bus 5 from t
+ he Coreplex. When the register bit is '1' the peripheral is mapped into the
+ 0x28000000 address range using AXI bus 6 from the Coreplex."*/
+#define APBBUS_CR_OFFSET 0x80
+ /* */
+ #define APBBUS_CR_MMUART0_OFFSET 0x0
+ #define APBBUS_CR_MMUART0_MASK (0x01 << 0x0)
+ /* */
+ #define APBBUS_CR_MMUART1_OFFSET 0x1
+ #define APBBUS_CR_MMUART1_MASK (0x01 << 0x1)
+ /* */
+ #define APBBUS_CR_MMUART2_OFFSET 0x2
+ #define APBBUS_CR_MMUART2_MASK (0x01 << 0x2)
+ /* */
+ #define APBBUS_CR_MMUART3_OFFSET 0x3
+ #define APBBUS_CR_MMUART3_MASK (0x01 << 0x3)
+ /* */
+ #define APBBUS_CR_MMUART4_OFFSET 0x4
+ #define APBBUS_CR_MMUART4_MASK (0x01 << 0x4)
+ /* */
+ #define APBBUS_CR_WDOG0_OFFSET 0x5
+ #define APBBUS_CR_WDOG0_MASK (0x01 << 0x5)
+ /* */
+ #define APBBUS_CR_WDOG1_OFFSET 0x6
+ #define APBBUS_CR_WDOG1_MASK (0x01 << 0x6)
+ /* */
+ #define APBBUS_CR_WDOG2_OFFSET 0x7
+ #define APBBUS_CR_WDOG2_MASK (0x01 << 0x7)
+ /* */
+ #define APBBUS_CR_WDOG3_OFFSET 0x8
+ #define APBBUS_CR_WDOG3_MASK (0x01 << 0x8)
+ /* */
+ #define APBBUS_CR_WDOG4_OFFSET 0x9
+ #define APBBUS_CR_WDOG4_MASK (0x01 << 0x9)
+ /* */
+ #define APBBUS_CR_SPI0_OFFSET 0xA
+ #define APBBUS_CR_SPI0_MASK (0x01 << 0xA)
+ /* */
+ #define APBBUS_CR_SPI1_OFFSET 0xB
+ #define APBBUS_CR_SPI1_MASK (0x01 << 0xB)
+ /* */
+ #define APBBUS_CR_I2C0_OFFSET 0xC
+ #define APBBUS_CR_I2C0_MASK (0x01 << 0xC)
+ /* */
+ #define APBBUS_CR_I2C1_OFFSET 0xD
+ #define APBBUS_CR_I2C1_MASK (0x01 << 0xD)
+ /* */
+ #define APBBUS_CR_CAN0_OFFSET 0xE
+ #define APBBUS_CR_CAN0_MASK (0x01 << 0xE)
+ /* */
+ #define APBBUS_CR_CAN1_OFFSET 0xF
+ #define APBBUS_CR_CAN1_MASK (0x01 << 0xF)
+ /* */
+ #define APBBUS_CR_GEM0_OFFSET 0x10
+ #define APBBUS_CR_GEM0_MASK (0x01 << 0x10)
+ /* */
+ #define APBBUS_CR_GEM1_OFFSET 0x11
+ #define APBBUS_CR_GEM1_MASK (0x01 << 0x11)
+ /* */
+ #define APBBUS_CR_TIMER_OFFSET 0x12
+ #define APBBUS_CR_TIMER_MASK (0x01 << 0x12)
+ /* */
+ #define APBBUS_CR_GPIO0_OFFSET 0x13
+ #define APBBUS_CR_GPIO0_MASK (0x01 << 0x13)
+ /* */
+ #define APBBUS_CR_GPIO1_OFFSET 0x14
+ #define APBBUS_CR_GPIO1_MASK (0x01 << 0x14)
+ /* */
+ #define APBBUS_CR_GPIO2_OFFSET 0x15
+ #define APBBUS_CR_GPIO2_MASK (0x01 << 0x15)
+ /* */
+ #define APBBUS_CR_RTC_OFFSET 0x16
+ #define APBBUS_CR_RTC_MASK (0x01 << 0x16)
+ /* */
+ #define APBBUS_CR_H2FINT_OFFSET 0x17
+ #define APBBUS_CR_H2FINT_MASK (0x01 << 0x17)
+
+/*"Enables the clock to the MSS peripheral. By turning clocks off dynamic power
+ can be saved. When the clock is off the peripheral should not be accessed
+ the access may be ignored return unspecified data or result in bus response
+ error."*/
+#define SUBBLK_CLOCK_CR_OFFSET 0x84
+ /* */
+ #define SUBBLK_CLOCK_CR_ENVM_OFFSET 0x0
+ #define SUBBLK_CLOCK_CR_ENVM_MASK (0x01 << 0x0)
+ /* */
+ #define SUBBLK_CLOCK_CR_MAC0_OFFSET 0x1
+ #define SUBBLK_CLOCK_CR_MAC0_MASK (0x01 << 0x1)
+ /* */
+ #define SUBBLK_CLOCK_CR_MAC1_OFFSET 0x2
+ #define SUBBLK_CLOCK_CR_MAC1_MASK (0x01 << 0x2)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMC_OFFSET 0x3
+ #define SUBBLK_CLOCK_CR_MMC_MASK (0x01 << 0x3)
+ /* */
+ #define SUBBLK_CLOCK_CR_TIMER_OFFSET 0x4
+ #define SUBBLK_CLOCK_CR_TIMER_MASK (0x01 << 0x4)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART0_OFFSET 0x5
+ #define SUBBLK_CLOCK_CR_MMUART0_MASK (0x01 << 0x5)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART1_OFFSET 0x6
+ #define SUBBLK_CLOCK_CR_MMUART1_MASK (0x01 << 0x6)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART2_OFFSET 0x7
+ #define SUBBLK_CLOCK_CR_MMUART2_MASK (0x01 << 0x7)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART3_OFFSET 0x8
+ #define SUBBLK_CLOCK_CR_MMUART3_MASK (0x01 << 0x8)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART4_OFFSET 0x9
+ #define SUBBLK_CLOCK_CR_MMUART4_MASK (0x01 << 0x9)
+ /* */
+ #define SUBBLK_CLOCK_CR_SPI0_OFFSET 0xA
+ #define SUBBLK_CLOCK_CR_SPI0_MASK (0x01 << 0xA)
+ /* */
+ #define SUBBLK_CLOCK_CR_SPI1_OFFSET 0xB
+ #define SUBBLK_CLOCK_CR_SPI1_MASK (0x01 << 0xB)
+ /* */
+ #define SUBBLK_CLOCK_CR_I2C0_OFFSET 0xC
+ #define SUBBLK_CLOCK_CR_I2C0_MASK (0x01 << 0xC)
+ /* */
+ #define SUBBLK_CLOCK_CR_I2C1_OFFSET 0xD
+ #define SUBBLK_CLOCK_CR_I2C1_MASK (0x01 << 0xD)
+ /* */
+ #define SUBBLK_CLOCK_CR_CAN0_OFFSET 0xE
+ #define SUBBLK_CLOCK_CR_CAN0_MASK (0x01 << 0xE)
+ /* */
+ #define SUBBLK_CLOCK_CR_CAN1_OFFSET 0xF
+ #define SUBBLK_CLOCK_CR_CAN1_MASK (0x01 << 0xF)
+ /* */
+ #define SUBBLK_CLOCK_CR_USB_OFFSET 0x10
+ #define SUBBLK_CLOCK_CR_USB_MASK (0x01 << 0x10)
+ /* */
+ #define SUBBLK_CLOCK_CR_RSVD_OFFSET 0x11
+ #define SUBBLK_CLOCK_CR_RSVD_MASK (0x01 << 0x11)
+ /* */
+ #define SUBBLK_CLOCK_CR_RTC_OFFSET 0x12
+ #define SUBBLK_CLOCK_CR_RTC_MASK (0x01 << 0x12)
+ /* */
+ #define SUBBLK_CLOCK_CR_QSPI_OFFSET 0x13
+ #define SUBBLK_CLOCK_CR_QSPI_MASK (0x01 << 0x13)
+ /* */
+ #define SUBBLK_CLOCK_CR_GPIO0_OFFSET 0x14
+ #define SUBBLK_CLOCK_CR_GPIO0_MASK (0x01 << 0x14)
+ /* */
+ #define SUBBLK_CLOCK_CR_GPIO1_OFFSET 0x15
+ #define SUBBLK_CLOCK_CR_GPIO1_MASK (0x01 << 0x15)
+ /* */
+ #define SUBBLK_CLOCK_CR_GPIO2_OFFSET 0x16
+ #define SUBBLK_CLOCK_CR_GPIO2_MASK (0x01 << 0x16)
+ /* */
+ #define SUBBLK_CLOCK_CR_DDRC_OFFSET 0x17
+ #define SUBBLK_CLOCK_CR_DDRC_MASK (0x01 << 0x17)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC0_OFFSET 0x18
+ #define SUBBLK_CLOCK_CR_FIC0_MASK (0x01 << 0x18)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC1_OFFSET 0x19
+ #define SUBBLK_CLOCK_CR_FIC1_MASK (0x01 << 0x19)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC2_OFFSET 0x1A
+ #define SUBBLK_CLOCK_CR_FIC2_MASK (0x01 << 0x1A)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC3_OFFSET 0x1B
+ #define SUBBLK_CLOCK_CR_FIC3_MASK (0x01 << 0x1B)
+ /* */
+ #define SUBBLK_CLOCK_CR_ATHENA_OFFSET 0x1C
+ #define SUBBLK_CLOCK_CR_ATHENA_MASK (0x01 << 0x1C)
+ /* */
+ #define SUBBLK_CLOCK_CR_CFM_OFFSET 0x1D
+ #define SUBBLK_CLOCK_CR_CFM_MASK (0x01 << 0x1D)
+
+/*"Holds the MSS peripherals in reset. When in reset the peripheral should
+ not be accessed the acess may be ignored return unspecified data or result
+ in bus response error."*/
+#define SOFT_RESET_CR_OFFSET 0x88
+ /* */
+ #define SOFT_RESET_CR_ENVM_OFFSET 0x0
+ #define SOFT_RESET_CR_ENVM_MASK (0x01 << 0x0)
+ /* */
+ #define SOFT_RESET_CR_MAC0_OFFSET 0x1
+ #define SOFT_RESET_CR_MAC0_MASK (0x01 << 0x1)
+ /* */
+ #define SOFT_RESET_CR_MAC1_OFFSET 0x2
+ #define SOFT_RESET_CR_MAC1_MASK (0x01 << 0x2)
+ /* */
+ #define SOFT_RESET_CR_MMC_OFFSET 0x3
+ #define SOFT_RESET_CR_MMC_MASK (0x01 << 0x3)
+ /* */
+ #define SOFT_RESET_CR_TIMER_OFFSET 0x4
+ #define SOFT_RESET_CR_TIMER_MASK (0x01 << 0x4)
+ /* */
+ #define SOFT_RESET_CR_MMUART0_OFFSET 0x5
+ #define SOFT_RESET_CR_MMUART0_MASK (0x01 << 0x5)
+ /* */
+ #define SOFT_RESET_CR_MMUART1_OFFSET 0x6
+ #define SOFT_RESET_CR_MMUART1_MASK (0x01 << 0x6)
+ /* */
+ #define SOFT_RESET_CR_MMUART2_OFFSET 0x7
+ #define SOFT_RESET_CR_MMUART2_MASK (0x01 << 0x7)
+ /* */
+ #define SOFT_RESET_CR_MMUART3_OFFSET 0x8
+ #define SOFT_RESET_CR_MMUART3_MASK (0x01 << 0x8)
+ /* */
+ #define SOFT_RESET_CR_MMUART4_OFFSET 0x9
+ #define SOFT_RESET_CR_MMUART4_MASK (0x01 << 0x9)
+ /* */
+ #define SOFT_RESET_CR_SPI0_OFFSET 0xA
+ #define SOFT_RESET_CR_SPI0_MASK (0x01 << 0xA)
+ /* */
+ #define SOFT_RESET_CR_SPI1_OFFSET 0xB
+ #define SOFT_RESET_CR_SPI1_MASK (0x01 << 0xB)
+ /* */
+ #define SOFT_RESET_CR_I2C0_OFFSET 0xC
+ #define SOFT_RESET_CR_I2C0_MASK (0x01 << 0xC)
+ /* */
+ #define SOFT_RESET_CR_I2C1_OFFSET 0xD
+ #define SOFT_RESET_CR_I2C1_MASK (0x01 << 0xD)
+ /* */
+ #define SOFT_RESET_CR_CAN0_OFFSET 0xE
+ #define SOFT_RESET_CR_CAN0_MASK (0x01 << 0xE)
+ /* */
+ #define SOFT_RESET_CR_CAN1_OFFSET 0xF
+ #define SOFT_RESET_CR_CAN1_MASK (0x01 << 0xF)
+ /* */
+ #define SOFT_RESET_CR_USB_OFFSET 0x10
+ #define SOFT_RESET_CR_USB_MASK (0x01 << 0x10)
+ /* */
+ #define SOFT_RESET_CR_FPGA_OFFSET 0x11
+ #define SOFT_RESET_CR_FPGA_MASK (0x01 << 0x11)
+ /* */
+ #define SOFT_RESET_CR_RTC_OFFSET 0x12
+ #define SOFT_RESET_CR_RTC_MASK (0x01 << 0x12)
+ /* */
+ #define SOFT_RESET_CR_QSPI_OFFSET 0x13
+ #define SOFT_RESET_CR_QSPI_MASK (0x01 << 0x13)
+ /* */
+ #define SOFT_RESET_CR_GPIO0_OFFSET 0x14
+ #define SOFT_RESET_CR_GPIO0_MASK (0x01 << 0x14)
+ /* */
+ #define SOFT_RESET_CR_GPIO1_OFFSET 0x15
+ #define SOFT_RESET_CR_GPIO1_MASK (0x01 << 0x15)
+ /* */
+ #define SOFT_RESET_CR_GPIO2_OFFSET 0x16
+ #define SOFT_RESET_CR_GPIO2_MASK (0x01 << 0x16)
+ /* */
+ #define SOFT_RESET_CR_DDRC_OFFSET 0x17
+ #define SOFT_RESET_CR_DDRC_MASK (0x01 << 0x17)
+ /* */
+ #define SOFT_RESET_CR_FIC0_OFFSET 0x18
+ #define SOFT_RESET_CR_FIC0_MASK (0x01 << 0x18)
+ /* */
+ #define SOFT_RESET_CR_FIC1_OFFSET 0x19
+ #define SOFT_RESET_CR_FIC1_MASK (0x01 << 0x19)
+ /* */
+ #define SOFT_RESET_CR_FIC2_OFFSET 0x1A
+ #define SOFT_RESET_CR_FIC2_MASK (0x01 << 0x1A)
+ /* */
+ #define SOFT_RESET_CR_FIC3_OFFSET 0x1B
+ #define SOFT_RESET_CR_FIC3_MASK (0x01 << 0x1B)
+ /* */
+ #define SOFT_RESET_CR_ATHENA_OFFSET 0x1C
+ #define SOFT_RESET_CR_ATHENA_MASK (0x01 << 0x1C)
+ /* */
+ #define SOFT_RESET_CR_CFM_OFFSET 0x1D
+ #define SOFT_RESET_CR_CFM_MASK (0x01 << 0x1D)
+ /* Reset to Corner SGMII block*/
+ #define SOFT_RESET_CR_SGMII_OFFSET 0x1E
+ #define SOFT_RESET_CR_SGMII_MASK (0x01 << 0x1E)
+
+/*Configures how many outstanding transfers the AXI-AHB bridges in front of
+ f the USB and Crypto blocks should allow. (See Synopsys AXI-AHB bridge docu
+ mentation)*/
+#define AHBAXI_CR_OFFSET 0x8C
+ /* Number of outstanding write transactions to USB block*/
+ #define AHBAXI_CR_USB_WBCNT_OFFSET 0x0
+ #define AHBAXI_CR_USB_WBCNT_MASK (0x0F << 0x0)
+ /* Number of outstanding read transactions to USB block*/
+ #define AHBAXI_CR_USB_RBCNT_OFFSET 0x4
+ #define AHBAXI_CR_USB_RBCNT_MASK (0x0F << 0x4)
+ /* Number of outstanding write transactions to Athena block*/
+ #define AHBAXI_CR_ATHENA_WBCNT_OFFSET 0x8
+ #define AHBAXI_CR_ATHENA_WBCNT_MASK (0x0F << 0x8)
+ /* Number of outstanding read transactions to Athena block*/
+ #define AHBAXI_CR_ATHENA_RBCNT_OFFSET 0xC
+ #define AHBAXI_CR_ATHENA_RBCNT_MASK (0x0F << 0xC)
+
+/*Configures the two AHB-APB bridges on S5 and S6*/
+#define AHBAPB_CR_OFFSET 0x90
+ /* Enables posted mode on the AHB-APB bridge when set the AHB write cyc
+ le will complete before the APB write cycle completes.*/
+ #define AHBAPB_CR_APB0_POSTED_OFFSET 0x0
+ #define AHBAPB_CR_APB0_POSTED_MASK (0x01 << 0x0)
+ /* Enables posted mode on the AHB-APB bridge when set the AHB write cyc
+ le will complete before the APB write cycle completes.*/
+ #define AHBAPB_CR_APB1_POSTED_OFFSET 0x1
+ #define AHBAPB_CR_APB1_POSTED_MASK (0x01 << 0x1)
+
+/*MSS Corner APB interface controls*/
+#define DFIAPB_CR_OFFSET 0x98
+ /* Turns on the APB clock to the MSS Corner is off at reset. Once corne
+ r blocks is configured the firmware may turn off the clock but periodically
+ should turn back on to allow refresh of TMR registers inside the corner bl
+ ock. */
+ #define DFIAPB_CR_CLOCKON_OFFSET 0x0
+ #define DFIAPB_CR_CLOCKON_MASK (0x01 << 0x0)
+ /* Asserts the APB reset to the MSS corner is asserted at MSS reset.*/
+ #define DFIAPB_CR_RESET_OFFSET 0x1
+ #define DFIAPB_CR_RESET_MASK (0x01 << 0x1)
+
+/*GPIO Blocks reset control*/
+#define GPIO_CR_OFFSET 0x9C
+ /* "This signal selects whether the associated byte is reset by soft re
+ set or the the MSS_GPIO_RESET_N signal from the FPGA fabric. The allowed va
+ lues are:* 0: Selects MSS_GPIO_RESET_N signal from the FPGA fabric.* 1
+ : Selects the GPIO to be reset by the GPIO block soft reset signal .Bit 0
+ controls GPIO0 [7:0] and bit 1 GPIO[15:8]The master MSS reset will also r
+ eset the GPIO register if not configured to use fabric reset."*/
+ #define GPIO_CR_GPIO0_SOFT_RESET_SELECT_OFFSET 0x0
+ #define GPIO_CR_GPIO0_SOFT_RESET_SELECT_MASK (0x03 << 0x0)
+ /* "Sets the reset value off the GPIO0 per byteBit 0 controls GPIO0 [7:
+ 0] and bit 1 GPIO[15:8]"*/
+ #define GPIO_CR_GPIO0_DEFAULT_OFFSET 0x4
+ #define GPIO_CR_GPIO0_DEFAULT_MASK (0x03 << 0x4)
+ /* "This signal selects whether the associated byte is reset by soft re
+ set or the the MSS_GPIO_RESET_N signal from the FPGA fabric. The allowed va
+ lues are:* 0: Selects MSS_GPIO_RESET_N signal from the FPGA fabric.* 1
+ : Selects the GPIO to be reset by the GPIO block soft reset signal .Bit 0
+ controls GPIO0 [7:0] bit 1 GPIO[15:8] and bit 2 GPIO[23:16]The master MSS
+ reset will also reset the GPIO register if not configured to use fabric res
+ et."*/
+ #define GPIO_CR_GPIO1_SOFT_RESET_SELECT_OFFSET 0x8
+ #define GPIO_CR_GPIO1_SOFT_RESET_SELECT_MASK (0x07 << 0x8)
+ /* "Sets the reset value off the GPIO0 per byteBit 0 controls GPIO0 [7:
+ 0] bit 1 GPIO[15:8] and bit 2 GPIO[23:16]"*/
+ #define GPIO_CR_GPIO1_DEFAULT_OFFSET 0xC
+ #define GPIO_CR_GPIO1_DEFAULT_MASK (0x07 << 0xC)
+ /* "This signal selects whether the associated byte is reset by soft re
+ set or the the MSS_GPIO_RESET_N signal from the FPGA fabric. The allowed va
+ lues are:* 0: Selects MSS_GPIO_RESET_N signal from the FPGA fabric.* 1
+ : Selects the GPIO to be reset by the GPIO block soft reset signal .Bit 0
+ controls GPIO0 [7:0] bit 1 GPIO[15:8] and bit 1 GPIO[23:16] and bit 3 GPIO
+ [31:24]The master MSS reset will also reset the GPIO register if not config
+ ured to use fabric reset."*/
+ #define GPIO_CR_GPIO2_SOFT_RESET_SELECT_OFFSET 0x10
+ #define GPIO_CR_GPIO2_SOFT_RESET_SELECT_MASK (0x0F << 0x10)
+ /* "Sets the reset value off the GPIO0 per byteBit 0 controls GPIO0 [7:
+ 0] bit 1 GPIO[15:8] and bit 1 GPIO[23:16] and bit 3 GPIO[31:24]"*/
+ #define GPIO_CR_GPIO2_DEFAULT_OFFSET 0x14
+ #define GPIO_CR_GPIO2_DEFAULT_MASK (0x0F << 0x14)
+
+/*MAC0 configuration register*/
+#define MAC0_CR_OFFSET 0xA4
+ /* Current speed mode on the MAC*/
+ #define MAC0_CR_SPEED_MODE_OFFSET 0x0
+ #define MAC0_CR_SPEED_MODE_MASK (0x0F << 0x0)
+
+/*MAC1 configuration register*/
+#define MAC1_CR_OFFSET 0xA8
+ /* Current speed mode on the MAC*/
+ #define MAC1_CR_SPEED_MODE_OFFSET 0x0
+ #define MAC1_CR_SPEED_MODE_MASK (0x0F << 0x0)
+
+/*USB Configuration register*/
+#define USB_CR_OFFSET 0xAC
+ /* "Configures USB for Single-Data Rate(SDR) mode or Double-Data Rate(D
+ DR) mode. 0 - SDR Mode is selected1 - DDR Mode is selected (Not supported i
+ n G5 or G5)"*/
+ #define USB_CR_DDR_SELECT_OFFSET 0x0
+ #define USB_CR_DDR_SELECT_MASK (0x01 << 0x0)
+ /* When '1' will stops the clock to the USB core when the core asserts
+ its POWERDOWN output. For G4 compatibility this bit defaults to 0.*/
+ #define USB_CR_POWERDOWN_ENABLE_OFFSET 0x1
+ #define USB_CR_POWERDOWN_ENABLE_MASK (0x01 << 0x1)
+ /* Indicates that the USB CLK may be stopped to save power. Derived fro
+ m combination of signals from CLK & XCLK flip-flops AVALID VBUSVALID and LI
+ NESTATE. When asserted the USB clock into the core is stopped.*/
+ #define USB_CR_POWERDOWN_OFFSET 0x2
+ #define USB_CR_POWERDOWN_MASK (0x01 << 0x2)
+ /* Set when entry is made into CarKit mode and cleared on exit from Car
+ Kit mode.*/
+ #define USB_CR_LPI_CARKIT_EN_OFFSET 0x3
+ #define USB_CR_LPI_CARKIT_EN_MASK (0x01 << 0x3)
+
+/*Crypto Mesh control and status register*/
+#define MESH_CR_OFFSET 0xB0
+ /* Writing a 1 will start the Mesh System*/
+ #define MESH_CR_START_OFFSET 0x0
+ #define MESH_CR_START_MASK (0x01 << 0x0)
+ /* "Sets the amount of time that the mesh is held active for actual hol
+ d time includes up to 256 us of random variation.Minimum Time = 1 + 256 * v
+ alue usMaximum Time = 1 + 256 * (1+value) usValue must be greater than
+ 0"*/
+ #define MESH_CR_HOLD_OFFSET 0x1
+ #define MESH_CR_HOLD_MASK (0xFFF << 0x1)
+ /* When set will inject an error in the mesh*/
+ #define MESH_CR_INJECT_ERROR_OFFSET 0x10
+ #define MESH_CR_INJECT_ERROR_MASK (0x01 << 0x10)
+ /* Indicates that Mesh detected an error. Cleared by writing a '1'*/
+ #define MESH_CR_MESH_ERROR_OFFSET 0x18
+ #define MESH_CR_MESH_ERROR_MASK (0x01 << 0x18)
+ /* Indicates that the Mesh is functioning correctly. Will be set approx
+ imately 520 clock cycles after mesh started and stay set as long as the me
+ sh is not detecting any errors.*/
+ #define MESH_CR_OKAY_OFFSET 0x19
+ #define MESH_CR_OKAY_MASK (0x01 << 0x19)
+
+/*Crypto mesh seed and update rate*/
+#define MESH_SEED_CR_OFFSET 0xB4
+ /* Sets the mesh seed value any value may be used zero should be avoide
+ d*/
+ #define MESH_SEED_CR_SEED_OFFSET 0x0
+ #define MESH_SEED_CR_SEED_MASK (0x7FFFFF << 0x0)
+ /* Sets the rate that the mesh value is changed. Rate = AHBCLK/(clkrate
+ +1). Rate must be less than 1MHz setting slower will reduce power consumpti
+ on.*/
+ #define MESH_SEED_CR_CLKRATE_OFFSET 0x18
+ #define MESH_SEED_CR_CLKRATE_MASK (0xFF << 0x18)
+
+/*ENVM AHB Controller setup*/
+#define ENVM_CR_OFFSET 0xB8
+ /* "Sets the number of AHB cycles used to generate the PNVM clockClock
+ period = (Value+1) * (1000/AHBFREQMHZ) Value must be 1 to 63 (0
+ defaults to 15)e.g.11 will generate a 40ns period 25MHz clock if the AHB
+ clock is 250MHz15 will generate a 40ns period 25MHz clock if the AHB cloc
+ k is 400MHz"*/
+ #define ENVM_CR_CLOCK_PERIOD_OFFSET 0x0
+ #define ENVM_CR_CLOCK_PERIOD_MASK (0x3F << 0x0)
+ /* Indicates the eNVM is running at the configured divider rate. */
+ #define ENVM_CR_CLOCK_OKAY_OFFSET 0x6
+ #define ENVM_CR_CLOCK_OKAY_MASK (0x01 << 0x6)
+ /* When '1' the PNVM clock will be always generated and not stopped bet
+ ween access cycles. Setting this will increase access latency but mean that
+ the PNVM clock operates at a stable rate.*/
+ #define ENVM_CR_CLOCK_CONTINUOUS_OFFSET 0x8
+ #define ENVM_CR_CLOCK_CONTINUOUS_MASK (0x01 << 0x8)
+ /* When set suppresses clock edge between C-Bus access cycles so that t
+ hey appear as consecutive access cycles.*/
+ #define ENVM_CR_CLOCK_SUPPRESS_OFFSET 0x9
+ #define ENVM_CR_CLOCK_SUPPRESS_MASK (0x01 << 0x9)
+ /* "Enables ""read-ahead"" on the ENVM controller. The controller will
+ automatically read the next PNVM location as soon as possible ahead of the
+ AHB request. This will improve read performance when incrementing though
+ memory as the NVM reads and AHB cycles are pipelined. When set non incrementing
+ accesses will take longer as the controller may be in the process of reading
+ the next address and the PNVM cycle needs to complete prior to starting
+ the required read"*/
+ #define ENVM_CR_READAHEAD_OFFSET 0x10
+ #define ENVM_CR_READAHEAD_MASK (0x01 << 0x10)
+ /* When '1' the controller will initiate separate ENVM reads for all reads.
+ No buffering or speculative operations will be carried out. When performing
+ word reads incrementing through PNVM each location will be read twice
+ (intended for test use)*/
+ #define ENVM_CR_SLOWREAD_OFFSET 0x11
+ #define ENVM_CR_SLOWREAD_MASK (0x01 << 0x11)
+ /* Enable the ENVM interrupt*/
+ #define ENVM_CR_INTERRUPT_ENABLE_OFFSET 0x12
+ #define ENVM_CR_INTERRUPT_ENABLE_MASK (0x01 << 0x12)
+ /* "Sets the duration of the timer used to detect a non response of slow
+ response from the PNVM on C and R bus accesses.Timer Duration = Value *
+ (1000/AHBFREQMHZ) 0x00: Timer disabled. If the timer expires the AHB cycle
+ is terminates using the HRESP protocol"*/
+ #define ENVM_CR_TIMER_OFFSET 0x18
+ #define ENVM_CR_TIMER_MASK (0xFF << 0x18)
+
+/*Reserved*/
+#define RESERVED_BC_OFFSET 0xBC
+ /* Reserved register address*/
+ #define RESERVED_BC_RESERVED_OFFSET 0x0
+ #define RESERVED_BC_RESERVED_MASK (0x01 << 0x0)
+
+/*QOS Athena USB & MMC Configuration*/
+#define QOS_PERIPHERAL_CR_OFFSET 0xC0
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_ATHENA_READ_OFFSET 0x0
+ #define QOS_PERIPHERAL_CR_ATHENA_READ_MASK (0x0F << 0x0)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_ATHENA_WRITE_OFFSET 0x4
+ #define QOS_PERIPHERAL_CR_ATHENA_WRITE_MASK (0x0F << 0x4)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_USB_READ_OFFSET 0x8
+ #define QOS_PERIPHERAL_CR_USB_READ_MASK (0x0F << 0x8)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_USB_WRITE_OFFSET 0xC
+ #define QOS_PERIPHERAL_CR_USB_WRITE_MASK (0x0F << 0xC)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_MMC_READ_OFFSET 0x10
+ #define QOS_PERIPHERAL_CR_MMC_READ_MASK (0x0F << 0x10)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_MMC_WRITE_OFFSET 0x14
+ #define QOS_PERIPHERAL_CR_MMC_WRITE_MASK (0x0F << 0x14)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_TRACE_READ_OFFSET 0x18
+ #define QOS_PERIPHERAL_CR_TRACE_READ_MASK (0x0F << 0x18)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_TRACE_WRITE_OFFSET 0x1C
+ #define QOS_PERIPHERAL_CR_TRACE_WRITE_MASK (0x0F << 0x1C)
+
+/*QOS Configuration Coreplex*/
+#define QOS_CPLEXIO_CR_OFFSET 0xC4
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE0_READ_OFFSET 0x0
+ #define QOS_CPLEXIO_CR_DEVICE0_READ_MASK (0x0F << 0x0)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE0_WRITE_OFFSET 0x4
+ #define QOS_CPLEXIO_CR_DEVICE0_WRITE_MASK (0x0F << 0x4)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE1_READ_OFFSET 0x8
+ #define QOS_CPLEXIO_CR_DEVICE1_READ_MASK (0x0F << 0x8)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE1_WRITE_OFFSET 0xC
+ #define QOS_CPLEXIO_CR_DEVICE1_WRITE_MASK (0x0F << 0xC)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC0_READ_OFFSET 0x10
+ #define QOS_CPLEXIO_CR_FABRIC0_READ_MASK (0x0F << 0x10)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC0_WRITE_OFFSET 0x14
+ #define QOS_CPLEXIO_CR_FABRIC0_WRITE_MASK (0x0F << 0x14)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC1_READ_OFFSET 0x18
+ #define QOS_CPLEXIO_CR_FABRIC1_READ_MASK (0x0F << 0x18)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC1_WRITE_OFFSET 0x1C
+ #define QOS_CPLEXIO_CR_FABRIC1_WRITE_MASK (0x0F << 0x1C)
+
+/*QOS configuration DDRC*/
+#define QOS_CPLEXDDR_CR_OFFSET 0xC8
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_CACHE_READ_OFFSET 0x0
+ #define QOS_CPLEXDDR_CR_CACHE_READ_MASK (0x0F << 0x0)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_CACHE_WRITE_OFFSET 0x4
+ #define QOS_CPLEXDDR_CR_CACHE_WRITE_MASK (0x0F << 0x4)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_NCACHE_READ_OFFSET 0x8
+ #define QOS_CPLEXDDR_CR_NCACHE_READ_MASK (0x0F << 0x8)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_NCACHE_WRITE_OFFSET 0xC
+ #define QOS_CPLEXDDR_CR_NCACHE_WRITE_MASK (0x0F << 0xC)
+
+/*Indicates that a master caused a MPU violation. Interrupts via maintenanc
+ e interrupt.*/
+#define MPU_VIOLATION_SR_OFFSET 0xF0
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_FIC0_OFFSET 0x0
+ #define MPU_VIOLATION_SR_FIC0_MASK (0x01 << 0x0)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_FIC1_OFFSET 0x1
+ #define MPU_VIOLATION_SR_FIC1_MASK (0x01 << 0x1)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_FIC2_OFFSET 0x2
+ #define MPU_VIOLATION_SR_FIC2_MASK (0x01 << 0x2)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_ATHENA_OFFSET 0x3
+ #define MPU_VIOLATION_SR_ATHENA_MASK (0x01 << 0x3)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_GEM0_OFFSET 0x4
+ #define MPU_VIOLATION_SR_GEM0_MASK (0x01 << 0x4)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_GEM1_OFFSET 0x5
+ #define MPU_VIOLATION_SR_GEM1_MASK (0x01 << 0x5)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_USB_OFFSET 0x6
+ #define MPU_VIOLATION_SR_USB_MASK (0x01 << 0x6)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_MMC_OFFSET 0x7
+ #define MPU_VIOLATION_SR_MMC_MASK (0x01 << 0x7)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_SCB_OFFSET 0x8
+ #define MPU_VIOLATION_SR_SCB_MASK (0x01 << 0x8)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_TRACE_OFFSET 0x9
+ #define MPU_VIOLATION_SR_TRACE_MASK (0x01 << 0x9)
+
+/*Enables interrupts on MPU violations*/
+#define MPU_VIOLATION_INTEN_CR_OFFSET 0xF4
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_FIC0_OFFSET 0x0
+ #define MPU_VIOLATION_INTEN_CR_FIC0_MASK (0x01 << 0x0)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_FIC1_OFFSET 0x1
+ #define MPU_VIOLATION_INTEN_CR_FIC1_MASK (0x01 << 0x1)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_FIC2_OFFSET 0x2
+ #define MPU_VIOLATION_INTEN_CR_FIC2_MASK (0x01 << 0x2)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_ATHENA_OFFSET 0x3
+ #define MPU_VIOLATION_INTEN_CR_ATHENA_MASK (0x01 << 0x3)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_GEM0_OFFSET 0x4
+ #define MPU_VIOLATION_INTEN_CR_GEM0_MASK (0x01 << 0x4)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_GEM1_OFFSET 0x5
+ #define MPU_VIOLATION_INTEN_CR_GEM1_MASK (0x01 << 0x5)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_USB_OFFSET 0x6
+ #define MPU_VIOLATION_INTEN_CR_USB_MASK (0x01 << 0x6)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_MMC_OFFSET 0x7
+ #define MPU_VIOLATION_INTEN_CR_MMC_MASK (0x01 << 0x7)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_SCB_OFFSET 0x8
+ #define MPU_VIOLATION_INTEN_CR_SCB_MASK (0x01 << 0x8)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_TRACE_OFFSET 0x9
+ #define MPU_VIOLATION_INTEN_CR_TRACE_MASK (0x01 << 0x9)
+
+/*AXI switch decode fail*/
+#define SW_FAIL_ADDR0_CR_OFFSET 0xF8
+ /* The address (bits 31:0) that failed. Reading this address as 64-bits
+ will return the 38-bit address in a single read combined with additional i
+ nformation in the next register*/
+ #define SW_FAIL_ADDR0_CR_ADDR_OFFSET 0x0
+ #define SW_FAIL_ADDR0_CR_ADDR_MASK (0xFFFFFFFF << 0x0)
+
+/*AXI switch decode fail*/
+#define SW_FAIL_ADDR1_CR_OFFSET 0xFC
+ /* Upper 6 bits off address [37:32]*/
+ #define SW_FAIL_ADDR1_CR_ADDR_OFFSET 0x0
+ #define SW_FAIL_ADDR1_CR_ADDR_MASK (0x3F << 0x0)
+ /* AXI ID off failure*/
+ #define SW_FAIL_ADDR1_CR_ID_OFFSET 0x8
+ #define SW_FAIL_ADDR1_CR_ID_MASK (0xFF << 0x8)
+ /* AXI write=1 or read=0*/
+ #define SW_FAIL_ADDR1_CR_WRITE_OFFSET 0x10
+ #define SW_FAIL_ADDR1_CR_WRITE_MASK (0x01 << 0x10)
+ /* */
+ #define SW_FAIL_ADDR1_CR_FAILED_OFFSET 0x11
+ #define SW_FAIL_ADDR1_CR_FAILED_MASK (0x01 << 0x11)
+
+/*Set when an ECC event happens*/
+#define EDAC_SR_OFFSET 0x100
+ /* */
+ #define EDAC_SR_MMC_1E_OFFSET 0x0
+ #define EDAC_SR_MMC_1E_MASK (0x01 << 0x0)
+ /* */
+ #define EDAC_SR_MMC_2E_OFFSET 0x1
+ #define EDAC_SR_MMC_2E_MASK (0x01 << 0x1)
+ /* */
+ #define EDAC_SR_DDRC_1E_OFFSET 0x2
+ #define EDAC_SR_DDRC_1E_MASK (0x01 << 0x2)
+ /* */
+ #define EDAC_SR_DDRC_2E_OFFSET 0x3
+ #define EDAC_SR_DDRC_2E_MASK (0x01 << 0x3)
+ /* */
+ #define EDAC_SR_MAC0_1E_OFFSET 0x4
+ #define EDAC_SR_MAC0_1E_MASK (0x01 << 0x4)
+ /* */
+ #define EDAC_SR_MAC0_2E_OFFSET 0x5
+ #define EDAC_SR_MAC0_2E_MASK (0x01 << 0x5)
+ /* */
+ #define EDAC_SR_MAC1_1E_OFFSET 0x6
+ #define EDAC_SR_MAC1_1E_MASK (0x01 << 0x6)
+ /* */
+ #define EDAC_SR_MAC1_2E_OFFSET 0x7
+ #define EDAC_SR_MAC1_2E_MASK (0x01 << 0x7)
+ /* */
+ #define EDAC_SR_USB_1E_OFFSET 0x8
+ #define EDAC_SR_USB_1E_MASK (0x01 << 0x8)
+ /* */
+ #define EDAC_SR_USB_2E_OFFSET 0x9
+ #define EDAC_SR_USB_2E_MASK (0x01 << 0x9)
+ /* */
+ #define EDAC_SR_CAN0_1E_OFFSET 0xA
+ #define EDAC_SR_CAN0_1E_MASK (0x01 << 0xA)
+ /* */
+ #define EDAC_SR_CAN0_2E_OFFSET 0xB
+ #define EDAC_SR_CAN0_2E_MASK (0x01 << 0xB)
+ /* */
+ #define EDAC_SR_CAN1_1E_OFFSET 0xC
+ #define EDAC_SR_CAN1_1E_MASK (0x01 << 0xC)
+ /* */
+ #define EDAC_SR_CAN1_2E_OFFSET 0xD
+ #define EDAC_SR_CAN1_2E_MASK (0x01 << 0xD)
+
+/*Enables ECC interrupt on event*/
+#define EDAC_INTEN_CR_OFFSET 0x104
+ /* */
+ #define EDAC_INTEN_CR_MMC_1E_OFFSET 0x0
+ #define EDAC_INTEN_CR_MMC_1E_MASK (0x01 << 0x0)
+ /* */
+ #define EDAC_INTEN_CR_MMC_2E_OFFSET 0x1
+ #define EDAC_INTEN_CR_MMC_2E_MASK (0x01 << 0x1)
+ /* */
+ #define EDAC_INTEN_CR_DDRC_1E_OFFSET 0x2
+ #define EDAC_INTEN_CR_DDRC_1E_MASK (0x01 << 0x2)
+ /* */
+ #define EDAC_INTEN_CR_DDRC_2E_OFFSET 0x3
+ #define EDAC_INTEN_CR_DDRC_2E_MASK (0x01 << 0x3)
+ /* */
+ #define EDAC_INTEN_CR_MAC0_1E_OFFSET 0x4
+ #define EDAC_INTEN_CR_MAC0_1E_MASK (0x01 << 0x4)
+ /* */
+ #define EDAC_INTEN_CR_MAC0_2E_OFFSET 0x5
+ #define EDAC_INTEN_CR_MAC0_2E_MASK (0x01 << 0x5)
+ /* */
+ #define EDAC_INTEN_CR_MAC1_1E_OFFSET 0x6
+ #define EDAC_INTEN_CR_MAC1_1E_MASK (0x01 << 0x6)
+ /* */
+ #define EDAC_INTEN_CR_MAC1_2E_OFFSET 0x7
+ #define EDAC_INTEN_CR_MAC1_2E_MASK (0x01 << 0x7)
+ /* */
+ #define EDAC_INTEN_CR_USB_1E_OFFSET 0x8
+ #define EDAC_INTEN_CR_USB_1E_MASK (0x01 << 0x8)
+ /* */
+ #define EDAC_INTEN_CR_USB_2E_OFFSET 0x9
+ #define EDAC_INTEN_CR_USB_2E_MASK (0x01 << 0x9)
+ /* */
+ #define EDAC_INTEN_CR_CAN0_1E_OFFSET 0xA
+ #define EDAC_INTEN_CR_CAN0_1E_MASK (0x01 << 0xA)
+ /* */
+ #define EDAC_INTEN_CR_CAN0_2E_OFFSET 0xB
+ #define EDAC_INTEN_CR_CAN0_2E_MASK (0x01 << 0xB)
+ /* */
+ #define EDAC_INTEN_CR_CAN1_1E_OFFSET 0xC
+ #define EDAC_INTEN_CR_CAN1_1E_MASK (0x01 << 0xC)
+ /* */
+ #define EDAC_INTEN_CR_CAN1_2E_OFFSET 0xD
+ #define EDAC_INTEN_CR_CAN1_2E_MASK (0x01 << 0xD)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_MMC_OFFSET 0x108
+ /* */
+ #define EDAC_CNT_MMC_COUNT_OFFSET 0x0
+ #define EDAC_CNT_MMC_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_DDRC_OFFSET 0x10C
+ /* */
+ #define EDAC_CNT_DDRC_COUNT_OFFSET 0x0
+ #define EDAC_CNT_DDRC_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_MAC0_OFFSET 0x110
+ /* */
+ #define EDAC_CNT_MAC0_COUNT_OFFSET 0x0
+ #define EDAC_CNT_MAC0_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_MAC1_OFFSET 0x114
+ /* */
+ #define EDAC_CNT_MAC1_COUNT_OFFSET 0x0
+ #define EDAC_CNT_MAC1_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_USB_OFFSET 0x118
+ /* */
+ #define EDAC_CNT_USB_COUNT_OFFSET 0x0
+ #define EDAC_CNT_USB_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_CAN0_OFFSET 0x11C
+ /* */
+ #define EDAC_CNT_CAN0_COUNT_OFFSET 0x0
+ #define EDAC_CNT_CAN0_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_CAN1_OFFSET 0x120
+ /* */
+ #define EDAC_CNT_CAN1_COUNT_OFFSET 0x0
+ #define EDAC_CNT_CAN1_COUNT_MASK (0x3FF << 0x0)
+
+/*"Will Corrupt write data to rams 1E corrupts bit 0 2E bits 1 and 2.Inject
+ s Errors into all RAMS in the block as long as the bits are set. Setting 1E
+ and 2E will inject a 3-bit error"*/
+#define EDAC_INJECT_CR_OFFSET 0x124
+ /* */
+ #define EDAC_INJECT_CR_MMC_1E_OFFSET 0x0
+ #define EDAC_INJECT_CR_MMC_1E_MASK (0x01 << 0x0)
+ /* */
+ #define EDAC_INJECT_CR_MMC_2E_OFFSET 0x1
+ #define EDAC_INJECT_CR_MMC_2E_MASK (0x01 << 0x1)
+ /* */
+ #define EDAC_INJECT_CR_DDRC_1E_OFFSET 0x2
+ #define EDAC_INJECT_CR_DDRC_1E_MASK (0x01 << 0x2)
+ /* */
+ #define EDAC_INJECT_CR_DDRC_2E_OFFSET 0x3
+ #define EDAC_INJECT_CR_DDRC_2E_MASK (0x01 << 0x3)
+ /* */
+ #define EDAC_INJECT_CR_MAC0_1E_OFFSET 0x4
+ #define EDAC_INJECT_CR_MAC0_1E_MASK (0x01 << 0x4)
+ /* */
+ #define EDAC_INJECT_CR_MAC0_2E_OFFSET 0x5
+ #define EDAC_INJECT_CR_MAC0_2E_MASK (0x01 << 0x5)
+ /* */
+ #define EDAC_INJECT_CR_MAC1_1E_OFFSET 0x6
+ #define EDAC_INJECT_CR_MAC1_1E_MASK (0x01 << 0x6)
+ /* */
+ #define EDAC_INJECT_CR_MAC1_2E_OFFSET 0x7
+ #define EDAC_INJECT_CR_MAC1_2E_MASK (0x01 << 0x7)
+ /* */
+ #define EDAC_INJECT_CR_USB_1E_OFFSET 0x8
+ #define EDAC_INJECT_CR_USB_1E_MASK (0x01 << 0x8)
+ /* */
+ #define EDAC_INJECT_CR_USB_2E_OFFSET 0x9
+ #define EDAC_INJECT_CR_USB_2E_MASK (0x01 << 0x9)
+ /* */
+ #define EDAC_INJECT_CR_CAN0_1E_OFFSET 0xA
+ #define EDAC_INJECT_CR_CAN0_1E_MASK (0x01 << 0xA)
+ /* */
+ #define EDAC_INJECT_CR_CAN0_2E_OFFSET 0xB
+ #define EDAC_INJECT_CR_CAN0_2E_MASK (0x01 << 0xB)
+ /* */
+ #define EDAC_INJECT_CR_CAN1_1E_OFFSET 0xC
+ #define EDAC_INJECT_CR_CAN1_1E_MASK (0x01 << 0xC)
+ /* */
+ #define EDAC_INJECT_CR_CAN1_2E_OFFSET 0xD
+ #define EDAC_INJECT_CR_CAN1_2E_MASK (0x01 << 0xD)
+
+/*Maintenance Interrupt Enable.*/
+#define MAINTENANCE_INTEN_CR_OFFSET 0x140
+ /* Enables interrupt on a PLL event PLL_STATUS_INTEN_CR should also be
+ set*/
+ #define MAINTENANCE_INTEN_CR_PLL_OFFSET 0x0
+ #define MAINTENANCE_INTEN_CR_PLL_MASK (0x01 << 0x0)
+ /* Enables interrupt on a MPU access violation */
+ #define MAINTENANCE_INTEN_CR_MPU_OFFSET 0x1
+ #define MAINTENANCE_INTEN_CR_MPU_MASK (0x01 << 0x1)
+ /* Enables interrupt on a AXI switch decode error*/
+ #define MAINTENANCE_INTEN_CR_DECODE_OFFSET 0x2
+ #define MAINTENANCE_INTEN_CR_DECODE_MASK (0x01 << 0x2)
+ /* Enables interrupt as lp_state goes high*/
+ #define MAINTENANCE_INTEN_CR_LP_STATE_ENTER_OFFSET 0x3
+ #define MAINTENANCE_INTEN_CR_LP_STATE_ENTER_MASK (0x01 << 0x3)
+ /* Enables interrupt as lp_state goes low*/
+ #define MAINTENANCE_INTEN_CR_LP_STATE_EXIT_OFFSET 0x4
+ #define MAINTENANCE_INTEN_CR_LP_STATE_EXIT_MASK (0x01 << 0x4)
+ /* Enables interrupt as flash_freeze goes high*/
+ #define MAINTENANCE_INTEN_CR_FF_START_OFFSET 0x5
+ #define MAINTENANCE_INTEN_CR_FF_START_MASK (0x01 << 0x5)
+ /* Enables interrupt as flash_freeze goes low*/
+ #define MAINTENANCE_INTEN_CR_FF_END_OFFSET 0x6
+ #define MAINTENANCE_INTEN_CR_FF_END_MASK (0x01 << 0x6)
+ /* Enables interrupt when FPGA turned on*/
+ #define MAINTENANCE_INTEN_CR_FPGA_ON_OFFSET 0x7
+ #define MAINTENANCE_INTEN_CR_FPGA_ON_MASK (0x01 << 0x7)
+ /* Enables interrupt when FPGA turned off*/
+ #define MAINTENANCE_INTEN_CR_FPGA_OFF_OFFSET 0x8
+ #define MAINTENANCE_INTEN_CR_FPGA_OFF_MASK (0x01 << 0x8)
+ /* Enables interrupt on SCB error*/
+ #define MAINTENANCE_INTEN_CR_SCB_ERROR_OFFSET 0x9
+ #define MAINTENANCE_INTEN_CR_SCB_ERROR_MASK (0x01 << 0x9)
+ /* Enables interrupt on SCB failure*/
+ #define MAINTENANCE_INTEN_CR_SCB_FAULT_OFFSET 0xA
+ #define MAINTENANCE_INTEN_CR_SCB_FAULT_MASK (0x01 << 0xA)
+ /* Enables interrupt on Mesh violation detection */
+ #define MAINTENANCE_INTEN_CR_MESH_ERROR_OFFSET 0xB
+ #define MAINTENANCE_INTEN_CR_MESH_ERROR_MASK (0x01 << 0xB)
+ /* Enables interrupt on bank2 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_ON_OFFSET 0xC
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_ON_MASK (0x01 << 0xC)
+ /* Enables interrupt on bank4 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_ON_OFFSET 0xD
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_ON_MASK (0x01 << 0xD)
+ /* Enables interrupt on bank5 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_ON_OFFSET 0xE
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_ON_MASK (0x01 << 0xE)
+ /* Enables interrupt on bank6 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_ON_OFFSET 0xF
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_ON_MASK (0x01 << 0xF)
+ /* Enables interrupt on bank2 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_OFF_OFFSET 0x10
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_OFF_MASK (0x01 << 0x10)
+ /* Enables interrupt on bank4 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_OFF_OFFSET 0x11
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_OFF_MASK (0x01 << 0x11)
+ /* Enables interrupt on bank5 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_OFF_OFFSET 0x12
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_OFF_MASK (0x01 << 0x12)
+ /* Enables interrupt on bank6 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_OFF_OFFSET 0x13
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_OFF_MASK (0x01 << 0x13)
+ /* Enables interrupt on a DLL event DLL_STATUS_INTEN_CR should also be
+ set*/
+ #define MAINTENANCE_INTEN_CR_DLL_OFFSET 0x14
+ #define MAINTENANCE_INTEN_CR_DLL_MASK (0x01 << 0x14)
+
+/*PLL Status interrupt enables*/
+#define PLL_STATUS_INTEN_CR_OFFSET 0x144
+ /* Enables interrupt on CPU PLL locking*/
+ #define PLL_STATUS_INTEN_CR_CPU_LOCK_OFFSET 0x0
+ #define PLL_STATUS_INTEN_CR_CPU_LOCK_MASK (0x01 << 0x0)
+ /* Enables interrupt on DFT PLL locking*/
+ #define PLL_STATUS_INTEN_CR_DFI_LOCK_OFFSET 0x1
+ #define PLL_STATUS_INTEN_CR_DFI_LOCK_MASK (0x01 << 0x1)
+ /* Enables interrupt on SGMII PLL locking*/
+ #define PLL_STATUS_INTEN_CR_SGMII_LOCK_OFFSET 0x2
+ #define PLL_STATUS_INTEN_CR_SGMII_LOCK_MASK (0x01 << 0x2)
+ /* Enables interrupt on CPU PLL unlocking*/
+ #define PLL_STATUS_INTEN_CR_CPU_UNLOCK_OFFSET 0x4
+ #define PLL_STATUS_INTEN_CR_CPU_UNLOCK_MASK (0x01 << 0x4)
+ /* Enables interrupt on DFT PLL unlocking*/
+ #define PLL_STATUS_INTEN_CR_DFI_UNLOCK_OFFSET 0x5
+ #define PLL_STATUS_INTEN_CR_DFI_UNLOCK_MASK (0x01 << 0x5)
+ /* Enables interrupt on SGMII PLL unlocking*/
+ #define PLL_STATUS_INTEN_CR_SGMII_UNLOCK_OFFSET 0x6
+ #define PLL_STATUS_INTEN_CR_SGMII_UNLOCK_MASK (0x01 << 0x6)
+
+/*Maintenance interrupt indicates fault and status events.*/
+#define MAINTENANCE_INT_SR_OFFSET 0x148
+ /* Indicates that one off the PLLs whent into the lock or unlock state.
+ Cleared via PLL status register*/
+ #define MAINTENANCE_INT_SR_PLL_OFFSET 0x0
+ #define MAINTENANCE_INT_SR_PLL_MASK (0x01 << 0x0)
+ /* Indicates that one off the MPUS signaled a MPU violation. Cleared vi
+ a MPU Violation Register*/
+ #define MAINTENANCE_INT_SR_MPU_OFFSET 0x1
+ #define MAINTENANCE_INT_SR_MPU_MASK (0x01 << 0x1)
+ /* Indicates that the AXI switch detected an illegal address. Cleared w
+ hen SREG.SW_FAIL.ADDR1_CR_FAILED is cleared.*/
+ #define MAINTENANCE_INT_SR_DECODE_OFFSET 0x2
+ #define MAINTENANCE_INT_SR_DECODE_MASK (0x01 << 0x2)
+ /* Indicates the device has entered the lower power state cleared by wr
+ iting '1'*/
+ #define MAINTENANCE_INT_SR_LP_STATE_ENTER_OFFSET 0x3
+ #define MAINTENANCE_INT_SR_LP_STATE_ENTER_MASK (0x01 << 0x3)
+ /* Indicates the device has exited the lower power state cleared by wri
+ ting '1'*/
+ #define MAINTENANCE_INT_SR_LP_STATE_EXIT_OFFSET 0x4
+ #define MAINTENANCE_INT_SR_LP_STATE_EXIT_MASK (0x01 << 0x4)
+ /* Indicates the device has entered the flash freezer state cleared by
+ writing '1'*/
+ #define MAINTENANCE_INT_SR_FF_START_OFFSET 0x5
+ #define MAINTENANCE_INT_SR_FF_START_MASK (0x01 << 0x5)
+ /* Indicates the device has exited the flash freezer state cleared by w
+ riting '1'*/
+ #define MAINTENANCE_INT_SR_FF_END_OFFSET 0x6
+ #define MAINTENANCE_INT_SR_FF_END_MASK (0x01 << 0x6)
+ /* Indicates that the FPGA array has been turned on cleared by writing
+ a '1'*/
+ #define MAINTENANCE_INT_SR_FPGA_ON_OFFSET 0x7
+ #define MAINTENANCE_INT_SR_FPGA_ON_MASK (0x01 << 0x7)
+ /* Indicates that the FPGA array has been turned off cleared by writing
+ a '1'*/
+ #define MAINTENANCE_INT_SR_FPGA_OFF_OFFSET 0x8
+ #define MAINTENANCE_INT_SR_FPGA_OFF_MASK (0x01 << 0x8)
+ /* Indicates that the SCB slave reported an error cleared via SCB contr
+ oller*/
+ #define MAINTENANCE_INT_SR_SCB_ERROR_OFFSET 0x9
+ #define MAINTENANCE_INT_SR_SCB_ERROR_MASK (0x01 << 0x9)
+ /* Indicates that the SCB bus fault occurred cleared via SCB controller
+ */
+ #define MAINTENANCE_INT_SR_SCB_FAULT_OFFSET 0xA
+ #define MAINTENANCE_INT_SR_SCB_FAULT_MASK (0x01 << 0xA)
+ /* Indicates that the mesh over the Crypto triggered cleared via Mesh s
+ ystem error*/
+ #define MAINTENANCE_INT_SR_MESH_ERROR_OFFSET 0xB
+ #define MAINTENANCE_INT_SR_MESH_ERROR_MASK (0x01 << 0xB)
+ /* Indicates that IO bank 2 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_ON_OFFSET 0xC
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_ON_MASK (0x01 << 0xC)
+ /* Indicates that IO bank 4 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_ON_OFFSET 0xD
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_ON_MASK (0x01 << 0xD)
+ /* Indicates that IO bank 5 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_ON_OFFSET 0xE
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_ON_MASK (0x01 << 0xE)
+ /* Indicates that IO bank 6 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_ON_OFFSET 0xF
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_ON_MASK (0x01 << 0xF)
+ /* Indicates that IO bank 2 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_OFF_OFFSET 0x10
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_OFF_MASK (0x01 << 0x10)
+ /* Indicates that IO bank 4 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_OFF_OFFSET 0x11
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_OFF_MASK (0x01 << 0x11)
+ /* Indicates that IO bank 5 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_OFF_OFFSET 0x12
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_OFF_MASK (0x01 << 0x12)
+ /* Indicates that one off the DLLs when into the lock or unlock state.
+ Cleared via DLL status register*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_OFF_OFFSET 0x13
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_OFF_MASK (0x01 << 0x13)
+ /* Indicates that IO bank 6 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_DLL_OFFSET 0x14
+ #define MAINTENANCE_INT_SR_DLL_MASK (0x01 << 0x14)
+
+/*PLL interrupt register*/
+#define PLL_STATUS_SR_OFFSET 0x14C
+ /* Indicates that the CPU PLL has locked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_CPU_LOCK_OFFSET 0x0
+ #define PLL_STATUS_SR_CPU_LOCK_MASK (0x01 << 0x0)
+ /* Indicates that the DFI PLL has locked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_DFI_LOCK_OFFSET 0x1
+ #define PLL_STATUS_SR_DFI_LOCK_MASK (0x01 << 0x1)
+ /* Indicates that the SGMII PLL has locked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_SGMII_LOCK_OFFSET 0x2
+ #define PLL_STATUS_SR_SGMII_LOCK_MASK (0x01 << 0x2)
+ /* Indicates that the CPU PLL has unlocked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_CPU_UNLOCK_OFFSET 0x4
+ #define PLL_STATUS_SR_CPU_UNLOCK_MASK (0x01 << 0x4)
+ /* Indicates that the DFI PLL has unlocked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_DFI_UNLOCK_OFFSET 0x5
+ #define PLL_STATUS_SR_DFI_UNLOCK_MASK (0x01 << 0x5)
+ /* Indicates that the SGMII PLL has unlocked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_SGMII_UNLOCK_OFFSET 0x6
+ #define PLL_STATUS_SR_SGMII_UNLOCK_MASK (0x01 << 0x6)
+ /* Current state off CPU PLL locked signal*/
+ #define PLL_STATUS_SR_CPU_LOCK_NOW_OFFSET 0x8
+ #define PLL_STATUS_SR_CPU_LOCK_NOW_MASK (0x01 << 0x8)
+ /* Current state off DFI PLL locked signal*/
+ #define PLL_STATUS_SR_DFI_LOCK_NOW_OFFSET 0x9
+ #define PLL_STATUS_SR_DFI_LOCK_NOW_MASK (0x01 << 0x9)
+ /* Current state off SGMII PLL locked signal*/
+ #define PLL_STATUS_SR_SGMII_LOCK_NOW_OFFSET 0xA
+ #define PLL_STATUS_SR_SGMII_LOCK_NOW_MASK (0x01 << 0xA)
+
+/*Enable to CFM Timer */
+#define CFM_TIMER_CR_OFFSET 0x150
+ /* When set and the CFM channel is in timer mode and CFM channel is set
+ to 2 (Group C) this register allows the timet to count. Allows software to
+ start and stop the timers.*/
+ #define CFM_TIMER_CR_ENABLE_OFFSET 0x0
+ #define CFM_TIMER_CR_ENABLE_MASK (0x1F << 0x0)
+
+/*Miscellaneous Register*/
+#define MISC_SR_OFFSET 0x154
+ /* Indicates that Interrupt from the G5C MSS SCB SPI controller is acti
+ ve*/
+ #define MISC_SR_CONT_SPI_INTERRUPT_OFFSET 0x0
+ #define MISC_SR_CONT_SPI_INTERRUPT_MASK (0x01 << 0x0)
+ /* Indicates that the user voltage or temperature detectors are signali
+ ng an alarm condition.*/
+ #define MISC_SR_VOLT_TEMP_ALARM_OFFSET 0x1
+ #define MISC_SR_VOLT_TEMP_ALARM_MASK (0x01 << 0x1)
+
+/*DLL Interrupt enables*/
+#define DLL_STATUS_CR_OFFSET 0x158
+ /* Enables the DLL0 lock interrupt*/
+ #define DLL_STATUS_CR_FIC0_LOCK_OFFSET 0x0
+ #define DLL_STATUS_CR_FIC0_LOCK_MASK (0x01 << 0x0)
+ /* Enables the DLL1 lock interrupt*/
+ #define DLL_STATUS_CR_FIC1_LOCK_OFFSET 0x1
+ #define DLL_STATUS_CR_FIC1_LOCK_MASK (0x01 << 0x1)
+ /* Enables the DLL2 lock interrupt*/
+ #define DLL_STATUS_CR_FIC2_LOCK_OFFSET 0x2
+ #define DLL_STATUS_CR_FIC2_LOCK_MASK (0x01 << 0x2)
+ /* Enables the DLL3 lock interrupt*/
+ #define DLL_STATUS_CR_FIC3_LOCK_OFFSET 0x4
+ #define DLL_STATUS_CR_FIC3_LOCK_MASK (0x01 << 0x4)
+ /* Enables the DLL4 (Crypto) lock interrupt*/
+ #define DLL_STATUS_CR_FIC4_LOCK_OFFSET 0x5
+ #define DLL_STATUS_CR_FIC4_LOCK_MASK (0x01 << 0x5)
+ /* Enables the DLL0 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC0_UNLOCK_OFFSET 0x8
+ #define DLL_STATUS_CR_FIC0_UNLOCK_MASK (0x01 << 0x8)
+ /* Enables the DLL1 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC1_UNLOCK_OFFSET 0x9
+ #define DLL_STATUS_CR_FIC1_UNLOCK_MASK (0x01 << 0x9)
+ /* Enables the DLL2 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC2_UNLOCK_OFFSET 0xA
+ #define DLL_STATUS_CR_FIC2_UNLOCK_MASK (0x01 << 0xA)
+ /* Enables the DLL3 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC3_UNLOCK_OFFSET 0xB
+ #define DLL_STATUS_CR_FIC3_UNLOCK_MASK (0x01 << 0xB)
+ /* Enables the DLL4 (crypto) unlock interrupt*/
+ #define DLL_STATUS_CR_FIC4_UNLOCK_OFFSET 0xC
+ #define DLL_STATUS_CR_FIC4_UNLOCK_MASK (0x01 << 0xC)
+
+/*DLL interrupt register*/
+#define DLL_STATUS_SR_OFFSET 0x15C
+ /* Indicates that the FIC0 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC0_LOCK_OFFSET 0x0
+ #define DLL_STATUS_SR_FIC0_LOCK_MASK (0x01 << 0x0)
+ /* Indicates that the FIC1 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC1_LOCK_OFFSET 0x1
+ #define DLL_STATUS_SR_FIC1_LOCK_MASK (0x01 << 0x1)
+ /* Indicates that the FIC2 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC2_LOCK_OFFSET 0x2
+ #define DLL_STATUS_SR_FIC2_LOCK_MASK (0x01 << 0x2)
+ /* Indicates that the FIC3 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC3_LOCK_OFFSET 0x4
+ #define DLL_STATUS_SR_FIC3_LOCK_MASK (0x01 << 0x4)
+ /* Indicates that the FIC4 (Crypto) DLL has locked cleared by writing a
+ '1'*/
+ #define DLL_STATUS_SR_FIC4_LOCK_OFFSET 0x5
+ #define DLL_STATUS_SR_FIC4_LOCK_MASK (0x01 << 0x5)
+ /* Indicates that the FIC0 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC0_UNLOCK_OFFSET 0x8
+ #define DLL_STATUS_SR_FIC0_UNLOCK_MASK (0x01 << 0x8)
+ /* Indicates that the FIC1 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC1_UNLOCK_OFFSET 0x9
+ #define DLL_STATUS_SR_FIC1_UNLOCK_MASK (0x01 << 0x9)
+ /* Indicates that the FIC2 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC2_UNLOCK_OFFSET 0xA
+ #define DLL_STATUS_SR_FIC2_UNLOCK_MASK (0x01 << 0xA)
+ /* Indicates that the FIC3 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC3_UNLOCK_OFFSET 0xB
+ #define DLL_STATUS_SR_FIC3_UNLOCK_MASK (0x01 << 0xB)
+ /* Indicates that the FIC4 (Crypto) DLL has unlocked cleared by writing
+ a '1'*/
+ #define DLL_STATUS_SR_FIC4_UNLOCK_OFFSET 0xC
+ #define DLL_STATUS_SR_FIC4_UNLOCK_MASK (0x01 << 0xC)
+ /* Current state off FIC0 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC0_LOCK_NOW_OFFSET 0x10
+ #define DLL_STATUS_SR_FIC0_LOCK_NOW_MASK (0x01 << 0x10)
+ /* Current state off FIC1 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC1_LOCK_NOW_OFFSET 0x11
+ #define DLL_STATUS_SR_FIC1_LOCK_NOW_MASK (0x01 << 0x11)
+ /* Current state off FIC2 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC2_LOCK_NOW_OFFSET 0x12
+ #define DLL_STATUS_SR_FIC2_LOCK_NOW_MASK (0x01 << 0x12)
+ /* Current state off FIC3 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC3_LOCK_NOW_OFFSET 0x13
+ #define DLL_STATUS_SR_FIC3_LOCK_NOW_MASK (0x01 << 0x13)
+ /* Current state off FIC4 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC4_LOCK_NOW_OFFSET 0x14
+ #define DLL_STATUS_SR_FIC4_LOCK_NOW_MASK (0x01 << 0x14)
+
+/*Puts all the RAMS in that block into low leakage mode. RAM contents and Q
+ value preserved.*/
+#define RAM_LIGHTSLEEP_CR_OFFSET 0x168
+ /* */
+ #define RAM_LIGHTSLEEP_CR_CAN0_OFFSET 0x0
+ #define RAM_LIGHTSLEEP_CR_CAN0_MASK (0x01 << 0x0)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_CAN1_OFFSET 0x1
+ #define RAM_LIGHTSLEEP_CR_CAN1_MASK (0x01 << 0x1)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_USB_OFFSET 0x2
+ #define RAM_LIGHTSLEEP_CR_USB_MASK (0x01 << 0x2)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_GEM0_OFFSET 0x3
+ #define RAM_LIGHTSLEEP_CR_GEM0_MASK (0x01 << 0x3)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_GEM1_OFFSET 0x4
+ #define RAM_LIGHTSLEEP_CR_GEM1_MASK (0x01 << 0x4)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_MMC_OFFSET 0x5
+ #define RAM_LIGHTSLEEP_CR_MMC_MASK (0x01 << 0x5)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_ATHENA_OFFSET 0x6
+ #define RAM_LIGHTSLEEP_CR_ATHENA_MASK (0x01 << 0x6)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_DDRC_OFFSET 0x7
+ #define RAM_LIGHTSLEEP_CR_DDRC_MASK (0x01 << 0x7)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_E51_OFFSET 0x8
+ #define RAM_LIGHTSLEEP_CR_E51_MASK (0x01 << 0x8)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_1_OFFSET 0x9
+ #define RAM_LIGHTSLEEP_CR_U54_1_MASK (0x01 << 0x9)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_2_OFFSET 0xA
+ #define RAM_LIGHTSLEEP_CR_U54_2_MASK (0x01 << 0xA)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_3_OFFSET 0xB
+ #define RAM_LIGHTSLEEP_CR_U54_3_MASK (0x01 << 0xB)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_4_OFFSET 0xC
+ #define RAM_LIGHTSLEEP_CR_U54_4_MASK (0x01 << 0xC)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_L2_OFFSET 0xD
+ #define RAM_LIGHTSLEEP_CR_L2_MASK (0x01 << 0xD)
+
+/*Puts all the RAMS in that block into deep sleep mode. RAM contents preser
+ ved. Powers down the periphery circuits.*/
+#define RAM_DEEPSLEEP_CR_OFFSET 0x16C
+ /* */
+ #define RAM_DEEPSLEEP_CR_CAN0_OFFSET 0x0
+ #define RAM_DEEPSLEEP_CR_CAN0_MASK (0x01 << 0x0)
+ /* */
+ #define RAM_DEEPSLEEP_CR_CAN1_OFFSET 0x1
+ #define RAM_DEEPSLEEP_CR_CAN1_MASK (0x01 << 0x1)
+ /* */
+ #define RAM_DEEPSLEEP_CR_USB_OFFSET 0x2
+ #define RAM_DEEPSLEEP_CR_USB_MASK (0x01 << 0x2)
+ /* */
+ #define RAM_DEEPSLEEP_CR_GEM0_OFFSET 0x3
+ #define RAM_DEEPSLEEP_CR_GEM0_MASK (0x01 << 0x3)
+ /* */
+ #define RAM_DEEPSLEEP_CR_GEM1_OFFSET 0x4
+ #define RAM_DEEPSLEEP_CR_GEM1_MASK (0x01 << 0x4)
+ /* */
+ #define RAM_DEEPSLEEP_CR_MMC_OFFSET 0x5
+ #define RAM_DEEPSLEEP_CR_MMC_MASK (0x01 << 0x5)
+ /* */
+ #define RAM_DEEPSLEEP_CR_ATHENA_OFFSET 0x6
+ #define RAM_DEEPSLEEP_CR_ATHENA_MASK (0x01 << 0x6)
+ /* */
+ #define RAM_DEEPSLEEP_CR_DDRC_OFFSET 0x7
+ #define RAM_DEEPSLEEP_CR_DDRC_MASK (0x01 << 0x7)
+ /* */
+ #define RAM_DEEPSLEEP_CR_E51_OFFSET 0x8
+ #define RAM_DEEPSLEEP_CR_E51_MASK (0x01 << 0x8)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_1_OFFSET 0x9
+ #define RAM_DEEPSLEEP_CR_U54_1_MASK (0x01 << 0x9)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_2_OFFSET 0xA
+ #define RAM_DEEPSLEEP_CR_U54_2_MASK (0x01 << 0xA)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_3_OFFSET 0xB
+ #define RAM_DEEPSLEEP_CR_U54_3_MASK (0x01 << 0xB)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_4_OFFSET 0xC
+ #define RAM_DEEPSLEEP_CR_U54_4_MASK (0x01 << 0xC)
+ /* */
+ #define RAM_DEEPSLEEP_CR_L2_OFFSET 0xD
+ #define RAM_DEEPSLEEP_CR_L2_MASK (0x01 << 0xD)
+
+/*Puts all the RAMS in that block into shut down mode. RAM contents not pre
+ served. Powers down the RAM and periphery circuits.*/
+#define RAM_SHUTDOWN_CR_OFFSET 0x170
+ /* */
+ #define RAM_SHUTDOWN_CR_CAN0_OFFSET 0x0
+ #define RAM_SHUTDOWN_CR_CAN0_MASK (0x01 << 0x0)
+ /* */
+ #define RAM_SHUTDOWN_CR_CAN1_OFFSET 0x1
+ #define RAM_SHUTDOWN_CR_CAN1_MASK (0x01 << 0x1)
+ /* */
+ #define RAM_SHUTDOWN_CR_USB_OFFSET 0x2
+ #define RAM_SHUTDOWN_CR_USB_MASK (0x01 << 0x2)
+ /* */
+ #define RAM_SHUTDOWN_CR_GEM0_OFFSET 0x3
+ #define RAM_SHUTDOWN_CR_GEM0_MASK (0x01 << 0x3)
+ /* */
+ #define RAM_SHUTDOWN_CR_GEM1_OFFSET 0x4
+ #define RAM_SHUTDOWN_CR_GEM1_MASK (0x01 << 0x4)
+ /* */
+ #define RAM_SHUTDOWN_CR_MMC_OFFSET 0x5
+ #define RAM_SHUTDOWN_CR_MMC_MASK (0x01 << 0x5)
+ /* */
+ #define RAM_SHUTDOWN_CR_ATHENA_OFFSET 0x6
+ #define RAM_SHUTDOWN_CR_ATHENA_MASK (0x01 << 0x6)
+ /* */
+ #define RAM_SHUTDOWN_CR_DDRC_OFFSET 0x7
+ #define RAM_SHUTDOWN_CR_DDRC_MASK (0x01 << 0x7)
+ /* */
+ #define RAM_SHUTDOWN_CR_E51_OFFSET 0x8
+ #define RAM_SHUTDOWN_CR_E51_MASK (0x01 << 0x8)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_1_OFFSET 0x9
+ #define RAM_SHUTDOWN_CR_U54_1_MASK (0x01 << 0x9)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_2_OFFSET 0xA
+ #define RAM_SHUTDOWN_CR_U54_2_MASK (0x01 << 0xA)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_3_OFFSET 0xB
+ #define RAM_SHUTDOWN_CR_U54_3_MASK (0x01 << 0xB)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_4_OFFSET 0xC
+ #define RAM_SHUTDOWN_CR_U54_4_MASK (0x01 << 0xC)
+ /* */
+ #define RAM_SHUTDOWN_CR_L2_OFFSET 0xD
+ #define RAM_SHUTDOWN_CR_L2_MASK (0x01 << 0xD)
+
+/*Allows each bank of the L2 Cache to be powered down ORed with global shut
+ down */
+#define L2_SHUTDOWN_CR_OFFSET 0x174
+ /* */
+ #define L2_SHUTDOWN_CR_L2_RAMS_OFFSET 0x0
+ #define L2_SHUTDOWN_CR_L2_RAMS_MASK (0x0F << 0x0)
+
+/*Selects whether the peripheral is connected to the Fabric or IOMUX struct
+ ure.*/
+#define IOMUX0_CR_OFFSET 0x200
+ /* */
+ #define IOMUX0_CR_SPI0_FABRIC_OFFSET 0x0
+ #define IOMUX0_CR_SPI0_FABRIC_MASK (0x01 << 0x0)
+ /* */
+ #define IOMUX0_CR_SPI1_FABRIC_OFFSET 0x1
+ #define IOMUX0_CR_SPI1_FABRIC_MASK (0x01 << 0x1)
+ /* */
+ #define IOMUX0_CR_I2C0_FABRIC_OFFSET 0x2
+ #define IOMUX0_CR_I2C0_FABRIC_MASK (0x01 << 0x2)
+ /* */
+ #define IOMUX0_CR_I2C1_FABRIC_OFFSET 0x3
+ #define IOMUX0_CR_I2C1_FABRIC_MASK (0x01 << 0x3)
+ /* */
+ #define IOMUX0_CR_CAN0_FABRIC_OFFSET 0x4
+ #define IOMUX0_CR_CAN0_FABRIC_MASK (0x01 << 0x4)
+ /* */
+ #define IOMUX0_CR_CAN1_FABRIC_OFFSET 0x5
+ #define IOMUX0_CR_CAN1_FABRIC_MASK (0x01 << 0x5)
+ /* */
+ #define IOMUX0_CR_QSPI_FABRIC_OFFSET 0x6
+ #define IOMUX0_CR_QSPI_FABRIC_MASK (0x01 << 0x6)
+ /* */
+ #define IOMUX0_CR_MMUART0_FABRIC_OFFSET 0x7
+ #define IOMUX0_CR_MMUART0_FABRIC_MASK (0x01 << 0x7)
+ /* */
+ #define IOMUX0_CR_MMUART1_FABRIC_OFFSET 0x8
+ #define IOMUX0_CR_MMUART1_FABRIC_MASK (0x01 << 0x8)
+ /* */
+ #define IOMUX0_CR_MMUART2_FABRIC_OFFSET 0x9
+ #define IOMUX0_CR_MMUART2_FABRIC_MASK (0x01 << 0x9)
+ /* */
+ #define IOMUX0_CR_MMUART3_FABRIC_OFFSET 0xA
+ #define IOMUX0_CR_MMUART3_FABRIC_MASK (0x01 << 0xA)
+ /* */
+ #define IOMUX0_CR_MMUART4_FABRIC_OFFSET 0xB
+ #define IOMUX0_CR_MMUART4_FABRIC_MASK (0x01 << 0xB)
+ /* */
+ #define IOMUX0_CR_MDIO0_FABRIC_OFFSET 0xC
+ #define IOMUX0_CR_MDIO0_FABRIC_MASK (0x01 << 0xC)
+ /* */
+ #define IOMUX0_CR_MDIO1_FABRIC_OFFSET 0xD
+ #define IOMUX0_CR_MDIO1_FABRIC_MASK (0x01 << 0xD)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX1_CR_OFFSET 0x204
+ /* */
+ #define IOMUX1_CR_PAD0_OFFSET 0x0
+ #define IOMUX1_CR_PAD0_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX1_CR_PAD1_OFFSET 0x4
+ #define IOMUX1_CR_PAD1_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX1_CR_PAD2_OFFSET 0x8
+ #define IOMUX1_CR_PAD2_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX1_CR_PAD3_OFFSET 0xC
+ #define IOMUX1_CR_PAD3_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX1_CR_PAD4_OFFSET 0x10
+ #define IOMUX1_CR_PAD4_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX1_CR_PAD5_OFFSET 0x14
+ #define IOMUX1_CR_PAD5_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX1_CR_PAD6_OFFSET 0x18
+ #define IOMUX1_CR_PAD6_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX1_CR_PAD7_OFFSET 0x1C
+ #define IOMUX1_CR_PAD7_MASK (0x0F << 0x1C)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX2_CR_OFFSET 0x208
+ /* */
+ #define IOMUX2_CR_PAD8_OFFSET 0x0
+ #define IOMUX2_CR_PAD8_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX2_CR_PAD9_OFFSET 0x4
+ #define IOMUX2_CR_PAD9_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX2_CR_PAD10_OFFSET 0x8
+ #define IOMUX2_CR_PAD10_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX2_CR_PAD11_OFFSET 0xC
+ #define IOMUX2_CR_PAD11_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX2_CR_PAD12_OFFSET 0x10
+ #define IOMUX2_CR_PAD12_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX2_CR_PAD13_OFFSET 0x14
+ #define IOMUX2_CR_PAD13_MASK (0x0F << 0x14)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX3_CR_OFFSET 0x20C
+ /* */
+ #define IOMUX3_CR_PAD14_OFFSET 0x0
+ #define IOMUX3_CR_PAD14_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX3_CR_PAD15_OFFSET 0x4
+ #define IOMUX3_CR_PAD15_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX3_CR_PAD16_OFFSET 0x8
+ #define IOMUX3_CR_PAD16_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX3_CR_PAD17_OFFSET 0xC
+ #define IOMUX3_CR_PAD17_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX3_CR_PAD18_OFFSET 0x10
+ #define IOMUX3_CR_PAD18_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX3_CR_PAD19_OFFSET 0x14
+ #define IOMUX3_CR_PAD19_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX3_CR_PAD20_OFFSET 0x18
+ #define IOMUX3_CR_PAD20_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX3_CR_PAD21_OFFSET 0x1C
+ #define IOMUX3_CR_PAD21_MASK (0x0F << 0x1C)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX4_CR_OFFSET 0x210
+ /* */
+ #define IOMUX4_CR_PAD22_OFFSET 0x0
+ #define IOMUX4_CR_PAD22_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX4_CR_PAD23_OFFSET 0x4
+ #define IOMUX4_CR_PAD23_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX4_CR_PAD24_OFFSET 0x8
+ #define IOMUX4_CR_PAD24_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX4_CR_PAD25_OFFSET 0xC
+ #define IOMUX4_CR_PAD25_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX4_CR_PAD26_OFFSET 0x10
+ #define IOMUX4_CR_PAD26_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX4_CR_PAD27_OFFSET 0x14
+ #define IOMUX4_CR_PAD27_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX4_CR_PAD28_OFFSET 0x18
+ #define IOMUX4_CR_PAD28_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX4_CR_PAD29_OFFSET 0x1C
+ #define IOMUX4_CR_PAD29_MASK (0x0F << 0x1C)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX5_CR_OFFSET 0x214
+ /* */
+ #define IOMUX5_CR_PAD30_OFFSET 0x0
+ #define IOMUX5_CR_PAD30_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX5_CR_PAD31_OFFSET 0x4
+ #define IOMUX5_CR_PAD31_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX5_CR_PAD32_OFFSET 0x8
+ #define IOMUX5_CR_PAD32_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX5_CR_PAD33_OFFSET 0xC
+ #define IOMUX5_CR_PAD33_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX5_CR_PAD34_OFFSET 0x10
+ #define IOMUX5_CR_PAD34_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX5_CR_PAD35_OFFSET 0x14
+ #define IOMUX5_CR_PAD35_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX5_CR_PAD36_OFFSET 0x18
+ #define IOMUX5_CR_PAD36_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX5_CR_PAD37_OFFSET 0x1C
+ #define IOMUX5_CR_PAD37_MASK (0x0F << 0x1C)
+
+/*Sets whether the MMC/SD Voltage select lines are inverted on entry to the
+ IOMUX structure*/
+#define IOMUX6_CR_OFFSET 0x218
+ /* */
+ #define IOMUX6_CR_VLT_SEL_OFFSET 0x0
+ #define IOMUX6_CR_VLT_SEL_MASK (0x01 << 0x0)
+ /* */
+ #define IOMUX6_CR_VLT_EN_OFFSET 0x1
+ #define IOMUX6_CR_VLT_EN_MASK (0x01 << 0x1)
+ /* */
+ #define IOMUX6_CR_VLT_CMD_DIR_OFFSET 0x2
+ #define IOMUX6_CR_VLT_CMD_DIR_MASK (0x01 << 0x2)
+ /* */
+ #define IOMUX6_CR_VLT_DIR_0_OFFSET 0x3
+ #define IOMUX6_CR_VLT_DIR_0_MASK (0x01 << 0x3)
+ /* */
+ #define IOMUX6_CR_VLT_DIR_1_3_OFFSET 0x4
+ #define IOMUX6_CR_VLT_DIR_1_3_MASK (0x01 << 0x4)
+ /* */
+ #define IOMUX6_CR_SD_LED_OFFSET 0x5
+ #define IOMUX6_CR_SD_LED_MASK (0x01 << 0x5)
+ /* */
+ #define IOMUX6_CR_SD_VOLT_0_OFFSET 0x6
+ #define IOMUX6_CR_SD_VOLT_0_MASK (0x01 << 0x6)
+ /* */
+ #define IOMUX6_CR_SD_VOLT_1_OFFSET 0x7
+ #define IOMUX6_CR_SD_VOLT_1_MASK (0x01 << 0x7)
+ /* */
+ #define IOMUX6_CR_SD_VOLT_2_OFFSET 0x8
+ #define IOMUX6_CR_SD_VOLT_2_MASK (0x01 << 0x8)
+
+/*Configures the MSSIO block*/
+#define MSSIO_BANK4_CFG_CR_OFFSET 0x230
+ /* Sets the PCODE value*/
+ #define MSSIO_BANK4_CFG_CR_BANK_PCODE_OFFSET 0x0
+ #define MSSIO_BANK4_CFG_CR_BANK_PCODE_MASK (0x3F << 0x0)
+ /* Sets the NCODE value*/
+ #define MSSIO_BANK4_CFG_CR_BANK_NCODE_OFFSET 0x6
+ #define MSSIO_BANK4_CFG_CR_BANK_NCODE_MASK (0x3F << 0x6)
+ /* Sets the voltage controls.*/
+ #define MSSIO_BANK4_CFG_CR_VS_OFFSET 0xC
+ #define MSSIO_BANK4_CFG_CR_VS_MASK (0x0F << 0xC)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_0_1_CR_OFFSET 0x234
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_2_3_CR_OFFSET 0x238
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_4_5_CR_OFFSET 0x23C
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_6_7_CR_OFFSET 0x240
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_8_9_CR_OFFSET 0x244
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_10_11_CR_OFFSET 0x248
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_12_13_CR_OFFSET 0x24C
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*Configures the MSSIO block*/
+#define MSSIO_BANK2_CFG_CR_OFFSET 0x250
+ /* Sets the PCODE value*/
+ #define MSSIO_BANK2_CFG_CR_BANK_PCODE_OFFSET 0x0
+ #define MSSIO_BANK2_CFG_CR_BANK_PCODE_MASK (0x3F << 0x0)
+ /* Sets the NCODE value*/
+ #define MSSIO_BANK2_CFG_CR_BANK_NCODE_OFFSET 0x6
+ #define MSSIO_BANK2_CFG_CR_BANK_NCODE_MASK (0x3F << 0x6)
+ /* Sets the voltage controls.*/
+ #define MSSIO_BANK2_CFG_CR_VS_OFFSET 0xC
+ #define MSSIO_BANK2_CFG_CR_VS_MASK (0x0F << 0xC)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_0_1_CR_OFFSET 0x254
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_2_3_CR_OFFSET 0x258
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_4_5_CR_OFFSET 0x25C
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_6_7_CR_OFFSET 0x260
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_8_9_CR_OFFSET 0x264
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_10_11_CR_OFFSET 0x268
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_12_13_CR_OFFSET 0x26C
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_14_15_CR_OFFSET 0x270
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_16_17_CR_OFFSET 0x274
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_18_19_CR_OFFSET 0x278
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_20_21_CR_OFFSET 0x27C
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_22_23_CR_OFFSET 0x280
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*Sets H2F [31:0] Spares out signals*/
+#define MSS_SPARE0_CR_OFFSET 0x2A8
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE0_CR_DATA_OFFSET 0x0
+ #define MSS_SPARE0_CR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Sets H2F [37:32] Spares out signals*/
+#define MSS_SPARE1_CR_OFFSET 0x2AC
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE1_CR_DATA_OFFSET 0x0
+ #define MSS_SPARE1_CR_DATA_MASK (0x3F << 0x0)
+
+/*Read H2F [31:0] Spares out signals*/
+#define MSS_SPARE0_SR_OFFSET 0x2B0
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE0_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE0_SR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Read H2F [37:32] Spares out signals*/
+#define MSS_SPARE1_SR_OFFSET 0x2B4
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE1_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE1_SR_DATA_MASK (0x3F << 0x0)
+
+/*Read F2H [31:0] Spares in1 signals*/
+#define MSS_SPARE2_SR_OFFSET 0x2B8
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE2_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE2_SR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Read F2H [37:32] Spares in1 signals*/
+#define MSS_SPARE3_SR_OFFSET 0x2BC
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE3_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE3_SR_DATA_MASK (0x3F << 0x0)
+
+/*Read F2H [31:0] Spares in2 signals*/
+#define MSS_SPARE4_SR_OFFSET 0x2C0
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE4_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE4_SR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Read F2H [37:32] Spares in2 signals*/
+#define MSS_SPARE5_SR_OFFSET 0x2C4
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE5_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE5_SR_DATA_MASK (0x3F << 0x0)
+
+/*Register for ECO usage*/
+#define SPARE_REGISTER_RW_OFFSET 0x2D0
+ /* No function provided for future ECO use*/
+ #define SPARE_REGISTER_RW_DATA_OFFSET 0x0
+ #define SPARE_REGISTER_RW_DATA_MASK (0xFF << 0x0)
+
+/*Register for ECO usage*/
+#define SPARE_REGISTER_W1P_OFFSET 0x2D4
+ /* No function provided for future ECO use*/
+ #define SPARE_REGISTER_W1P_DATA_OFFSET 0x0
+ #define SPARE_REGISTER_W1P_DATA_MASK (0xFF << 0x0)
+
+/*Register for ECO usage*/
+#define SPARE_REGISTER_RO_OFFSET 0x2D8
+ /* Provides read-back of { W1P RW } registers. No function provided for
+ future ECO use.*/
+ #define SPARE_REGISTER_RO_DATA_OFFSET 0x0
+ #define SPARE_REGISTER_RO_DATA_MASK (0xFFFF << 0x0)
+
+/*Spare signal back to G5C*/
+#define SPARE_PERIM_RW_OFFSET 0x2DC
+ /* Allows the MSS to control the perim_spare_out bits [2] & [6]. No fun
+ ction provided for future ECO use.*/
+ #define SPARE_PERIM_RW_DATA_OFFSET 0x0
+ #define SPARE_PERIM_RW_DATA_MASK (0x03 << 0x0)
+
+/*Unused FIC resets*/
+#define SPARE_FIC_OFFSET 0x2E0
+ /* Connected to spare FIC 0-3 Reset inputs to provide simple RO bits. N
+ o defined use*/
+ #define SPARE_FIC_RESET_OFFSET 0x0
+ #define SPARE_FIC_RESET_MASK (0x0F << 0x0)
+/**************************************************************************
+ *******
+********************TOP LEVEL REGISTER STRUCTURE***************************
+ *******
+***************************************************************************
+ *******/
+
+typedef struct _mss_sysreg
+{
+ /*Register for software use*/
+ __IO uint32_t TEMP0;
+
+ /*Register for software use*/
+ __IO uint32_t TEMP1;
+
+ /*Master clock configuration*/
+ __IO uint32_t CLOCK_CONFIG_CR;
+
+ /*RTC clock divider*/
+ __IO uint32_t RTC_CLOCK_CR;
+
+ /*Fabric Reset mask*/
+ __IO uint32_t FABRIC_RESET_CR;
+
+ /**/
+ __IO uint32_t BOOT_FAIL_CR;
+
+ /* Allows the CPU to fully reset the MSS.
+ When written to 16'hDEAD will cause a full MSS reset. The Reset wil clear
+ this register. The register may be writtent to any value but only a value
+ off 16'hDEAD will cause the reset to happen */
+ __IO uint32_t MSS_RESET_CR;
+
+ /*Configuration lock*/
+ __IO uint32_t CONFIG_LOCK_CR;
+
+ /*Indicates which reset caused the last reset. After a reset occurs reg
+ ister should be read and then zero written to allow the next reset event to
+ be correctly captured.*/
+ __IO uint32_t RESET_SR;
+
+ /*Indicates the device status in particular the state of the FPGA fabri
+ c and the MSS IO banks*/
+ __IO uint32_t DEVICE_STATUS ;
+
+ /*MSS Build Info*/
+ __I uint32_t MSS_BUILD;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_1;
+ __I uint32_t RESERVEDREG32B_2;
+ __I uint32_t RESERVEDREG32B_3;
+ __I uint32_t RESERVEDREG32B_4;
+ __I uint32_t RESERVEDREG32B_5;
+
+ /*U54-1 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_1;
+
+ /*U54-2 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_2;
+
+ /*U54-3 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_3;
+
+ /*U54-4 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_4;
+
+ /*Allows the Ethernet interrupts to be directly routed to the U54 CPUS.
+ */
+ __IO uint32_t FAB_INTEN_MISC;
+ /* Enables the Ethernet MAC0 to interrupt U54_1 directly */
+ #define FAB_INTEN_MAC0_U54_1_EN_OFFSET 0x01U
+ /* Enables the Ethernet MAC0 to interrupt U54_2 directly */
+ #define FAB_INTEN_MAC0_U54_2_EN_OFFSET 0x02U
+ /* Enables the Ethernet MAC1 to interrupt U54_3 directly */
+ #define FAB_INTEN_MAC1_U54_3_EN_OFFSET 0x03U
+ /* Enables the Ethernet MAC1 to interrupt U54_4 directly */
+ #define FAB_INTEN_MAC1_U54_4_EN_OFFSET 0x04U
+ #define FAB_INTEN_MAC0_U54_1_EN_MASK 0x01U
+ #define FAB_INTEN_MAC0_U54_2_EN_MASK 0x02U
+ #define FAB_INTEN_MAC1_U54_3_EN_MASK 0x04U
+ #define FAB_INTEN_MAC1_U54_4_EN_MASK 0x08U
+
+ /*Switches GPIO interrupt from PAD to Fabric GPIO*/
+ __IO uint32_t GPIO_INTERRUPT_FAB_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_6;
+ __I uint32_t RESERVEDREG32B_7;
+ __I uint32_t RESERVEDREG32B_8;
+ __I uint32_t RESERVEDREG32B_9;
+ __I uint32_t RESERVEDREG32B_10;
+ __I uint32_t RESERVEDREG32B_11;
+ __I uint32_t RESERVEDREG32B_12;
+ __I uint32_t RESERVEDREG32B_13;
+ __I uint32_t RESERVEDREG32B_14;
+ __I uint32_t RESERVEDREG32B_15;
+
+ /*"AMP Mode peripheral mapping register. When the register bit is '0' t
+ he peripheral is mapped into the 0x2000000 address range using AXI bus 5 fr
+ om the Coreplex. When the register bit is '1' the peripheral is mapped into
+ the 0x28000000 address range using AXI bus 6 from the Coreplex."*/
+ __IO uint32_t APBBUS_CR;
+
+ /*"Enables the clock to the MSS peripheral. By turning clocks off dynam
+ ic power can be saved. When the clock is off the peripheral should not be
+ accessed*/
+ __IO uint32_t SUBBLK_CLOCK_CR;
+
+ /*"Holds the MSS peripherals in reset. When in reset the peripheral sho
+ uld not be accessed*/
+ __IO uint32_t SOFT_RESET_CR;
+
+ /*Configures how many outstanding transfers the AXI-AHB bridges in fron
+ t off the USB and Crypto blocks should allow. (See Synopsys AXI-AHB bridge
+ documentation)*/
+ __IO uint32_t AHBAXI_CR;
+
+ /*Configures the two AHB-APB bridges on S5 and S6*/
+ __IO uint32_t AHBAPB_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ uint32_t reservedReg32b_16;
+
+ /*MSS Corner APB interface controls*/
+ __IO uint32_t DFIAPB_CR;
+
+ /*GPIO Blocks reset control*/
+ __IO uint32_t GPIO_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ uint32_t reservedReg32b_17;
+
+ /*MAC0 configuration register*/
+ __IO uint32_t MAC0_CR;
+
+ /*MAC1 configuration register*/
+ __IO uint32_t MAC1_CR;
+
+ /*USB Configuration register*/
+ __IO uint32_t USB_CR;
+
+ /*Crypto Mesh control and status register*/
+ __IO uint32_t MESH_CR;
+
+ /*Crypto mesh seed and update rate*/
+ __IO uint32_t MESH_SEED_CR;
+
+ /*ENVM AHB Controller setup*/
+ __IO uint32_t ENVM_CR;
+
+ /*Reserved*/
+ __I uint32_t RESERVED_BC;
+
+ /*QOS Athena USB & MMC Configuration*/
+ __IO uint32_t QOS_PERIPHERAL_CR;
+
+ /*QOS Configuration Coreplex*/
+ __IO uint32_t QOS_CPLEXIO_CR;
+
+ /*QOS configuration DDRC*/
+ __IO uint32_t QOS_CPLEXDDR_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_18;
+ __I uint32_t RESERVEDREG32B_19;
+ __I uint32_t RESERVEDREG32B_20;
+ __I uint32_t RESERVEDREG32B_21;
+ __I uint32_t RESERVEDREG32B_22;
+ __I uint32_t RESERVEDREG32B_23;
+ __I uint32_t RESERVEDREG32B_24;
+ __I uint32_t RESERVEDREG32B_25;
+ __I uint32_t RESERVEDREG32B_26;
+
+ /*Indicates that a master caused a MPU violation. Interrupts via mainte
+ nance interrupt.*/
+ __IO uint32_t MPU_VIOLATION_SR;
+
+ /*Enables interrupts on MPU violations*/
+ __IO uint32_t MPU_VIOLATION_INTEN_CR;
+
+ /*AXI switch decode fail*/
+ __IO uint32_t SW_FAIL_ADDR0_CR;
+
+ /*AXI switch decode fail*/
+ __IO uint32_t SW_FAIL_ADDR1_CR;
+
+ /*Set when an ECC event happens*/
+ __IO uint32_t EDAC_SR;
+
+ /*Enables ECC interrupt on event*/
+ __IO uint32_t EDAC_INTEN_CR;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_MMC;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_DDRC;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_MAC0;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_MAC1;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_USB;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_CAN0;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_CAN1;
+
+ /*"Will Corrupt write data to rams 1E corrupts bit 0 2E bits 1 and 2.In
+ jects Errors into all RAMS in the block as long as the bits are set. Settin
+ g 1E and 2E will inject a 3-bit error"*/
+ __IO uint32_t EDAC_INJECT_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_27;
+ __I uint32_t RESERVEDREG32B_28;
+ __I uint32_t RESERVEDREG32B_29;
+ __I uint32_t RESERVEDREG32B_30;
+ __I uint32_t RESERVEDREG32B_31;
+ __I uint32_t RESERVEDREG32B_32;
+
+ /*Maintenance Interrupt Enable.*/
+ __IO uint32_t MAINTENANCE_INTEN_CR;
+
+ /*PLL Status interrupt enables*/
+ __IO uint32_t PLL_STATUS_INTEN_CR;
+
+ /*Maintenance interrupt indicates fault and status events.*/
+ __IO uint32_t MAINTENANCE_INT_SR;
+
+ /*PLL interrupt register*/
+ __IO uint32_t PLL_STATUS_SR;
+
+ /*Enable to CFM Timer */
+ __IO uint32_t CFM_TIMER_CR;
+
+ /*Miscellaneous Register*/
+ uint32_t MISC_SR;
+
+ /*DLL Interrupt enables*/
+ __IO uint32_t DLL_STATUS_CR;
+
+ /*DLL interrupt register*/
+ __IO uint32_t DLL_STATUS_SR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_33;
+ __I uint32_t RESERVEDREG32B_34;
+
+ /*Puts all the RAMS in that block into low leakage mode. RAM contents a
+ nd Q value preserved.*/
+ __IO uint32_t RAM_LIGHTSLEEP_CR;
+
+ /*Puts all the RAMS in that block into deep sleep mode. RAM contents pr
+ eserved. Powers down the periphery circuits.*/
+ __IO uint32_t RAM_DEEPSLEEP_CR;
+
+ /*Puts all the RAMS in that block into shut down mode. RAM contents not
+ preserved. Powers down the RAM and periphery circuits.*/
+ __IO uint32_t RAM_SHUTDOWN_CR;
+
+ /*Allows each bank of the L2 Cache to be powered down ORed with global
+ shutdown */
+ __IO uint32_t L2_SHUTDOWN_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_35;
+ __I uint32_t RESERVEDREG32B_36;
+ __I uint32_t RESERVEDREG32B_37;
+ __I uint32_t RESERVEDREG32B_38;
+ __I uint32_t RESERVEDREG32B_39;
+ __I uint32_t RESERVEDREG32B_40;
+ __I uint32_t RESERVEDREG32B_41;
+ __I uint32_t RESERVEDREG32B_42;
+ __I uint32_t RESERVEDREG32B_43;
+ __I uint32_t RESERVEDREG32B_44;
+ __I uint32_t RESERVEDREG32B_45;
+ __I uint32_t RESERVEDREG32B_46;
+ __I uint32_t RESERVEDREG32B_47;
+ __I uint32_t RESERVEDREG32B_48;
+ __I uint32_t RESERVEDREG32B_49;
+ __I uint32_t RESERVEDREG32B_50;
+ __I uint32_t RESERVEDREG32B_51;
+ __I uint32_t RESERVEDREG32B_52;
+ __I uint32_t RESERVEDREG32B_53;
+ __I uint32_t RESERVEDREG32B_54;
+ __I uint32_t RESERVEDREG32B_55;
+ __I uint32_t RESERVEDREG32B_56;
+ __I uint32_t RESERVEDREG32B_57;
+ __I uint32_t RESERVEDREG32B_58;
+ __I uint32_t RESERVEDREG32B_59;
+ __I uint32_t RESERVEDREG32B_60;
+ __I uint32_t RESERVEDREG32B_61;
+ __I uint32_t RESERVEDREG32B_62;
+ __I uint32_t RESERVEDREG32B_63;
+ __I uint32_t RESERVEDREG32B_64;
+ __I uint32_t RESERVEDREG32B_65;
+ __I uint32_t RESERVEDREG32B_66;
+ __I uint32_t RESERVEDREG32B_67;
+ __I uint32_t RESERVEDREG32B_68;
+
+ /*Selects whether the peripheral is connected to the Fabric or IOMUX st
+ ructure.*/
+ __IO uint32_t IOMUX0_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX1_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX2_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX3_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX4_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX5_CR;
+
+ /*Sets whether the MMC/SD Voltage select lines are inverted on entry to
+ the IOMUX structure*/
+ __IO uint32_t IOMUX6_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_69;
+ __I uint32_t RESERVEDREG32B_70;
+ __I uint32_t RESERVEDREG32B_71;
+ __I uint32_t RESERVEDREG32B_72;
+ __I uint32_t RESERVEDREG32B_73;
+
+ /*Configures the MSSIO block*/
+ __IO uint32_t MSSIO_BANK4_CFG_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_0_1_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_2_3_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_4_5_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_6_7_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_8_9_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_10_11_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_12_13_CR;
+
+ /*Configures the MSSIO block*/
+ __IO uint32_t MSSIO_BANK2_CFG_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_0_1_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_2_3_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_4_5_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_6_7_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_8_9_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_10_11_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_12_13_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_14_15_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_16_17_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_18_19_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_20_21_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_22_23_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_74;
+ __I uint32_t RESERVEDREG32B_75;
+ __I uint32_t RESERVEDREG32B_76;
+ __I uint32_t RESERVEDREG32B_77;
+ __I uint32_t RESERVEDREG32B_78;
+ __I uint32_t RESERVEDREG32B_79;
+ __I uint32_t RESERVEDREG32B_80;
+ __I uint32_t RESERVEDREG32B_81;
+ __I uint32_t RESERVEDREG32B_82;
+
+ /*Sets H2F [31:0] Spares out signals*/
+ __IO uint32_t MSS_SPARE0_CR;
+
+ /*Sets H2F [37:32] Spares out signals*/
+ __IO uint32_t MSS_SPARE1_CR;
+
+ /*Read H2F [31:0] Spares out signals*/
+ __IO uint32_t MSS_SPARE0_SR;
+
+ /*Read H2F [37:32] Spares out signals*/
+ __IO uint32_t MSS_SPARE1_SR;
+
+ /*Read F2H [31:0] Spares in1 signals*/
+ __IO uint32_t MSS_SPARE2_SR;
+
+ /*Read F2H [37:32] Spares in1 signals*/
+ __IO uint32_t MSS_SPARE3_SR;
+
+ /*Read F2H [31:0] Spares in2 signals*/
+ __IO uint32_t MSS_SPARE4_SR;
+
+ /*Read F2H [37:32] Spares in2 signals*/
+ __IO uint32_t MSS_SPARE5_SR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_83;
+ __I uint32_t RESERVEDREG32B_84;
+
+ /*Register for ECO usage*/
+ __IO uint32_t SPARE_REGISTER_RW;
+
+ /*Register for ECO usage*/
+ __IO uint32_t SPARE_REGISTER_W1P;
+
+ /*Register for ECO usage*/
+ __I uint32_t SPARE_REGISTER_RO;
+
+ /*Spare signal back to G5C*/
+ __IO uint32_t SPARE_PERIM_RW;
+
+ /*Unused FIC resets*/
+ __I uint32_t SPARE_FIC;
+} mss_sysreg_t;
+
+#define SYSREG_ATHENACR_RESET (1U << 0U)
+#define SYSREG_ATHENACR_PURGE (1U << 1U)
+#define SYSREG_ATHENACR_GO (1U << 2U)
+#define SYSREG_ATHENACR_RINGOSCON (1U << 3U)
+#define SYSREG_ATHENACR_COMPLETE (1U << 8U)
+#define SYSREG_ATHENACR_ALARM (1U << 9U)
+#define SYSREG_ATHENACR_BUSERROR (1U << 10U)
+#define SYSREG_SOFTRESET_ENVM (1U << 0U)
+#define SYSREG_SOFTRESET_TIMER (1U << 4U)
+#define SYSREG_SOFTRESET_MMUART0 (1U << 5U)
+#define SYSREG_SOFTRESET_DDRC (1U << 23U)
+#define SYSREG_SOFTRESET_FIC3 (1U << 27U)
+#define SYSREG_SOFTRESET_ATHENA (1U << 28U)
+
+#define SYSREG ((volatile mss_sysreg_t * const) BASE32_ADDR_MSS_SYSREG)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MSS_SYSREG_H*/
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_util.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_util.c
new file mode 100644
index 00000000..cb706149
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_util.c
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_util.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Utility functions
+ *
+ */
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void enable_interrupts(void) {
+ __enable_irq();
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+uint64_t disable_interrupts(void) {
+ uint64_t psr;
+ psr = read_csr(mstatus);
+ __disable_irq();
+ return(psr);
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void restore_interrupts(uint64_t saved_psr) {
+ write_csr(mstatus, saved_psr);
+}
+
+/*------------------------------------------------------------------------------
+ * Disable all interrupts.
+ */
+void __disable_irq(void)
+{
+ clear_csr(mstatus, MSTATUS_MIE);
+ clear_csr(mstatus, MSTATUS_MPIE);
+}
+
+void __disable_all_irqs(void)
+{
+ __disable_irq();
+ write_csr(mie, 0x00U);
+ write_csr(mip, 0x00);
+}
+
+/*------------------------------------------------------------------------------
+ * Enable all interrupts.
+ */
+void __enable_irq(void)
+{
+ set_csr(mstatus, MSTATUS_MIE); /* mstatus Register- Machine Interrupt Enable */
+}
+
+/*------------------------------------------------------------------------------
+ * Enable particular local interrupt
+ */
+void __enable_local_irq(uint8_t local_interrupt)
+{
+ if((local_interrupt > (int8_t)0) && (local_interrupt <= LOCAL_INT_MAX))
+ {
+ set_csr(mie, (0x1LLU << (int8_t)(local_interrupt + 16U))); /* mie Register- Machine Interrupt Enable Register */
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Disable particular local interrupt
+ */
+void __disable_local_irq(uint8_t local_interrupt)
+{
+ if((local_interrupt > (int8_t)0) && (local_interrupt <= LOCAL_INT_MAX))
+ {
+ clear_csr(mie, (0x1LLU << (int8_t)(local_interrupt + 16U))); /* mie Register- Machine Interrupt Enable Register */
+ }
+}
+
+/**
+ * readmcycle(void)
+ * @return returns the mcycle count from hart CSR
+ */
+uint64_t readmcycle(void)
+{
+ return (read_csr(mcycle));
+}
+
+void sleep_ms(uint64_t msecs)
+{
+ uint64_t starttime = readmtime();
+ volatile uint64_t endtime = 0U;
+
+ while(endtime < (starttime+msecs)) {
+ endtime = readmtime();
+ }
+}
+
+/**
+ * sleep_cycles(uint64_t ncycles)
+ * @param number of cycles to sleep
+ */
+void sleep_cycles(uint64_t ncycles)
+{
+ uint64_t starttime = readmcycle();
+ volatile uint64_t endtime = 0U;
+
+ while(endtime < (starttime + ncycles)) {
+ endtime = readmcycle();
+ }
+}
+
+/**
+ * get_program_counter(void)
+ * @return returns the program counter
+ */
+__attribute__((aligned(16))) uint64_t get_program_counter(void)
+{
+ uint64_t prog_counter;
+ asm volatile ("auipc %0, 0" : "=r"(prog_counter));
+ return (prog_counter);
+}
+
+/**
+ * get_stack_pointer(void)
+ * @return Return the stack pointer
+ */
+uint64_t get_stack_pointer(void)
+{
+ uint64_t stack_pointer;
+ asm volatile ("addi %0, sp, 0" : "=r"(stack_pointer));
+ return (stack_pointer);
+}
+
+/**
+ * Return the tp register
+ * The tp register holds the value of the Hart Common memory HLS once not in an
+ * interrupt. If the tp value is used in an interrupt, it is saved first and
+ * restored on exit. This conforms to OpenSBI implementation.
+ *
+ * @return returns the tp register value
+ */
+uint64_t get_tp_reg(void)
+{
+ uint64_t tp_reg_val;
+ asm volatile ("addi %0, tp, 0" : "=r"(tp_reg_val));
+ return (tp_reg_val);
+}
+
+/**
+ * mpfs_sync_bool_compare_and_swap()
+ * this works on the E51 / U54s, and operates equivalently to the
+ * __sync_bool_compare_and_swap() intrinsic.
+ * @param ptr
+ * @param oldval
+ * @param newval
+ * @return
+ */
+bool mpfs_sync_bool_compare_and_swap(volatile long *ptr, long oldval, long newval)
+{
+ static long lock = 0;
+ bool result = false;
+
+ if (!__sync_lock_test_and_set(&lock, 1)) { // amoswap.d.aq
+ if (*ptr == oldval) {
+ *ptr = newval;
+ }
+
+ __sync_lock_release(&lock); // fence iorw,ow; ampswap.d
+ result = true;
+ }
+
+ return result;
+}
+
+/**
+ * mpfs_sync_val_compare_and_swap()
+ * this works on the E51 / U54s, and operates equivalently to the
+ * __sync_val_compare_and_swap() intrinsic. It works by using a separate
+ * static lock, and then emulating the behaviour of the lr.w.aq instruction
+ * Required as lr/sr instructions are not supported on the E51 and are only
+ * supported on L1 cached back memory types. These limitations are not present
+ * with this function.
+ * @param ptr
+ * @param oldval
+ * @param newval
+ */
+long mpfs_sync_val_compare_and_swap(volatile long *ptr, long oldval, long newval)
+{
+ long result = *ptr;
+
+ (void)mpfs_sync_bool_compare_and_swap(ptr, oldval, newval);
+
+ return result;
+}
+
+#ifdef PRINTF_DEBUG_SUPPORTED
+void display_address_of_interest(uint64_t * address_of_interest, int nb_locations) {
+ uint64_t * p_addr_of_interest = address_of_interest;
+ int inc;
+ mpfs_printf(" Displaying address of interest: 0x%lx\n", p_addr_of_interest);
+
+ for (inc = 0U; inc < nb_locations; ++inc) {
+ mpfs_printf(" address of interest: 0x%lx: 0x%lx\n", p_addr_of_interest, *p_addr_of_interest);
+ p_addr_of_interest = p_addr_of_interest + 8;
+ }
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_util.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_util.h
new file mode 100644
index 00000000..a418faae
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/mss_util.h
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_util.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MACROs defines and prototypes associated with utility functions
+ *
+ */
+#ifndef MSS_UTIL_H
+#define MSS_UTIL_H
+
+#include
+#include
+#include "encoding.h"
+#include "mss_hart_ints.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Useful macros
+ */
+#define WRITE_REG8(x, y) (*((volatile uint8_t *)(x)) = (y))
+#define READ_REG8(x) (*((volatile uint8_t *)(x)))
+
+#define WRITE_REG32(x, y) (*((volatile uint32_t *)(x)) = (y))
+#define READ_REG32(x) (*((volatile uint32_t *)(x)))
+
+#define WRITE_REG64(x, y) (*((volatile uint64_t *)(x)) = (y))
+#define READ_REG64(x) (*((volatile uint64_t *)(x)))
+
+/*
+ * return mcycle
+ */
+uint64_t readmcycle(void);
+
+void sleep_ms(uint64_t msecs);
+void sleep_cycles(uint64_t ncycles);
+
+
+uint64_t get_stack_pointer(void);
+uint64_t get_tp_reg(void);
+uint64_t get_program_counter(void) __attribute__((aligned(16)));
+
+#ifdef MPFS_PRINTF_DEBUG_SUPPORTED
+void display_address_of_interest(uint64_t * address_of_interest, int nb_locations);
+#endif
+
+void exit_simulation(void);
+
+void enable_interrupts(void);
+uint64_t disable_interrupts(void);
+void restore_interrupts(uint64_t saved_psr);
+void __disable_irq(void);
+void __disable_all_irqs(void);
+void __enable_irq(void);
+void __enable_local_irq(uint8_t local_interrupt);
+void __disable_local_irq(uint8_t local_interrupt);
+
+bool mpfs_sync_bool_compare_and_swap(volatile long *ptr, long oldval, long newval);
+long mpfs_sync_val_compare_and_swap(volatile long *ptr, long oldval, long newval);
+
+static inline void spinunlock(volatile long *lock)
+{
+ *lock = 0;
+}
+
+static inline void spinlock(volatile long *lock)
+{
+ while(!mpfs_sync_bool_compare_and_swap(lock, 0, 1))
+ {
+ /* add yield if OS */
+ }
+ *lock = 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_UTIL_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_cfm.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_cfm.c
new file mode 100644
index 00000000..3ad42107
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_cfm.c
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mpfs_hal/mss_hal.h"
+#include "mss_cfm.h"
+
+/***************************************************************************//**
+ * See mss_cfm.h for description of this function.
+ */
+uint8_t MSS_CFM_control_start(void)
+{
+
+ /* Writing a 1, to this causes measurement circuitry to start. */
+ CFM_REG->controlReg |= 1;
+
+ return (CFM_REG->controlReg & CFM_CONTROL_REG_START_MASK);
+
+}
+
+
+uint8_t MSS_CFM_control_stop(void)
+{
+
+ /* Writing a 1, to this causes measurement circuitry to start. */
+ CFM_REG->controlReg |= (1 << CFM_CONTROL_REG_STOP_BITS_SHIFT);
+
+ return (CFM_REG->controlReg & CFM_CONTROL_REG_START_MASK);
+
+}
+
+
+
+cfm_error_id_t MSS_CLF_clk_configuration(
+ uint8_t clkSel,
+ uint8_t refsel0,
+ uint8_t refsel1,
+ uint8_t monSEL,
+ uint8_t monEN
+ )
+{
+
+ /* Reset the register. */
+ CFM_REG->clkselReg = 0;
+
+ /* Some error checking on configuration values. */
+ if(clkSel > CFM_CLK_SEL_MASK)
+ return ERROR_INVALID_CLK_SELECTION_GROUP;
+
+ if(refsel0 > CFM_CLK_REFSEL0_MASK)
+ return ERROR_INVALID_REF_SEL0;
+
+ if(refsel1 > CFM_CLK_REFSEL1_MASK)
+ return ERROR_INVALID_REF_SEL1;
+
+ if(monSEL > CFM_CLK_MONSEL_MASK)
+ return ERROR_INVALID_CHANNEL_DRIVE_CLK_MONITOR;
+
+
+ CFM_REG->clkselReg |= (clkSel & CFM_CLK_SEL_MASK);
+
+ if(refsel0)
+ CFM_REG->clkselReg |= (uint32_t)(refsel0 << CFM_CLK_REFSEL0SHIFT);
+
+ if(refsel1)
+ CFM_REG->clkselReg |= (uint32_t)(refsel1 << CFM_CLK_REFSEL1SHIFT);
+
+ if(monSEL)
+ CFM_REG->clkselReg |= (uint32_t)(monSEL << CFM_CLK_MONSEL_SHIFT);
+
+
+ if(monEN)
+ CFM_REG->clkselReg |= (uint32_t)(monEN << CFM_CLK_MONEN_SHIFT);
+
+
+ return CFM_OK;
+
+}
+
+
+void MSS_CFM_runtime_register(uint32_t referenceCount)
+{
+
+ /*Sets how many runtime reference clock cycles the frequency and time
+ * measurement shold be made for.. */
+ CFM_REG->runtimeReg = (referenceCount & CFM_RUNTIME_REG_MASK);
+
+ return;
+}
+
+
+void MSS_CFM_channel_mode(cfmChannelMode chMode)
+{
+
+
+ uint32_t chConfiguration = 0;
+
+ chConfiguration |= (chMode.channel0 & CFM_CHANNEL_MODE_MASK) << CFM_CH0_SHIFT_MASK;
+ chConfiguration |= (chMode.channel1 & CFM_CHANNEL_MODE_MASK) << CFM_CH1_SHIFT_MASK;
+ chConfiguration |= (chMode.channel2 & CFM_CHANNEL_MODE_MASK) << CFM_CH2_SHIFT_MASK;
+ chConfiguration |= (chMode.channel3 & CFM_CHANNEL_MODE_MASK) << CFM_CH3_SHIFT_MASK;
+ chConfiguration |= (chMode.channel4 & CFM_CHANNEL_MODE_MASK) << CFM_CH4_SHIFT_MASK;
+ chConfiguration |= (chMode.channel5 & CFM_CHANNEL_MODE_MASK) << CFM_CH5_SHIFT_MASK;
+ chConfiguration |= (chMode.channel6 & CFM_CHANNEL_MODE_MASK) << CFM_CH6_SHIFT_MASK;
+ chConfiguration |= (chMode.channel7 & CFM_CHANNEL_MODE_MASK) << CFM_CH7_SHIFT_MASK;
+
+ CFM_REG->modelReg = chConfiguration;
+
+
+ return;
+}
+
+cfm_error_id_t MSS_CFM_get_count(cfm_count_id_t ch, uint32_t *count)
+{
+
+ if(count == NULL)
+ return ERROR_NULL_VALUE;
+
+ *count = 0;
+
+ if(CFM_REG->controlReg & CFM_CONTROL_REG_BUSY_MASK)
+ return ERROR_INVALID_CFM_BUSY;
+
+ switch(ch)
+ {
+ case CFM_COUNT_0:
+ *count = CFM_REG->count0;
+ break;
+
+ case CFM_COUNT_1:
+ *count = CFM_REG->count1;
+ break;
+
+ case CFM_COUNT_2:
+ *count = CFM_REG->count2;
+ break;
+
+ case CFM_COUNT_3:
+ *count = CFM_REG->count3;
+ break;
+
+ case CFM_COUNT_4:
+ *count = CFM_REG->count4;
+ break;
+
+ case CFM_COUNT_5:
+ *count = CFM_REG->count5;
+ break;
+
+ case CFM_COUNT_6:
+ *count = CFM_REG->count6;
+ break;
+
+ case CFM_COUNT_7:
+ *count = CFM_REG->count7;
+ break;
+
+ default:
+ return 11;
+
+
+ }
+
+ return CFM_OK;
+
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_cfm.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_cfm.h
new file mode 100644
index 00000000..1429da6c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_cfm.h
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire MSS Frequency Meter Bare Metal Driver.
+ The MSS Clock Frequency Meter (CFM) block is used to support test of the
+ DLL's within the MSS. All functional clocks are connected to the CFM block.
+
+ The frequency meter can be configured to measure time or frequency, time
+ allowing items such as PLL lock times to be tested and frequency to test
+ oscillator frequencies.
+
+ Upto 8 circuit counters are implemented.
+
+ @section intro_sec Introduction
+
+ *//*=========================================================================*/
+#ifndef __COREPLEX_PLATFORM_CFM_H_
+#define __COREPLEX_PLATFORM_CFM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/* CFM Register base address. */
+#define CFM_REG_BASE 0x20006000
+
+/***************************************************************************//**
+ The __cfm_count_id_t enumeration is used to identify the channel used.
+ */
+typedef enum __cfm_count_id
+{
+ CFM_COUNT_0 = 0,
+ CFM_COUNT_1,
+ CFM_COUNT_2,
+ CFM_COUNT_3,
+ CFM_COUNT_4,
+ CFM_COUNT_5,
+ CFM_COUNT_6,
+ CFM_COUNT_7,
+ cfm_lastCH,
+} cfm_count_id_t;
+
+
+
+/***************************************************************************//**
+ The cfm_channel_mode enumeration is used to specify the channel mode.
+ */
+typedef enum __cfm_channel_mode
+{
+ CFM_CH_DISABLED = 0,
+ CFM_CH_FREQUENCY_MODE,
+ CFM_CH_RESERVER,
+ CFM_CH_TIMER_MODE,
+ CFM_CH_lastmd
+} cfm_channel_mode;
+
+
+
+typedef enum __cfm_error_id_t
+{
+ CFM_OK = 0,
+ ERROR_INVALID_CLK_SELECTION_GROUP,
+ ERROR_INVALID_REF_SEL0,
+ ERROR_INVALID_REF_SEL1,
+ ERROR_INVALID_CHANNEL_DRIVE_CLK_MONITOR,
+ ERROR_INVALID_CFM_BUSY,
+
+ ERROR_NULL_VALUE,
+
+ ERROR_CFMLAST_ID
+} cfm_error_id_t;
+
+
+typedef struct _cfmRegs
+{
+ __IO uint32_t controlReg; /* CFM Control Register */
+ __IO uint32_t clkselReg; /* Clock Selection Register */
+ __IO uint32_t runtimeReg; /* Reference Count Value */
+ __IO uint32_t modelReg; /* Sets the measurement mode */
+
+ __I uint32_t count0; /* Count x value */
+ __I uint32_t count1;
+ __I uint32_t count2;
+ __I uint32_t count3;
+ __I uint32_t count4;
+ __I uint32_t count5;
+ __I uint32_t count6;
+ __I uint32_t count7;
+
+ __I uint32_t reserved[4]; /*Reserved registers, padding structure */
+
+
+}CFM;
+
+
+#define CFM_REG ((CFM *)CFM_REG_BASE)
+
+typedef struct _cfmChannelMode
+{
+ uint8_t channel0; /* Channel x mode */
+ uint8_t channel1; /* Channel x mode */
+ uint8_t channel2; /* Channel x mode */
+ uint8_t channel3; /* Channel x mode */
+ uint8_t channel4; /* Channel x mode */
+ uint8_t channel5; /* Channel x mode */
+ uint8_t channel6; /* Channel x mode */
+ uint8_t channel7; /* Channel x mode */
+
+}cfmChannelMode;
+
+#define CFM_CONTROL_REG_BUSY_MASK 0x01U
+#define CFM_CONTROL_REG_START_MASK 0x01U
+#define CFM_CONTROL_REG_STOP_BITS_SHIFT 0x01U
+
+#define CFM_CLK_SEL_MASK 0x07U
+
+
+#define CFM_CLK_REFSEL0_MASK 0x01U
+#define CFM_CLK_REFSEL0SHIFT 0x04U
+
+
+#define CFM_CLK_REFSEL1_MASK 0x01U
+#define CFM_CLK_REFSEL1SHIFT 0x05U
+
+
+#define CFM_CLK_MONSEL_MASK 0x07U
+#define CFM_CLK_MONSEL_SHIFT 0x08U
+
+
+
+#define CFM_CLK_MONEN_MASK 0x01
+#define CFM_CLK_MONEN_SHIFT 11U
+
+#define CFM_RUNTIME_REG_MASK 0xFFFFFFU
+
+#define CFM_CHANNEL_MODE_MASK 0x3U
+
+#define CFM_CH0_SHIFT_MASK 0x00U
+#define CFM_CH1_SHIFT_MASK 0x02U
+#define CFM_CH2_SHIFT_MASK 0x04U
+#define CFM_CH3_SHIFT_MASK 0x06U
+#define CFM_CH4_SHIFT_MASK 0x08U
+#define CFM_CH5_SHIFT_MASK 0x0AU
+#define CFM_CH6_SHIFT_MASK 0x0CU
+#define CFM_CH7_SHIFT_MASK 0x0EU
+
+
+
+/*****************************************************************************
+ * CFM Function Prototypes
+ *******************************************************************************
+ */
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_control_start() function causes the measurement circuitry
+ to start. This state of 'busy' will clear which measurement is complete.
+
+
+ @param None
+
+ @return
+ Busy state
+
+ Example:
+ The following call will start the CFM
+ @code
+ MSS_CFM_control_start( );
+ @endcode
+ */
+uint8_t MSS_CFM_control_start(void);
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_control_stop() function causes the measurement circuitry
+ to stop.
+
+
+ @param None
+
+
+ @return uint8_t
+ Returns the busy flag.
+
+
+ Example:
+ The following call will stop the CFM
+ @code
+ MSS_CFM_control_stop( );
+ @endcode
+ */
+uint8_t MSS_CFM_control_stop(void);
+
+
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CLF_clk_configuration() function is used to configure the clock
+ selection register.
+
+ @param clkSel
+ Selects which group of clock inputs are selected by the channels, control
+ the input multiplexer.
+
+ @param refsel0
+ Selects the reference input, 0=clkref1 / 1=clkref2
+
+ @param refsel1
+ When in timer mode allows ATPG (corners) / clkref3 clock input to clock
+ the channel counters. This clock input is expected to be sourced from an
+ on-chip PLL to support at-speed testing. This allows the timer to clocked
+ off a much higher clock frequency that the reference counter that is limited
+ to 100Mhz.
+
+ @param monSEL
+ Selects which channel drives the clock monitor output 0-7.
+
+
+ @param monEN
+ Enables the clock monitor output.
+
+
+ @return
+ cfm_error_id_t
+
+ Example:
+ The following call will configure clk 0, using clkref1, channel zero drives
+ the clock monitor and enable the clock monitor output.
+ @code
+ MSS_GPIO_config( 0, 0, 0, 0, 1 );
+ @endcode
+ */
+cfm_error_id_t MSS_CLF_clk_configuration(
+ uint8_t clkSel,
+ uint8_t refsel0,
+ uint8_t refsel1,
+ uint8_t monSEL,
+ uint8_t monEN
+ );
+
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_runtime_register() function is used to set how many reference
+ clock cycles the frequency and time measurement should be made.
+ The register does NOT change during oepration
+
+ @param refcount
+ The reference count value.
+
+ */
+void MSS_CFM_runtime_register(
+ uint32_t referenceCount
+ );
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_channel_mode() function is used to set the measurement mode for
+ the specified channel.
+ 2'b00: Disabled
+ 2'b01: Frequency Mode
+ 2'b11: Timer Mode
+ 2'b10: Reserved
+
+ @param cfmChannelMode
+ Configuration structure for each channel
+
+ @return
+ None
+
+ */
+void MSS_CFM_channel_mode(cfmChannelMode chMode);
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_get_count() function is used to get the count value.
+ Block must not be busy.
+
+ @param ch
+ The channel ID to return the count for.
+
+ @param count
+ The count for the channel register.
+
+ @return
+ cfm_error_id_t
+
+ Example:
+ The following call will return the value in count register. channel 0
+
+ @code
+ MSS_CFM_get_count();
+ @endcode
+ */
+cfm_error_id_t MSS_CFM_get_count(cfm_count_id_t ch, uint32_t *count);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __COREPLEX_PLATFORM_CFM_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr.c
new file mode 100644
index 00000000..6dce7432
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr.c
@@ -0,0 +1,4692 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief DDR related code
+ *
+ */
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#ifdef DDR_SUPPORT
+#include "mss_ddr_debug.h"
+#include "simulation.h"
+#ifdef FABRIC_NOISE_TEST
+#include "drivers/mss_gpio/mss_gpio.h"
+#endif
+
+/*******************************************************************************
+ * Local Defines
+ */
+/* This string is updated if any change to ddr driver */
+#define DDR_DRIVER_VERSION_STRING "0.2.003"
+/* Version | Comment */
+/* 0.2.003 | Updated SEG setup to match Libero 12.7, Removed warnings, */
+/* | shortened timeout in mtc_test */
+/* 0.2.002 | MTC_test() update -added more tests */
+/* 0.2.001 | Reverted ADDCMD training command */
+/* 0.2.000 | RPC166 now does short retrain by default */
+/* 0.1.009 | Removed AXI overrides. Agreed better placed in */
+/* | mss_sw_config.h util until corrected in configurator v3.0 */
+/* 0.1.008 | Added manual addcmd traing for all variants */
+/* 0.1.007 | Added some updates from SVG and DCT. Also overrides AXI */
+/* | ranges if incorrectly set (Liber0 v12.5 and Liber0 v12.6 */
+/* 0.1.006 | Added tuning for rpc166, read lane FIFO alignement */
+/* 0.1.005 | Added parameter to modify rpc166, lane out of sync on read */
+/* 0.1.004 | Corrected default RPC220 setting so dq/dqs window centred */
+/* 0.1.003 | refclk_phase correctly masked during bclk sclk sw training */
+/* 0.1.002 | Reset modified- corrects softreset on retry issue (1.8.x) */
+/* 0.1.001 | Reset modified- corrects softreset on retry issue (1.7.2) */
+/* 0.0.016 | Added #define DDR_FULL_32BIT_NC_CHECK_EN to mss_ddr.h */
+/* 0.0.016 | updated mss_ddr_debug.c with additio of 32-bit write test */
+/* 0.0.015 | DDR3L - Use Software Bclk Sclk training */
+/* 0.0.014 | DDR3 and DDR update to sync with SVG proven golden version */
+/* 0.0.013 | Added code to turn off DM if DDR4 and using ECC */
+/* 0.0.012 | Added support for turning off unused I/O from Libero */
+
+/*
+ * Calibration data records calculated write calibration values during training
+ */
+mss_ddr_calibration calib_data;
+
+/* rx lane FIFO used for tuning */
+#if (TUNE_RPC_166_VALUE == 1)
+static uint32_t rpc_166_fifo_offset;
+#endif
+
+/*
+ * This string is used as a quick sanity check of write/read to DDR.
+ * The memory test core is used for more comprehensive testing during and
+ * post calibration
+ */
+#ifdef DDR_SANITY_CHECKS_EN
+static const uint32_t test_string[] = {
+ 0x12345678,23211234,0x35675678,0x4456789,0x56789123,0x65432198,\
+ 0x45673214,0xABCD1234,0x99999999,0xaaaaaaaa,0xbbbbbbbb,0xcccccccc,\
+ 0xdddddddd,0xeeeeeeee,0x12121212,0x12345678};
+#endif
+
+/*******************************************************************************
+ * external functions
+ */
+#ifdef DEBUG_DDR_INIT
+extern mss_uart_instance_t *g_debug_uart;
+extern uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt);
+#endif
+
+/* Use to record instance of errors during calibration */
+static uint32_t ddr_error_count;
+#ifdef SWEEP_ENABLED
+uint8_t sweep_results[MAX_NUMBER_DPC_VS_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_H_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_V_GEN_SWEEPS]\
+ [MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS]\
+ [MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS];
+#define TOTAL_SWEEPS (MAX_NUMBER_DPC_H_GEN_SWEEPS*MAX_NUMBER_DPC_H_GEN_SWEEPS*\
+ MAX_NUMBER_DPC_V_GEN_SWEEPS*MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS*\
+ MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS)
+#endif
+
+/*******************************************************************************
+ * Local function declarations
+ */
+static uint32_t ddr_setup(void);
+static void init_ddrc(void);
+static uint8_t write_calibration_using_mtc(uint8_t num_of_lanes_to_calibrate);
+/*static uint8_t mode_register_write(uint32_t MR_ADDR, uint32_t MR_DATA);*/
+static uint8_t MTC_test(uint8_t mask, uint64_t start_address, uint32_t size, MTC_PATTERN pattern, MTC_ADD_PATTERN add_pattern, uint32_t *error);
+#ifdef VREFDQ_CALIB
+static uint8_t FPGA_VREFDQ_calibration_using_mtc(void);
+static uint8_t VREFDQ_calibration_using_mtc(void);
+#endif
+#ifdef DDR_SANITY_CHECKS_EN
+static uint8_t rw_sanity_chk(uint64_t * address, uint32_t count);
+static uint8_t mtc_sanity_check(uint64_t start_address);
+#endif
+#ifdef SET_VREF_LPDDR4_MODE_REGS
+static uint8_t mode_register_write(uint32_t MR_ADDR, uint32_t MR_DATA);
+#endif
+#ifdef DDR_SANITY_CHECKS_EN
+static uint8_t memory_tests(void);
+#endif
+static void ddr_off_mode(void);
+static void set_ddr_mode_reg_and_vs_bits(uint32_t dpc_bits);
+static void set_ddr_rpc_regs(DDR_TYPE ddr_type);
+static uint8_t get_num_lanes(void);
+static void load_dq(uint8_t lane);
+static uint8_t use_software_bclk_sclk_training(DDR_TYPE ddr_type);
+static void config_ddr_io_pull_up_downs_rpc_bits(DDR_TYPE ddr_type);
+#ifdef SWEEP_ENABLED
+static uint8_t get_best_sweep(sweep_index *good_index);
+#endif
+#ifdef MANUAL_ADDCMD_TRAINIG
+static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index);
+#endif
+
+/*******************************************************************************
+ * External function declarations
+ */
+extern void delay(uint32_t n);
+
+#ifdef DEBUG_DDR_INIT
+extern mss_uart_instance_t *g_debug_uart;
+#ifdef DEBUG_DDR_DDRCFG
+void debug_read_ddrcfg(void);
+#endif
+#endif
+
+#ifdef FABRIC_NOISE_TEST
+uint32_t fabric_noise_en = 1;
+uint32_t fabric_noise_en_log = 1;
+uint32_t num_of_noise_blocks_en = 3; /* do not set less than 1 */
+uint32_t noise_ena = 0x0;
+#endif
+
+/*******************************************************************************
+ * Instance definitions
+ */
+
+/*******************************************************************************
+ * Public Functions - API
+ ******************************************************************************/
+
+
+/***************************************************************************//**
+ * ddr_state_machine(DDR_SS_COMMAND)
+ * call this routine if you do not require the state machine
+ *
+ * @param ddr_type
+ */
+uint32_t ddr_state_machine(DDR_SS_COMMAND command)
+{
+ static DDR_SM_STATES ddr_state;
+ static uint32_t return_status;
+ if (command == DDR_SS__INIT)
+ {
+ ddr_state = DDR_STATE_INIT;
+ }
+ SIM_FEEDBACK0(100U + ddr_state);
+ SIM_FEEDBACK1(ddr_state);
+ switch (ddr_state)
+ {
+ default:
+ case DDR_STATE_INIT:
+ ddr_state = DDR_STATE_TRAINING;
+ return_status = 0U;
+ break;
+
+ case DDR_STATE_TRAINING:
+ /*
+ * We stay in this state until finished training/fail training
+ */
+ return_status = ddr_setup();
+ break;
+
+ case DDR_STATE_MONITOR:
+ /*
+ * 1. Periodically check DDR access
+ * 2. Run any tests, as directed
+ */
+// return_status = ddr_monitor();
+ break;
+ }
+ SIM_FEEDBACK1(0xFF000000UL + return_status);
+ return (return_status);
+}
+
+
+/***************************************************************************//**
+ * ddr_setup(DDR_TYPE ddr_type)
+ * call this routine if you do not require the state machine
+ *
+ * @param ddr_type
+ */
+static uint32_t ddr_setup(void)
+{
+ static DDR_TRAINING_SM ddr_training_state = DDR_TRAINING_INIT;
+ static uint32_t error;
+ static uint32_t timeout;
+#ifdef DEBUG_DDR_INIT
+ static uint32_t addr_cmd_value;
+ static uint32_t bclk_sclk_offset_value;
+ static uint32_t dpc_vrgen_v_value;
+ static uint32_t dpc_vrgen_h_value;
+ static uint32_t dpc_vrgen_vs_value;
+#endif
+#ifdef SWEEP_ENABLED
+ static SWEEP_STATES sweep_state = INIT_SWEEP;
+#endif
+ static uint32_t retry_count;
+ static uint32_t write_latency;
+ static uint32_t tip_cfg_params;
+ static uint32_t dpc_bits;
+ static uint8_t last_sweep_status;
+#if (TUNE_RPC_166_VALUE == 1)
+ static uint8_t num_rpc_166_retires = 0U;
+#endif
+#ifdef MANUAL_ADDCMD_TRAINIG
+ static uint8_t refclk_offset;
+ static uint8_t refclk_sweep_index =0xFU;
+#endif
+ static uint32_t bclk_answer = 0U;
+ DDR_TYPE ddr_type;
+ uint32_t ret_status = 0U;
+ uint8_t number_of_lanes_to_calibrate;
+
+ ddr_type = LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK;
+
+ SIM_FEEDBACK0(200U + ddr_training_state);
+ SIM_FEEDBACK1(0U);
+
+ switch (ddr_training_state)
+ {
+ case DDR_TRAINING_INIT:
+ tip_cfg_params = LIBERO_SETTING_TIP_CFG_PARAMS;
+ dpc_bits = LIBERO_SETTING_DPC_BITS ;
+ write_latency = LIBERO_SETTING_CFG_WRITE_LATENCY_SET;
+#if (TUNE_RPC_166_VALUE == 1)
+ rpc_166_fifo_offset = DEFAULT_RPC_166_VALUE;
+#endif
+#ifdef MANUAL_ADDCMD_TRAINIG
+ refclk_offset = LIBERO_SETTING_MAX_MANUAL_REF_CLK_PHASE_OFFSET + 1U;
+#endif
+#ifdef SWEEP_ENABLED
+ sweep_state = INIT_SWEEP;
+#endif
+ ddr_error_count = 0U;
+ error = 0U;
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ retry_count = 0U;
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r Start training. TIP_CFG_PARAMS:"\
+ , LIBERO_SETTING_TIP_CFG_PARAMS);
+#endif
+#ifdef SWEEP_ENABLED
+ addr_cmd_value = LIBERO_SETTING_TIP_CFG_PARAMS\
+ & ADDRESS_CMD_OFFSETT_MASK;
+ bclk_sclk_offset_value = (LIBERO_SETTING_TIP_CFG_PARAMS\
+ & BCLK_SCLK_OFFSET_MASK)>>BCLK_SCLK_OFFSET_SHIFT;
+ dpc_vrgen_v_value = (LIBERO_SETTING_DPC_BITS & \
+ BCLK_DPC_VRGEN_V_MASK)>>BCLK_DPC_VRGEN_V_SHIFT;
+ dpc_vrgen_h_value = (LIBERO_SETTING_DPC_BITS & \
+ BCLK_DPC_VRGEN_H_MASK)>>BCLK_DPC_VRGEN_H_SHIFT;
+ dpc_vrgen_vs_value = (LIBERO_SETTING_DPC_BITS & \
+ BCLK_DPC_VRGEN_VS_MASK)>>BCLK_DPC_VRGEN_VS_SHIFT;
+#endif
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ break;
+ case DDR_TRAINING_FAIL_SM2_VERIFY:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM2_VERIFY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_VERIFY:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_VERIFY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_DQ_DQS:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_DQ_DQS: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_RDGATE:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_RDGATE: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_WRLVL:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_WRLVL: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_ADDCMD:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_ADDCMD: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_BCLKSCLK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r BCLKSCLK_SWY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_BCLKSCLK_SW:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r BCLKSCLK_SW: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_FULL_32BIT_NC_CHECK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r 32BIT_NC_CHECK: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_32BIT_CACHE_CHECK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r 32BIT_CACHE_CHECK: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_MIN_LATENCY:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r MIN_LATENCY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_START_CHECK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r START_CHECK: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_PLL_LOCK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r PLL LOCK FAIL: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_DDR_SANITY_CHECKS:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r DDR_SANITY_CHECKS FAIL: ",\
+ addr_cmd_value);
+ ddr_training_state = DDR_TRAINING_FAIL;
+#endif
+ break;
+ case DDR_SWEEP_AGAIN:
+ retry_count++;
+ last_sweep_status = CALIBRATION_PASSED;
+ #ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR_SWEEP_AGAIN: ",\
+ ddr_training_state);
+ #endif
+ ddr_training_state = DDR_CHECK_TRAINING_SWEEP;
+ break;
+ case DDR_TRAINING_FAIL:
+#ifdef DEBUG_DDR_INIT
+ {
+ tip_register_status (g_debug_uart);
+ (void)uprint32(g_debug_uart, "\n\r ****************************************************", 0U);
+
+ }
+#endif
+ retry_count++;
+ if(last_sweep_status != CALIBRATION_SUCCESS)
+ {
+ last_sweep_status = CALIBRATION_FAILED;
+ }
+ #ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR_TRAINING_FAIL: ",\
+ ddr_training_state);
+ (void)uprint32(g_debug_uart, "\n\r Retry Count: ", retry_count);
+ #endif
+ ddr_training_state = DDR_CHECK_TRAINING_SWEEP;
+ break;
+
+ case DDR_CHECK_TRAINING_SWEEP:
+ {
+#ifdef SWEEP_ENABLED
+ /* first check if we are finished */
+ if(last_sweep_status == CALIBRATION_SUCCESS)
+ {
+ /*
+ * Try again with calculated values
+ */
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ }
+ else if(retry_count == TOTAL_SWEEPS)
+ {
+ sweep_index index;
+#ifdef DEBUG_DDR_INIT
+ sweep_status(g_debug_uart);
+#endif
+ /*
+ * Choose the best index
+ */
+ if (get_best_sweep(&index) == 0U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r sweep success: ",\
+ tip_cfg_params);
+#endif
+ last_sweep_status = CALIBRATION_SUCCESS;
+ /*
+ * Use obtained settings
+ */
+ addr_cmd_value = index.cmd_index +\
+ LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET;
+ bclk_sclk_offset_value = index.bclk_sclk_index +\
+ LIBERO_SETTING_MIN_ADDRESS_BCLK_SCLK_OFFSET;
+ dpc_vrgen_v_value = index.dpc_vgen_index +\
+ LIBERO_SETTING_MIN_DPC_V_GEN;
+ dpc_vrgen_h_value = index.dpc_vgen_h_index +\
+ LIBERO_SETTING_MIN_DPC_H_GEN;
+ dpc_vrgen_vs_value = index.dpc_vgen_vs_index +\
+ LIBERO_SETTING_MIN_DPC_VS_GEN;
+
+ tip_cfg_params = ((tip_cfg_params &\
+ (~BCLK_SCLK_OFFSET_MASK))|\
+ (bclk_sclk_offset_value<DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START = 0x0U;
+ /* reset controller */
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x0U;
+ CFG_DDR_SGMII_PHY->training_start.training_start = 0x0U;
+ }
+#else /* we are not SWEEP_ENABLED */
+ ddr_error_count = 0U;
+ error = 0U;
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START = 0x0U;
+ /* reset controller */
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x0U;
+ CFG_DDR_SGMII_PHY->training_start.training_start = 0x0U;
+
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ }
+#endif
+ break;
+
+ case DDR_TRAINING_SWEEP:
+#ifdef SWEEP_ENABLED
+ {
+ static uint32_t sweep_count_cmd_offset;
+ static uint32_t sweep_count_bck_sclk;
+ static uint32_t sweep_count_dpc_v_bits;
+ static uint32_t sweep_count_dpc_h_bits;
+ static uint32_t sweep_count_dpc_vs_bits;
+
+ switch(sweep_state)
+ {
+ case INIT_SWEEP:
+ /*
+ * Parameter values
+ */
+ addr_cmd_value = LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET;
+ bclk_sclk_offset_value =\
+ LIBERO_SETTING_MIN_ADDRESS_BCLK_SCLK_OFFSET;
+ dpc_vrgen_v_value = LIBERO_SETTING_MIN_DPC_V_GEN;
+ dpc_vrgen_h_value = LIBERO_SETTING_MIN_DPC_H_GEN;
+ dpc_vrgen_vs_value = LIBERO_SETTING_MIN_DPC_VS_GEN;
+ /*
+ * state counts
+ */
+ sweep_count_cmd_offset = 0U;
+ sweep_count_bck_sclk = 0U;
+ sweep_count_dpc_v_bits = 0U;
+ sweep_count_dpc_h_bits = 0U;
+ sweep_count_dpc_vs_bits = 0U;
+ sweep_state = ADDR_CMD_OFFSET_SWEEP;
+ __attribute__((fallthrough)); /* deliberately fall through */
+ case ADDR_CMD_OFFSET_SWEEP:
+ /*
+ * Record sweep result
+ */
+ sweep_results[sweep_count_dpc_vs_bits][sweep_count_dpc_h_bits][sweep_count_dpc_v_bits]\
+ [sweep_count_bck_sclk]\
+ [sweep_count_cmd_offset] = last_sweep_status;
+ /*
+ * sweep: ADDR_CMD OFFSET
+ */
+ addr_cmd_value++;
+ if (addr_cmd_value > \
+ LIBERO_SETTING_MAX_ADDRESS_CMD_OFFSET)
+ {
+ addr_cmd_value = \
+ LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET;
+ }
+
+ tip_cfg_params = ((tip_cfg_params &\
+ (~ADDRESS_CMD_OFFSETT_MASK))|(addr_cmd_value));
+ sweep_count_cmd_offset++;
+ if(sweep_count_cmd_offset > MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS)
+ {
+ sweep_count_cmd_offset = 0U;
+ sweep_state = BCLK_SCLK_OFFSET_SWEEP;
+ }
+ else
+ {
+ /*
+ * Now do a sweep
+ */
+ ddr_error_count = 0U;
+ error = 0U;
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START = 0x00000000U;
+ /* reset controller */
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x00000000U;
+ CFG_DDR_SGMII_PHY->training_start.training_start = 0x00000000U;
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ }
+ break;
+ case BCLK_SCLK_OFFSET_SWEEP:
+ /*
+ * sweep: BCLK_SCLK
+ */
+ bclk_sclk_offset_value++;
+ if (bclk_sclk_offset_value > \
+ LIBERO_SETTING_MAX_ADDRESS_BCLK_SCLK_OFFSET)
+ {
+ bclk_sclk_offset_value = \
+ LIBERO_SETTING_MIN_ADDRESS_BCLK_SCLK_OFFSET;
+ }
+ tip_cfg_params = ((tip_cfg_params &\
+ (~BCLK_SCLK_OFFSET_MASK))|\
+ (bclk_sclk_offset_value< MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS)
+ {
+ sweep_count_bck_sclk = 0U;
+ sweep_state = DPC_VRGEN_V_SWEEP;
+ }
+ else
+ {
+ sweep_state = ADDR_CMD_OFFSET_SWEEP;
+ }
+ break;
+ case DPC_VRGEN_V_SWEEP:
+ /*
+ * sweep: DPC_VRGEN_V [4:6]
+ * LIBERO_SETTING_DPC_BITS
+ */
+ dpc_vrgen_v_value++;
+ if (dpc_vrgen_v_value > \
+ LIBERO_SETTING_MAX_DPC_V_GEN)
+ {
+ dpc_vrgen_v_value = \
+ LIBERO_SETTING_MIN_DPC_V_GEN;
+ }
+ dpc_bits = ((dpc_bits &\
+ (~BCLK_DPC_VRGEN_V_MASK))|\
+ (dpc_vrgen_v_value< MAX_NUMBER_DPC_V_GEN_SWEEPS)
+ {
+ sweep_count_dpc_v_bits = 0U;
+ sweep_state = DPC_VRGEN_H_SWEEP;
+ }
+ else
+ {
+ sweep_state = BCLK_SCLK_OFFSET_SWEEP;
+ }
+ break;
+ case DPC_VRGEN_H_SWEEP:
+ /*
+ * sweep: DPC_VRGEN_V [4:6]
+ * LIBERO_SETTING_DPC_BITS
+ */
+ dpc_vrgen_h_value++;
+ if (dpc_vrgen_h_value > \
+ LIBERO_SETTING_MAX_DPC_H_GEN)
+ {
+ dpc_vrgen_h_value = \
+ LIBERO_SETTING_MIN_DPC_H_GEN;
+ }
+ dpc_bits = ((dpc_bits &\
+ (~BCLK_DPC_VRGEN_H_MASK))|\
+ (dpc_vrgen_h_value< MAX_NUMBER_DPC_H_GEN_SWEEPS)
+ {
+ sweep_count_dpc_h_bits = 0U;
+ sweep_state = DPC_VRGEN_VS_SWEEP;
+ }
+ else
+ {
+ sweep_state = DPC_VRGEN_V_SWEEP;
+ }
+ break;
+ case DPC_VRGEN_VS_SWEEP:
+ /*
+ * sweep: DPC_VRGEN_V [4:6]
+ * LIBERO_SETTING_DPC_BITS
+ */
+ dpc_vrgen_vs_value++;
+ if (dpc_vrgen_vs_value > \
+ LIBERO_SETTING_MAX_DPC_VS_GEN)
+ {
+ dpc_vrgen_vs_value = \
+ LIBERO_SETTING_MIN_DPC_VS_GEN;
+ }
+ dpc_bits = ((dpc_bits &\
+ (~BCLK_DPC_VRGEN_VS_MASK))|\
+ (dpc_vrgen_vs_value< MAX_NUMBER_DPC_VS_GEN_SWEEPS)
+ {
+ sweep_count_dpc_vs_bits = 0U;
+ }
+ sweep_state = DPC_VRGEN_H_SWEEP;
+ break;
+ case FINISHED_SWEEP:
+ break;
+ default:
+ break;
+ }
+ }
+#endif /* SWEEP_ENABLED */
+ break;
+
+ case DDR_TRAINING_CHECK_FOR_OFFMODE:
+ /*
+ * check if we are in off mode
+ */
+ if (ddr_type == DDR_OFF_MODE)
+ {
+ ddr_off_mode();
+ ret_status |= DDR_SETUP_DONE;
+ return (ret_status);
+ }
+ else
+ {
+ /*
+ * set initial conditions
+ */
+ /* enable fabric noise */
+#ifdef FABRIC_NOISE_TEST
+ if(fabric_noise_en)
+ {
+ SYSREG->SOFT_RESET_CR &= 0x00U;
+ SYSREG->SUBBLK_CLOCK_CR = 0xffffffffUL;
+ SYSREG->GPIO_INTERRUPT_FAB_CR = 0x00000000UL;
+ PLIC_init();
+ PLIC_SetPriority_Threshold(0);
+ __enable_irq();
+ /* bit0-bit15 used to enable noise logic in steps of 5%
+ bit 16 noise logic reset
+ bit 17 clkmux sel
+ bit 18 pll powerdown
+ bit 19 external io enable for GCLKINT */
+ PLIC_SetPriority(GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0, 4U);
+ PLIC_SetPriority(GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1, 4U);
+ PLIC_SetPriority(GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2, 4U);
+ PLIC_SetPriority(GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3, 4U);
+ PLIC_SetPriority(GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4, 4U);
+ PLIC_SetPriority(GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5, 4U);
+ PLIC_SetPriority(GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6, 4U);
+ PLIC_SetPriority(GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7, 4U);
+ PLIC_SetPriority(GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8, 4U);
+ PLIC_SetPriority(GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9, 4U);
+ PLIC_SetPriority(GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10, 4U);
+ PLIC_SetPriority(GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11, 4U);
+ PLIC_SetPriority(GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12, 4U);
+ PLIC_SetPriority(GPIO0_BIT13_or_GPIO2_BIT13_PLIC_13, 4U);
+ PLIC_SetPriority(GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14, 4U);
+ PLIC_SetPriority(GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15, 4U);
+ PLIC_SetPriority(GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16, 4U);
+ PLIC_SetPriority(GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17, 4U);
+ PLIC_SetPriority(GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18, 4U);
+ PLIC_SetPriority(GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19, 4U);
+
+ MSS_GPIO_init(GPIO2_LO);
+ MSS_GPIO_config_all(GPIO2_LO, MSS_GPIO_OUTPUT_MODE);
+ MSS_GPIO_set_outputs(GPIO2_LO, 0x00000UL); /* bits 15:0 - 0, noise logic disabled */
+ delay(100);
+ /*MSS_GPIO_set_outputs(GPIO2_LO, 0x00FFFUL);*/ /* bits 12:0 - 1, 56% enabled */
+ noise_ena = (1 << num_of_noise_blocks_en) - 1;
+ MSS_GPIO_set_outputs(GPIO2_LO, noise_ena); /* num_of_noise_blocks_en * 4.72% */
+ fabric_noise_en = 0;
+ }
+#endif /* FABRIC_NOISE_TEST */
+ write_latency = MIN_LATENCY;
+ ddr_training_state = DDR_TRAINING_SET_MODE_VS_BITS;
+ }
+ break;
+
+ case DDR_TRAINING_SET_MODE_VS_BITS:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r dpc_bits: ",\
+ dpc_bits);
+#endif
+ /*
+ * Set the training mode
+ */
+ set_ddr_mode_reg_and_vs_bits(dpc_bits);
+ ddr_training_state = DDR_TRAINING_FLASH_REGS;
+ break;
+
+ case DDR_TRAINING_FLASH_REGS:
+ /*
+ * flash registers with RPC values
+ * Enable DDR IO decoders
+ * Note :
+ * rpc sequence:
+ * power-up -> mss_boot -> re-flash nv_map -> override
+ * any changes (to fix issues)
+ *
+ * SOFT_RESET_ bit 0 == periph soft reset, auto cleared
+ */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_DRIVER.SOFT_RESET_DECODER_DRIVER = 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_ODT.SOFT_RESET_DECODER_ODT=1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_IO.SOFT_RESET_DECODER_IO = 1U;
+ ddr_training_state = DDR_TRAINING_CORRECT_RPC;
+ break;
+
+ case DDR_TRAINING_CORRECT_RPC:
+ /*
+ * correct some rpc registers, which were incorrectly set in mode
+ * setting
+ */
+ set_ddr_rpc_regs(ddr_type);
+ ddr_training_state = DDR_TRAINING_SOFT_RESET;
+ break;
+ case DDR_TRAINING_SOFT_RESET:
+ /*
+ * Set soft reset on IP to load RPC to SCB regs (dynamic mode)
+ * Bring the DDR bank controller out of reset
+ */
+ IOSCB_BANKCONT_DDR->soft_reset = 1U; /* DPC_BITS NV_MAP reset */
+ ddr_training_state = DDR_TRAINING_CALIBRATE_IO;
+ break;
+ case DDR_TRAINING_CALIBRATE_IO:
+ /*
+ * Calibrate DDR I/O here, once all RPC settings correct
+ */
+ ddr_pvt_calibration();
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r PCODE = ",\
+ (CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2 & 0x7FU));
+ (void)uprint32(g_debug_uart, "\n\r NCODE = ", \
+ (((CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2) >> 7U) & 0x7FU));
+ (void)uprint32(g_debug_uart, "\n\r addr_cmd_value: ",\
+ addr_cmd_value);
+ (void)uprint32(g_debug_uart, "\n\r bclk_sclk_offset_value: ",\
+ bclk_sclk_offset_value);
+ (void)uprint32(g_debug_uart, "\n\r dpc_vrgen_v_value: ",\
+ dpc_vrgen_v_value);
+ (void)uprint32(g_debug_uart, "\n\r dpc_vrgen_h_value: ",\
+ dpc_vrgen_h_value);
+ (void)uprint32(g_debug_uart, "\n\r dpc_vrgen_vs_value: ",\
+ dpc_vrgen_vs_value);
+#endif
+ ddr_training_state = DDR_TRAINING_CONFIG_PLL;
+ break;
+ case DDR_TRAINING_CONFIG_PLL:
+ /*
+ * Configure the DDR PLL
+ */
+ ddr_pll_config(SCB_UPDATE);
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_VERIFY_PLL_LOCK;
+ break;
+ case DDR_TRAINING_VERIFY_PLL_LOCK:
+ /*
+ * Verify DDR PLL lock
+ */
+ if (ddr_pll_lock_scb() == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_SETUP_SEGS;
+ }
+ else if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_PLL_LOCK;
+ }
+ break;
+ case DDR_TRAINING_SETUP_SEGS:
+ /*
+ * Configure Segments- address mapping, CFG0/CFG1
+ */
+ setup_ddr_segments(DEFAULT_SEG_SETUP);
+ /*
+ * enable the DDRC
+ */
+ /* Turn on DDRC clock */
+ SYSREG->SUBBLK_CLOCK_CR |= SUBBLK_CLOCK_CR_DDRC_MASK;
+ /* Remove soft reset */
+ SYSREG->SOFT_RESET_CR &= (uint32_t)~SOFT_RESET_CR_DDRC_MASK;
+ ddr_training_state = DDR_TRAINING_SETUP_DDRC;
+ break;
+ case DDR_TRAINING_SETUP_DDRC:
+ /*
+ * set-up DDRC
+ * Configuration taken from the user.
+ */
+ {
+ init_ddrc();
+ ddr_training_state = DDR_TRAINING_RESET;
+ }
+ break;
+ case DDR_TRAINING_RESET:
+ /*
+ * Assert training reset
+ * reset pin is bit [1]
+ * and load skip setting
+ */
+ /* leave in reset */
+/* To verify if separate reset required for DDR4 - believe it is not */
+#ifndef SPECIAL_TRAINIG_RESET
+ CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U;
+#ifndef SOFT_RESET_PRE_TAG_172
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000000U;
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000001U;
+#endif /* !SOFT_RESET_PRE_TAG_172 */
+#else
+ /* Disable CKE */
+ DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1;
+
+ /* Assert FORCE_RESET */
+ DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x1;
+ delay(100);
+ /* release reset to memory here, set INIT_FORCE_RESET to 0 */
+ DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x0;
+ delay(500000);
+
+ /* Enable CKE */
+ DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x0;
+ delay(1000);
+
+ /* reset pin is bit [1] */
+ CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U;
+
+#endif
+ ddr_training_state = DDR_TRAINING_ROTATE_CLK;
+ break;
+ case DDR_TRAINING_ROTATE_CLK:
+ /*
+ * Rotate bclk90 by 90 deg
+ */
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt = 0x00000004U;
+ /*expert mode enabling */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000002U;
+ /* */
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x7CU; /* loading */
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x78U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x78U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x7CU;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x4U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x64U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x66U; /* increment */
+ for (uint32_t d=0;d< \
+ LIBERO_SETTING_TIP_CONFIG_PARAMS_BCLK_VCOPHS_OFFSET;d++)
+ {
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x67U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x66U;
+ }
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x64U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x4U;
+
+ /* setting load delay lines */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_mv_rd_dly_reg.expert_dlycnt_mv_rd_dly_reg\
+ = 0x1FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xFFFFFFFFU; /* setting to 1 to load delaylines */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x00000000U;
+
+ /* write w DFICFG_REG mv_rd_dly 0x00000000 #
+ tip_apb_write(12'h89C, 32'h0); mv_rd_dly */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_mv_rd_dly_reg.expert_dlycnt_mv_rd_dly_reg \
+ = 0x0U;
+
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xFFFFFFFFU; /* setting to 1 to load delaylines */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x00000000U;
+
+
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x0000003FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x00000000U;
+
+ /* DQ */
+ /* dfi_training_complete_shim = 1'b1
+ dfi_wrlvl_en_shim = 1'b1 */
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x6;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0xFFFFFFFFU; /* load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xF; /* (ECC) - load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0x0; /* clear */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x0; /* (ECC) clear */
+
+ /* DQS
+ * dfi_wrlvl_en_shim = 1'b1 */
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x4;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0xFFFFFFFFU; /* load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xF; /* (ECC) - load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0x0; /* clear */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x0; /* (ECC) clear */
+
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x0; /* clear */
+
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x0000003FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x00000000U;
+
+ /* expert mode disabling */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en =\
+ 0x00000000U;
+ ddr_training_state = DDR_TRAINING_SET_TRAINING_PARAMETERS;
+ break;
+ case DDR_TRAINING_SET_TRAINING_PARAMETERS:
+ /*
+ * SET TRAINING PARAMETERS
+ *
+ * TIP STATIC PARAMETERS 0
+ *
+ * 30:22 Number of VCO Phase offsets between BCLK and SCLK
+ * 21:13 Number of VCO Phase offsets between BCLK and SCLK
+ * 12:6 Number of VCO Phase offsets between BCLK and SCLK
+ * 5:3 Number of VCO Phase offsets between BCLK and SCLK
+ * 2:0 Number of VCO Phase offsets between REFCLK and ADDCMD bits
+ */
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r tip_cfg_params: ",\
+ tip_cfg_params);
+#endif
+
+ CFG_DDR_SGMII_PHY->tip_cfg_params.tip_cfg_params =\
+ tip_cfg_params;
+ timeout = 0xFFFF;
+
+ if(use_software_bclk_sclk_training(ddr_type) == 1U)
+ {
+ /*
+ * Initiate software training
+ */
+#ifdef SOFT_RESET_PRE_TAG_172
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000001U;
+#endif
+ ddr_training_state = DDR_TRAINING_IP_SM_BCLKSCLK_SW;
+ }
+ else
+ {
+ /*
+ * Initiate IP training and wait for dfi_init_complete
+ */
+ /*asserting training_reset */
+ if (ddr_type != DDR3)
+ {
+ CFG_DDR_SGMII_PHY->training_reset.training_reset =\
+ 0x00000000U;
+ }
+ else
+ {
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000001U;
+ }
+ ddr_training_state = DDR_TRAINING_IP_SM_START;
+ }
+ }
+ break;
+
+ case DDR_TRAINING_IP_SM_BCLKSCLK_SW:
+ /*
+ * We have chosen to use software bclk sclk sweep instead of IP
+ */
+ {
+ uint32_t bclk_phase, bclk90_phase,refclk_phase;
+ bclk_answer = 0U;
+ {
+ /*
+ * BEGIN MANUAL BCLKSCLK TRAINING
+ */
+ uint32_t rx_previous=0x3U;
+ uint32_t rx_current=0U;
+ uint32_t answer_count[8U]={0U,0U,0U,0U,0U,0U,0U,0U};
+ uint32_t answer_index=0U;
+
+ /*UPPER LIMIT MUST BE MULTIPLE OF 8 */
+ for (uint32_t i=0U; i<(8U * 100); i++)
+ {
+
+ bclk_phase = ( i & 0x07UL ) << 8U;
+ bclk90_phase = ((i+2U) & 0x07UL ) << 11U;
+ /*
+ * LOAD BCLK90 PHASE
+ */
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+
+ /*
+ * No pause required, causes an issue
+ */
+
+ /*
+ * SAMPLE RX_BCLK
+ */
+ rx_current = ((CFG_DDR_SGMII_PHY->expert_addcmd_ln_readback.expert_addcmd_ln_readback) >> 12)& 0x03;
+ /* IF WE FOUND A TRANSITION, BREAK THE LOOP */
+ if ((rx_current & (~rx_previous)) != 0x00000000UL)
+ {
+ answer_index=i&0x07U;
+ /* increment the answer count for this index */
+ answer_count[answer_index]++;
+ }
+
+ rx_previous = rx_current;
+ uint32_t max=0U;
+ for (uint32_t j=0U;j<8U;j++)
+ {
+ /* sweep through found answers and select the most common */
+ if (answer_count[j] > max)
+ {
+ bclk_answer = j;
+ max=answer_count[j];
+ }
+ }
+ }
+ }
+ ddr_training_state = DDR_MANUAL_ADDCMD_TRAINING_SW;
+ break;
+
+ case DDR_MANUAL_ADDCMD_TRAINING_SW:
+ {
+ /*
+ * APPLY OFFSET & LOAD THE PHASE
+ * bclk_sclk_offset_value
+ * BCLK_SCLK_OFFSET_BASE
+ */
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT)
+ {
+ /*
+ * We are skipping add/cmd training so need to set
+ * refclk phase offset manually
+ * We may need to sweep this
+ */
+ refclk_phase = (uint32_t)(((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET + 5U + LIBERO_SETTING_MANUAL_REF_CLK_PHASE_OFFSET ) & 0x07UL) << 2U);
+ bclk_phase = ((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET) & 0x07UL ) << 8U;
+ bclk90_phase= ((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET+2U) & 0x07UL ) << 11U;
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase | refclk_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase);
+ }
+ else
+ {
+ bclk_phase = ((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET) & 0x07UL ) << 8U;
+ bclk90_phase=((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET+2U) & 0x07UL ) << 11U;
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+ }
+ ddr_training_state = DDR_TRAINING_IP_SM_START;
+ /* END MANUAL BCLKSCLK TRAINING */
+ }
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_BCLKSCLK_SW;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_START:
+ {
+ CFG_DDR_SGMII_PHY->training_skip.training_skip =\
+ LIBERO_SETTING_TRAINING_SKIP_SETTING;
+ if ((ddr_type == DDR3)||(ddr_type == LPDDR4)||(ddr_type == DDR4))
+ {
+ /* RX_MD_CLKN */
+ CFG_DDR_SGMII_PHY->rpc168.rpc168 = 0x0U;
+ }
+#ifdef DDR_TRAINING_IP_SM_START_DELAY
+ delay(100);
+#endif
+ /* release reset to training */
+ CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000000U;
+#ifdef IP_SM_START_TRAINING_PAUSE
+ /* todo: pause removed at Alister's request for test. Will
+ * remove once verified not required after further testing
+ */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0xffU;
+ delay(100);
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x00000000U;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x0000003FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x00000000U;
+ delay(100);
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00U;
+ delay(100);
+#endif
+ }
+ {
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START =\
+ 0x00000000U;
+ /* kick off training- DDRC, set dfi_init_start */
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START =\
+ 0x00000001U;
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x00000000U;
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x00000001U;
+
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_START_CHECK;
+ }
+#ifdef DEBUG_DDR_INIT
+#ifdef MANUAL_ADDCMD_TRAINIG
+ (void)uprint32(g_debug_uart, "\n\r\n\r ADDCMD_OFFSET ", refclk_offset);
+#endif
+#endif
+ break;
+ case DDR_TRAINING_IP_SM_START_CHECK:
+#ifndef RENODE_DEBUG
+ if((DDRCFG->DFI.STAT_DFI_INIT_COMPLETE.STAT_DFI_INIT_COMPLETE\
+ & 0x01U) == 0x01U)
+#endif
+ {
+#ifdef LANE_ALIGNMENT_RESET_REQUIRED
+ CFG_DDR_SGMII_PHY->lane_alignment_fifo_control.lane_alignment_fifo_control = 0x00U;
+ CFG_DDR_SGMII_PHY->lane_alignment_fifo_control.lane_alignment_fifo_control = 0x02U;
+#endif
+
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, \
+ "\n\r\n\r pll_phadj_after_hw_training ",\
+ MSS_SCB_DDR_PLL->PLL_DIV_2_3);
+ (void)uprint32(g_debug_uart, \
+ "\n\r\n\r pll_phadj_after_hw_training ",\
+ MSS_SCB_DDR_PLL->PLL_DIV_0_1);
+#endif
+
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & BCLK_SCLK_BIT)
+ {
+ ddr_training_state = DDR_TRAINING_IP_SM_ADDCMD;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_IP_SM_BCLKSCLK;
+ }
+ timeout = 0xFFFF;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_START_CHECK;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_BCLKSCLK:
+ if(CFG_DDR_SGMII_PHY->training_status.training_status & BCLK_SCLK_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_ADDCMD;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_BCLKSCLK;
+ }
+ break;
+
+ case DDR_TRAINING_IP_SM_ADDCMD:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT)
+ {
+ timeout = 0xFFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_WRLVL;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & ADDCMD_BIT)
+ {
+ timeout = 0xFFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_WRLVL;
+ }
+ if(--timeout == 0U)
+ {
+ /*
+ * Typically this can fail for two
+ * reasons:
+ * 1. ADD/CMD not being received
+ * We need to sweep:
+ * ADDCMD_OFFSET [0:3] RW value
+ * sweep-> 0x2 -> 4 -> C -> 0
+ * 2. DQ not received
+ * We need to sweep:
+ * LIBERO_SETTING_DPC_BITS
+ * DPC_VRGEN_H [4:6] value= 0x8->0xC
+ *
+ * */
+ ddr_training_state = DDR_TRAINING_FAIL_SM_ADDCMD;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_WRLVL:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & WRLVL_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_RDGATE;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & WRLVL_BIT)
+ {
+ timeout = 0xFFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_RDGATE;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_WRLVL;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_RDGATE:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & RDGATE_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_DQ_DQS;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & RDGATE_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_DQ_DQS;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_RDGATE;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_DQ_DQS:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & DQ_DQS_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_VERIFY;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & DQ_DQS_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_VERIFY;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_DQ_DQS;
+ }
+ break;
+
+ case DDR_TRAINING_IP_SM_VERIFY:
+ if ((DDRCFG->DFI.STAT_DFI_TRAINING_COMPLETE.STAT_DFI_TRAINING_COMPLETE & 0x01U) == 0x01U)
+ {
+ /*
+ * Step 15:
+ * check worked for each lane
+ */
+ uint32_t lane_sel, t_status = 0U;
+ for (lane_sel=0U; lane_sel< \
+ LIBERO_SETTING_DATA_LANES_USED; lane_sel++)
+ {
+ SIM_FEEDBACK1(1000U);
+ delay(10U);
+ SIM_FEEDBACK1(1001U);
+ CFG_DDR_SGMII_PHY->lane_select.lane_select =\
+ lane_sel;
+ delay(10U);
+ /*
+ * verify cmd address results
+ * rejects if not acceptable
+ * */
+ {
+ uint32_t ca_status[8]= {\
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0>>8U)&0xFFU), \
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0>>16U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0>>24U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1>>8U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1>>16U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1>>24U)&0xFFU)};
+ uint32_t low_ca_dly_count = 0U;
+ uint32_t last = 0U;
+ uint32_t decrease_count = 0U;
+ for(uint32_t i =0U; i<8U;i++)
+ {
+ if(ca_status[i] < 5U)
+ {
+ low_ca_dly_count++;
+ }
+ if(ca_status[i]<=last)
+ {
+ decrease_count++;
+ }
+ last = ca_status[i];
+ }
+ if(ca_status[0]<= ca_status[7U])
+ {
+ decrease_count++;
+ }
+ if((LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT) != ADDCMD_BIT)
+ {
+ /* Retrain if abnormal CA training result detected */
+ if(low_ca_dly_count > ABNORMAL_RETRAIN_CA_DLY_DECREASE_COUNT)
+ {
+ t_status = t_status | 0x01U;
+ }
+ /* Retrain if abnormal CA training result detected */
+ if(decrease_count > ABNORMAL_RETRAIN_CA_DECREASE_COUNT)
+ {
+ t_status = t_status | 0x01U;
+ }
+ }
+ }
+ /* Check that gate training passed without error */
+ t_status =t_status |\
+ CFG_DDR_SGMII_PHY->gt_err_comb.gt_err_comb;
+ delay(10U);
+ /* Check that DQ/DQS training passed without error */
+ if(CFG_DDR_SGMII_PHY->dq_dqs_err_done.dq_dqs_err_done != 8U)
+ {
+ t_status = t_status | 0x01U;
+ }
+ /* Check that DQ/DQS calculated window is above 5 taps. */
+ if(CFG_DDR_SGMII_PHY->dqdqs_status1.dqdqs_status1 < \
+ DQ_DQS_NUM_TAPS)
+ {
+ t_status = t_status | 0x01U;
+ }
+#ifdef DCT_EXTRA_CHECKS /* todo: Theses checks was added by DCT */
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly)&0xFFU) == 0U) // Gate training tx_dly check: AL
+ {
+ t_status = t_status | 0x01U;
+ }
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly>>8U)&0xFFU) == 0U)
+ {
+ t_status = t_status | 0x01U;
+ }
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly>>16U)&0xFFU) == 0U)
+ {
+ t_status = t_status | 0x01U;
+ }
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly>>24U)&0xFFU) == 0U)
+ {
+ t_status = t_status | 0x01U;
+ }
+#endif
+ }
+ #ifdef RENODE_DEBUG
+ t_status = 0U; /* Dummy success -move on to
+ next stage */
+ #endif
+ if(t_status == 0U)
+ {
+ SIM_FEEDBACK1(21U);
+ /*
+ * We can now set vref on the memory
+ * mode register for lpddr4
+ * May include other modes, and include a sweep
+ * Alister looking into this and will revert.
+ */
+ if (ddr_type == LPDDR4)
+ {
+#ifdef SET_VREF_LPDDR4_MODE_REGS
+ mode_register_write(DDR_MODE_REG_VREF,\
+ DDR_MODE_REG_VREF_VALUE);
+#endif
+ }
+ ddr_training_state = DDR_TRAINING_SET_FINAL_MODE;
+ }
+ else /* fail, try again */
+ {
+ SIM_FEEDBACK1(20U);
+ ddr_training_state = DDR_TRAINING_FAIL_SM_VERIFY;
+ }
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM2_VERIFY;
+ }
+ break;
+
+
+ case DDR_TRAINING_SET_FINAL_MODE:
+ /*
+ * Set final mode register value.
+ */
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ LIBERO_SETTING_DDRPHY_MODE;
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR FINAL_MODE: ",\
+ LIBERO_SETTING_DDRPHY_MODE);
+#ifdef DEBUG_DDR_CFG_DDR_SGMII_PHY
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)CFG_DDR_SGMII_PHY,\
+ (sizeof(CFG_DDR_SGMII_PHY_TypeDef)/4U));
+#endif
+#ifdef DEBUG_DDR_DDRCFG
+ debug_read_ddrcfg();
+#endif
+#endif
+#ifdef DEBUG_DDR_INIT
+ {
+ tip_register_status (g_debug_uart);
+ (void)uprint32(g_debug_uart, "\n\r ****************************************************", 0U);
+
+ }
+#endif
+ ddr_training_state = DDR_TRAINING_WRITE_CALIBRATION;
+ break;
+
+ case DDR_TRAINING_WRITE_CALIBRATION:
+ /*
+ * Does the following in the DDRC need to be checked??
+ * DDRCFG->DFI.STAT_DFI_TRAINING_COMPLETE.STAT_DFI_TRAINING_COMPLETE;
+ *
+ */
+ number_of_lanes_to_calibrate = get_num_lanes();
+ /*
+ * Now start the write calibration as training has been successful
+ */
+ if(error == 0U)
+ {
+ if (ddr_type == LPDDR4)
+ {
+ uint8_t lane;
+ /* Changed default value to centre dq/dqs on window */
+ CFG_DDR_SGMII_PHY->rpc220.rpc220 = 0xCUL;
+ for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++)
+ {
+ load_dq(lane);
+ }
+ SIM_FEEDBACK1(1U);
+
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+ error =\
+ write_calibration_lpddr4_using_mtc(\
+ number_of_lanes_to_calibrate);
+#else
+ error =\
+ write_calibration_using_mtc(\
+ number_of_lanes_to_calibrate);
+#endif
+ }
+ else
+ {
+ SIM_FEEDBACK1(2U);
+ error =\
+ write_calibration_using_mtc(number_of_lanes_to_calibrate);
+ }
+ if(error)
+ {
+ ddr_error_count++;
+ SIM_FEEDBACK1(106U);
+ }
+ }
+#if (EN_RETRY_ON_FIRST_TRAIN_PASS == 1)
+ if((error == 0U)&&(retry_count != 0U))
+#else
+ if(error == 0U)
+#endif
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r wr calib result ",\
+ calib_data.write_cal.lane_calib_result);
+#endif
+ ddr_training_state = DDR_SWEEP_CHECK;
+ }
+ else if(error == MTC_TIMEOUT_ERROR)
+ {
+ error = 0U;
+ ddr_training_state = DDR_TRAINING_FAIL_DDR_SANITY_CHECKS;
+ }
+ else
+ {
+ error = 0U;
+ ddr_training_state = DDR_TRAINING_WRITE_CALIBRATION_RETRY;
+ }
+ break;
+
+ case DDR_TRAINING_WRITE_CALIBRATION_RETRY:
+ /*
+ * Clear write calibration data
+ */
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ /*
+ * Try the next offset
+ */
+ write_latency++;
+ if (write_latency > MAX_LATENCY)
+ {
+ write_latency = MIN_LATENCY;
+ ddr_training_state = DDR_TRAINING_FAIL_MIN_LATENCY;
+ }
+ else
+ {
+ DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT =\
+ write_latency;
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\
+ write_latency);
+#endif
+ ddr_training_state = DDR_TRAINING_WRITE_CALIBRATION;
+ }
+ break;
+
+ case DDR_SWEEP_CHECK:
+#ifdef SWEEP_ENABLED
+ if((retry_count != 0U)&&(retry_count < (TOTAL_SWEEPS-1U)))
+ {
+ ddr_training_state = DDR_SWEEP_AGAIN;
+ }
+ else
+#endif
+ {
+ ddr_training_state = DDR_SANITY_CHECKS;
+ }
+ break;
+
+ case DDR_SANITY_CHECKS:
+ /*
+ * Now start the write calibration if training successful
+ */
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR SANITY_CHECKS: ",\
+ error);
+#endif
+ if(error == 0U)
+ {
+#ifdef DDR_SANITY_CHECKS_EN
+ error = memory_tests();
+#endif
+ }
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_MTC_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_DDR_SANITY_CHECKS;
+ }
+ break;
+
+ case DDR_FULL_MTC_CHECK:
+ {
+ uint64_t start_address = 0x0000000000000000ULL;
+ uint32_t size = ONE_MB_MTC; /* Number of reads for each iteration 2**size*/
+ uint8_t mask;
+ if (get_num_lanes() <= 3U)
+ {
+ mask = 0x3U;
+ }
+ else
+ {
+ mask = 0xFU;
+ }
+ error = MTC_test(mask, start_address, size, MTC_COUNTING_PATTERN, MTC_ADD_SEQUENTIAL, &error);
+ /* Read using different patterns */
+ error = 0U;
+ error |= MTC_test(mask, start_address, size, MTC_COUNTING_PATTERN, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_WALKING_ONE, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_NO_REPEATING_PSEUDO_RANDOM, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_ONES_ZEROS, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_5_A, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_16BIT, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_8BIT, MTC_ADD_SEQUENTIAL, &error);
+
+ error |= MTC_test(mask, start_address, size, MTC_COUNTING_PATTERN, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_WALKING_ONE, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_NO_REPEATING_PSEUDO_RANDOM, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_ONES_ZEROS, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_5_A, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_16BIT, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_8BIT, MTC_ADD_RANDOM, &error);
+ }
+ if(error == 0U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r Passed MTC full check ", error);
+#endif
+ ddr_training_state = DDR_FULL_32BIT_NC_CHECK;
+ }
+ else
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r Failed MTC full check ", error);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+
+ case DDR_FULL_32BIT_NC_CHECK:
+ /*
+ * write and read back test from drr, non cached access
+ */
+ {
+#if (DDR_FULL_32BIT_NC_CHECK_EN == 1)
+ error = ddr_read_write_fn((uint64_t*)LIBERO_SETTING_DDR_32_NON_CACHE,\
+ SW_CFG_NUM_READS_WRITES,\
+ SW_CONFIG_PATTERN);
+#endif
+ }
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_32BIT_CACHE_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_FULL_32BIT_NC_CHECK;
+ }
+ break;
+ case DDR_FULL_32BIT_CACHE_CHECK:
+#if (DDR_FULL_32BIT_CACHED_CHECK_EN == 1)
+ error = ddr_read_write_fn((uint64_t*)LIBERO_SETTING_DDR_32_CACHE,\
+ SW_CFG_NUM_READS_WRITES,\
+ SW_CONFIG_PATTERN);
+#endif
+ if(error == 0U)
+ {
+#ifdef SKIP_VERIFY_PATTERN_IN_CACHE
+ ddr_training_state = DDR_FULL_32BIT_WRC_CHECK;
+#else
+ ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE;
+#endif
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_32BIT_CACHE_CHECK;
+ }
+ break;
+ case DDR_LOAD_PATTERN_TO_CACHE:
+ load_ddr_pattern(LIBERO_SETTING_DDR_32_CACHE, SIZE_OF_PATTERN_TEST, SIZE_OF_PATTERN_OFFSET);
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_VERIFY_PATTERN_IN_CACHE;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_VERIFY_PATTERN_IN_CACHE:
+ error = test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST);
+ if(error == 0U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\
+ write_latency);
+#if (TUNE_RPC_166_VALUE == 1)
+ (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\
+ rpc_166_fifo_offset);
+#endif
+#endif
+ ddr_training_state = DDR_FULL_32BIT_WRC_CHECK;
+ }
+ else
+ {
+#if (TUNE_RPC_166_VALUE == 1)
+
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\
+ rpc_166_fifo_offset);
+#endif
+
+#ifdef NOT_A_FULL_RETRAIN
+
+ /* this fails post tests */
+ if(num_rpc_166_retires < NUM_RPC_166_VALUES)
+ {
+ num_rpc_166_retires++;
+ rpc_166_fifo_offset++;
+ if(rpc_166_fifo_offset > MAX_RPC_166_VALUE)
+ {
+ rpc_166_fifo_offset = MIN_RPC_166_VALUE;
+ }
+ /* try again here DDR_LOAD_PATTERN_TO_CACHE */
+ }
+ else
+ {
+ num_rpc_166_retires = 0U;
+ rpc_166_fifo_offset = DEFAULT_RPC_166_VALUE;
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ CFG_DDR_SGMII_PHY->rpc166.rpc166 = rpc_166_fifo_offset;
+ //PAUSE to reset fifo (loads new RXPTR value).
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x1U;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x0000003EU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x00000000U;
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U;
+ //delay(10);
+ //END PAUSE
+#else
+ if(num_rpc_166_retires < NUM_RPC_166_VALUES)
+ {
+ num_rpc_166_retires++;
+ rpc_166_fifo_offset++;
+ if(rpc_166_fifo_offset > MAX_RPC_166_VALUE)
+ {
+ rpc_166_fifo_offset = MIN_RPC_166_VALUE;
+ }
+ /* try again here DDR_LOAD_PATTERN_TO_CACHE */
+ }
+ else
+ {
+ num_rpc_166_retires = 0U;
+ rpc_166_fifo_offset = DEFAULT_RPC_166_VALUE;
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ ddr_training_state = DDR_TRAINING_FAIL;
+#endif
+#else /* (TUNE_RPC_166_VALUE == 0) */
+ ddr_training_state = DDR_TRAINING_FAIL;
+#endif
+ }
+ break;
+ case DDR_FULL_32BIT_WRC_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_64BIT_NC_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_FULL_64BIT_NC_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_64BIT_CACHE_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_FULL_64BIT_CACHE_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_64BIT_WRC_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_FULL_64BIT_WRC_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_VREFDQ_CALIB;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+
+ break;
+
+ case DDR_TRAINING_VREFDQ_CALIB:
+#ifdef VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+ error = VREFDQ_calibration_using_mtc();
+ if(error != 0U)
+ {
+ ddr_error_count++;
+ }
+#endif
+ ddr_training_state = DDR_TRAINING_FPGA_VREFDQ_CALIB;
+ break;
+
+ case DDR_TRAINING_FPGA_VREFDQ_CALIB:
+#ifdef FPGA_VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+ error = FPGA_VREFDQ_calibration_using_mtc();
+ if(error != 0U)
+ {
+ ddr_error_count++;
+ }
+#endif
+ ddr_training_state = DDR_TRAINING_FINISH_CHECK;
+ break;
+
+ case DDR_TRAINING_FINISH_CHECK:
+ /*
+ * return status
+ */
+#ifdef DEBUG_DDR_INIT
+ {
+ tip_register_status (g_debug_uart);
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR_TRAINING_PASS: ",\
+ ddr_training_state);
+ (void)uprint32(g_debug_uart, "\n ****************************************************", 0);
+
+ }
+#endif
+ if(ddr_error_count > 0)
+ {
+ ret_status |= DDR_SETUP_FAIL;
+ }
+ else
+ {
+ /*
+ * Configure Segments- address mapping, CFG0/CFG1
+ */
+ setup_ddr_segments(LIBERO_SEG_SETUP);
+ }
+ ret_status |= DDR_SETUP_DONE;
+ ddr_training_state = DDR_TRAINING_FINISHED;
+ break;
+
+ default:
+ case DDR_TRAINING_FINISHED:
+ break;
+ } /* end of case statement */
+
+ return (ret_status);
+}
+
+
+/**
+ * get_num_lanes(void)
+ * @return number of lanes used, 2(16 bit), 3(16 bit + ecc), 4(32 bit) or 5
+ * Note: Lane 4 always used when ECC enabled, even for x16
+ */
+static uint8_t get_num_lanes(void)
+{
+ uint8_t lanes;
+ /* Check width, 16bit or 32bit bit supported, 1 => 32 bit */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_BUS_WIDTH_MASK) ==\
+ DDRPHY_MODE_BUS_WIDTH_4_LANE)
+ {
+ lanes = 4U;
+ }
+ else
+ {
+ lanes = 2U;
+ }
+ /* Check if using ECC, add a lane */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_ECC_MASK) ==\
+ DDRPHY_MODE_ECC_ON)
+ {
+ lanes++;
+ }
+ return lanes;
+}
+
+
+
+/***************************************************************************//**
+ * set_ddr_mode_reg_and_vs_bits()
+ *
+ */
+static void set_ddr_mode_reg_and_vs_bits(uint32_t dpc_bits)
+{
+ DDR_TYPE ddr_type = LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK;
+ /*
+ * R1.6
+ * Write DDR phy mode reg (eg DDR3)
+ * When we write to the mode register, an ip state machine copies default
+ * values for the particular mode chosen to RPC registers associated with
+ * DDR in the MSS custom block.
+ * ( Note: VS bits are not include in the copy so we set below )
+ * The RPC register values are transferred to the SCB registers in a
+ * subsequent step.
+ */
+ /*
+ * Set VS bits
+ * Select VS bits for DDR mode selected --- set dynamic pc bit settings to
+ * allow editing of RPC registers
+ * pvt calibration etc
+ *
+ * [19] dpc_move_en_v enable dynamic control of vrgen circuit for
+ * ADDCMD pins
+ * [18] dpc_vrgen_en_v enable vref generator for ADDCMD pins
+ * [17:12] dpc_vrgen_v reference voltage ratio setting for ADDCMD
+ * pins
+ * [11:11] dpc_move_en_h enable dynamic control of vrgen circuit for
+ * DQ/DQS pins
+ * [10:10] dpc_vrgen_en_h enable vref generator for DQ/DQS pins
+ * [9:4] dpc_vrgen_h reference voltage ratio setting for DQ/DQS
+ * pins
+ * [3:0] dpc_vs bank voltage select for pvt calibration
+ */
+ /*
+ DDRPHY_MODE setting from MSS configurator
+ DDRMODE :3;
+ ECC :1;
+ CRC :1;
+ Bus_width :3;
+ DMI_DBI :1;
+ DQ_drive :2;
+ DQS_drive :2;
+ ADD_CMD_drive :2;
+ Clock_out_drive :2;
+ DQ_termination :2;
+ DQS_termination :2;
+ ADD_CMD_input_pin_termination :2;
+ preset_odt_clk :2;
+ Power_down :1;
+ rank :1;
+ Command_Address_Pipe :2;
+ */
+ {
+ if ((ddr_type == DDR4) &&\
+ (LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_ECC_MASK) ==\
+ DDRPHY_MODE_ECC_ON)
+ {
+ /*
+ * For ECC on when DDR4, and data mask on during training, training
+ * will not pass
+ * This will eventually be handled by the configurator
+ * DM will not be allowed for DDR4 with ECC
+ */
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ (LIBERO_SETTING_DDRPHY_MODE & DMI_DBI_MASK );
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ LIBERO_SETTING_DDRPHY_MODE;
+ }
+ delay((uint32_t) 100U);
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS = dpc_bits;
+ }
+}
+
+
+
+/***************************************************************************//**
+ * set_ddr_rpc_regs()
+ * @param ddr_type
+ */
+static void set_ddr_rpc_regs(DDR_TYPE ddr_type)
+{
+ /*
+ * Write DDR phy mode reg (eg DDR3)
+ * When we write to the mode register, an ip state machine copies default
+ * values for the particular mode chossen
+ * to RPC registers associated with DDR in the MSS custom block.
+ * The RPC register values are transferred to the SCB registers in a
+ * subsequent step.
+ *
+ * Question:
+ * Select VS bits (eg DDR3 ) (vs bits not included in mode setup - should
+ * be??)
+ * Small wait while state machine transfer takes place required here.
+ * (status bit required?)
+ *
+ */
+ /*
+ DDRPHY_MODE setting from MSS configurator
+ DDRMODE :3;
+ ECC :1;
+ CRC :1;
+ Bus_width :3;
+ DMI_DBI :1;
+ DQ_drive :2;
+ DQS_drive :2;
+ ADD_CMD_drive :2;
+ Clock_out_drive :2;
+ DQ_termination :2;
+ DQS_termination :2;
+ ADD_CMD_input_pin_termination :2;
+ preset_odt_clk :2;
+ Power_down :1;
+ rank :1;
+ Command_Address_Pipe :2;
+ */
+ {
+ switch (ddr_type)
+ {
+ default:
+ case DDR_OFF_MODE:
+ /* Below have already been set */
+ /* CFG_DDR_SGMII_PHY->rpc95.rpc95 = 0x07; */ /* addcmd I/O*/
+ /* CFG_DDR_SGMII_PHY->rpc96.rpc96 = 0x07; */ /* clk */
+ /* CFG_DDR_SGMII_PHY->rpc97.rpc97 = 0x07; */ /* dq */
+ /* CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x07; */ /* dqs */
+ /*
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ break;
+ case DDR3L:
+ case DDR3:
+ /* Required when rank x 2 */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_RANK_MASK) ==\
+ DDRPHY_MODE_TWO_RANKS)
+ {
+ CFG_DDR_SGMII_PHY->spio253.spio253 = 1U;
+ }
+
+ {
+ /*
+ * firmware set this to 3'b100 for all cases except when we
+ * are in OFF mode (DDR3,DDR4,LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ }
+ /*
+ * SAR xxxx
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ break;
+ case DDR4:
+ {
+ /*
+ * Sar 108017
+ * ODT_STATIC setting is wrong for DDR4/LPDDR3, needs to
+ * be overwritten in embedded SW for E51
+ *
+ * ODT_STATIC is set to 001 for DQ/DQS/DBI bits in
+ * DDR3/LPDDR4, this enables termination to VSS.
+ *
+ * This needs to be switched to VDDI termination.
+ *
+ * To do this, we do APB register writes to override
+ * the following PC bits:
+ * odt_static_dq=010
+ * odt_static_dqs=010
+ */
+ CFG_DDR_SGMII_PHY->rpc10_ODT.rpc10_ODT = 2U;
+ CFG_DDR_SGMII_PHY->rpc11_ODT.rpc11_ODT = 2U;
+ /*
+ * SAR 108218
+ * The firmware should set this to 3'b100 for
+ * all cases except when we are in OFF mode (DDR3,DDR4,
+ * LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ /*
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ }
+ break;
+ case LPDDR3:
+ {
+ /*
+ * Sar 108017
+ * ODT_STATIC setting is wrong for DDR4/LPDDR3, needs to be
+ * overwritten in embedded SW for E51
+ *
+ * ODT_STATIC is set to 001 for DQ/DQS/DBI bits in
+ * DDR3/LPDDR4, this enables termination to VSS.
+ *
+ * This needs to be switched to VDDI termination.
+ *
+ * To do this, we should do APB register writes to override
+ * the following PC bits:
+ * odt_static_dq=010
+ * odt_static_dqs=010
+ */
+ CFG_DDR_SGMII_PHY->rpc10_ODT.rpc10_ODT = 2U;
+ CFG_DDR_SGMII_PHY->rpc11_ODT.rpc11_ODT = 2U;
+ /*
+ * SAR 108218
+ * I've reviewed the results, and the ibufmd bit should be
+ * fixed in firmware for ibufmd_dqs. Malachy please have
+ * the firmware set this to 3'b100 for all cases except
+ * when we are in OFF mode (DDR3,DDR4,LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ /*
+ * SAR xxxx
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ }
+ break;
+ case LPDDR4:
+ {
+ /*
+ * We need to be able to implement different physical
+ * configurations of LPDDR4, given the twindie architecture.
+ * These are not fully decoded by the APB decoder (we dont
+ * have all the options).
+ * Basically we want to support:
+ * Hook the CA buses from the 2 die up in parallel on the
+ * same FPGA pins
+ * Hook the CA buses from the 2 die up in parallel using
+ * the mirrored FPGA pins (IE CA_A/CA_B)
+ * Some combination of the 2, ie duplicate the clocks but
+ * not the CA, duplicate the clocks and command, but not
+ * address, etc.
+ */
+ /* OVRT_EN_ADDCMD1 (default 0xF00), register named ovrt11 */
+#ifndef LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9
+ /*
+ * If this define is not present, indicates older
+ * Libero core (pre 2.0.109)
+ * So we run this code
+ */
+ CFG_DDR_SGMII_PHY->ovrt10.ovrt10 =\
+ LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10;
+ {
+ /* Use pull-ups to set the CMD/ADD ODT */
+ CFG_DDR_SGMII_PHY->rpc245.rpc245 =\
+ 0x00000000U;
+
+ CFG_DDR_SGMII_PHY->rpc237.rpc237 =\
+ 0xffffffff;
+ }
+
+ /* OVRT_EN_ADDCMD2 (default 0xE06U), register named ovrt12 */
+ CFG_DDR_SGMII_PHY->ovrt11.ovrt11 =\
+ LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11;
+#endif
+ /* Required when rank x 2 */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_RANK_MASK) ==\
+ DDRPHY_MODE_TWO_RANKS)
+ {
+ /* todo: need to verify this setting with verification */
+ CFG_DDR_SGMII_PHY->spio253.spio253 = 1;
+ }
+
+ {
+ /*
+ * SAR 108218
+ * I've reviewed the results, and the ibufmd bit should be
+ * fixed in firmware for ibufmd_dqs. Malachy please have the
+ * firmware set this to 3'b100 for all cases except when we
+ * are in OFF mode (DDR3,DDR4,LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ }
+ /*
+ * SAR xxxx
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0xA000U;
+
+ }
+
+ break;
+ }
+ }
+
+ {
+
+ /*
+ * sar107009 found by Paul in Crevin,
+ * This has been fixed in tag g5_mss_ddrphy_apb tag 2.9.130
+ * todo: remove this software workaround as no longer required
+ *
+ * Default of rpc27 should be 2, currently is 0
+ * We will set to 2 for the moment with software.
+ */
+ CFG_DDR_SGMII_PHY->rpc27.rpc27 = 0x2U;
+ /*
+ * Default of rpc27 Issue see by Paul/Alister 10th June
+ * tb_top.duv_wrapper.u_design.mss_custom.gbank6.tip.gapb.\
+ * MAIN.u_apb_mss_decoder_io.rpc203_spare_iog_dqsn
+ */
+ CFG_DDR_SGMII_PHY->rpc203.rpc203 = 0U;
+ }
+
+ {
+ /*
+ *
+ * We'll have to pass that one in via E51, meaning APB writes to
+ * addresses:
+ * 0x2000 7384 rpc1_ODT ODT_CA
+ * 0x2000 7388 rpc2_ODT RPC_ODT_CLK
+ * 0x2000 738C rpc3_ODT ODT_DQ
+ * 0x2000 7390 rpc4_ODT ODT_DQS
+ *
+ * todo: replace with Libero settings below, once values verified
+ */
+ CFG_DDR_SGMII_PHY->rpc1_ODT.rpc1_ODT = LIBERO_SETTING_RPC_ODT_ADDCMD;
+ CFG_DDR_SGMII_PHY->rpc2_ODT.rpc2_ODT = LIBERO_SETTING_RPC_ODT_CLK;
+ CFG_DDR_SGMII_PHY->rpc3_ODT.rpc3_ODT = LIBERO_SETTING_RPC_ODT_DQ;
+ CFG_DDR_SGMII_PHY->rpc4_ODT.rpc4_ODT = LIBERO_SETTING_RPC_ODT_DQS;
+ }
+ {
+ /*
+ * bclk_sel_clkn - selects bclk sclk training clock
+ */
+ CFG_DDR_SGMII_PHY->rpc19.rpc19 = 0x01U; /* bclk_sel_clkn */
+ /*
+ * add cmd - selects bclk sclk training clock
+ */
+ CFG_DDR_SGMII_PHY->rpc20.rpc20 = 0x00U; /* bclk_sel_clkp */
+
+ }
+
+ {
+ /*
+ * Each lane has its own FIFO. This paramater adjusts offset for all lanes.
+ */
+#if (TUNE_RPC_166_VALUE == 1)
+ CFG_DDR_SGMII_PHY->rpc166.rpc166 = rpc_166_fifo_offset;
+#endif
+ }
+
+ /*
+ * Override RPC bits for weak PU and PD's
+ * Set over-ride bit for unused I/O
+ */
+ config_ddr_io_pull_up_downs_rpc_bits(ddr_type);
+}
+
+/**
+ Info on OFF modes:
+
+ OFF MODE from reset- I/O not being used
+ MSSIO from reset- non default values
+ Needs non default values to completely go completely OFF
+ Drive bits and ibuff mode
+ Ciaran to define what need to be done
+ SAR107676
+ DDR - by default put to DDR4 mode so needs active intervention
+ Bills sac spec (DDR PHY SAC spec section 6.1)
+ Mode register set to 7
+ Ibuff mode set to 7 (rx turned off)
+ P-Code/ N-code of no relevance as not used
+ Disable DDR PLL
+ Will be off from reset- no need
+ Need to reflash
+ DDR APB ( three resets - soft reset bit 0 to 1)
+ Drive odt etc
+ SGMII - from reset nothing to be done
+ See Jeff's spread sheet- default values listed
+ Extn clock off also defined in spread sheet
+ */
+
+
+/**
+ * ddr_off_mode(void)
+ * Assumed in Dynamic mode.
+ * i.e.
+ * SCB dynamic enable bit is high
+ * MSS core_up = 1
+ * dce[0,1,2] 0,0,0
+ * flash valid = 1
+ * IP:
+ * DECODER_DRIVER, ODT, IO all out of reset
+ *
+ * DDR PHY off mode that I took from version 1.58 of the DDR SAC spec.
+ * 1. DDR PHY OFF mode (not used at all).
+ * 1. Set the DDR_MODE register to 7
+ * This will disable all the drive and ODT to 0, as well as set all WPU bits.
+ * 2. Set the RPC_IBUF_MD_* registers to 7
+ * This will disable all receivers.
+ * 3. Set the REG_POWERDOWN_B register to 0
+ * This will disable the DDR PLL
+ *
+ */
+static void ddr_off_mode(void)
+{
+ /*
+ * DDR PLL is not turn on on reset- so no need to do anything
+ */
+ /*
+ * set the mode register to 7 => off mode
+ * From the DDRPHY training firmware spec.:
+ * If the DDR interface is unused, the firmware will have to write 3'b111
+ * into the APB_DDR_MODE register. This will disable all the DRIVERs, ODT
+ * and INPUT receivers.
+ * By default, WPD will be applied to all pads.
+ *
+ * If a user wants to apply WPU, this will have to be applied through
+ * firmware, by changing all RPC_WPU_*=0, and RPC_WPD_*=1, via APB register
+ * writes.
+ *
+ * Unused IO within an interface will automatically be shut off, as unused
+ * DQ/DM/DQS/and CA buffers and odt are automatically disabled by the
+ * decode, and put into WPD mode.
+ * Again, if the user wants to change this to WPU, the will have to write
+ * RPC_WPU_*=0 and RPC_WPD_*=1 to override the default.
+ *
+ */
+ /* Note: DMI_DBI [8:1] needs to be 0 (off) during training */
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ (LIBERO_SETTING_DDRPHY_MODE_OFF /* & DMI_DBI_MASK */);
+ /*
+ * VS for off mode
+ */
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ LIBERO_SETTING_DPC_BITS_OFF_MODE;
+
+ /*
+ * Toggle decoder here
+ * bit 0 == PERIPH soft reset, auto cleared
+ */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_DRIVER.SOFT_RESET_DECODER_DRIVER= 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_ODT.SOFT_RESET_DECODER_ODT = 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_IO.SOFT_RESET_DECODER_IO = 1U;
+
+ /*
+ * set ibuff mode to 7 in off mode
+ *
+ */
+ CFG_DDR_SGMII_PHY->rpc95.rpc95 = 0x07; /* addcmd I/O*/
+ CFG_DDR_SGMII_PHY->rpc96.rpc96 = 0x07; /* clk */
+ CFG_DDR_SGMII_PHY->rpc97.rpc97 = 0x07; /* dq */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x07; /* dqs */
+
+ /*
+ * Default WPU, modify If user wants Weak Pull Up
+ */
+ /*
+ * UNUSED_SPACE0
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ * todo: Do we need to add Pu/PD option for off mode to Libero setting?
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0000U;
+
+ /*
+ * REG_POWERDOWN_B on PLL turn-off, in case was turned on.
+ */
+ ddr_pll_config_scb_turn_off();
+ return;
+}
+
+
+/***************************************************************************//**
+ * Number of tests which write and read from DDR
+ * Tests data path through the cache and through AXI4 switch.
+ */
+#ifdef DDR_SANITY_CHECKS_EN
+static uint8_t memory_tests(void)
+{
+ uint64_t shift_walking_one = 4U;
+ uint64_t start_address = 0x0000000000000000U;
+ uint8_t error = 0U;
+ SIM_FEEDBACK1(199U);
+ /*
+ * Verify seg1 reg 2, datapath through AXI4 switch
+ */
+ while(shift_walking_one <= 28U) /* 28 => 1G, as 2**28 == 256K and this is
+ mult by (4 lanes) */
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0xC0000000U + (0x1U< 1G
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x1400000000U + (0x1U<= 4U)
+ {
+ start_address = (uint64_t)(0x1400000000U + \
+ (((0x1U<<(shift_walking_one +1)) - 1U) -0x0F) );
+ error = rw_sanity_chk((uint64_t *)start_address , (uint32_t)0x5U);
+
+ if(error)
+ {
+ ddr_error_count++;
+ SIM_FEEDBACK1(201U);
+ }
+ }
+
+ shift_walking_one++;
+ }
+ /*
+ * Verify mtc
+ */
+ SIM_FEEDBACK1(600U);
+ shift_walking_one = 4U;
+ while(shift_walking_one <= 28U) //28 => 1G
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x1U<= 4U)
+ {
+ start_address = (uint64_t)((((0x1U<<(shift_walking_one +1)) - 1U)\
+ -0x0F) );
+ error = mtc_sanity_check(start_address);
+
+ if(error)
+ {
+ ddr_error_count++;
+ SIM_FEEDBACK1(204U);
+ }
+ }
+ shift_walking_one++;
+ }
+
+ /*
+ * Verify seg0 reg 0, datapath through cache
+ */
+ SIM_FEEDBACK1(700U);
+ shift_walking_one = 4U;
+ while(shift_walking_one <= 27U) //28 => 1G
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x80000000U + (0x1U< 1G (0x10000000(address) * 4 (32bits wide))
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x1000000000U + (0x1U<expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\
+ & (uint32_t)~0x0FU);
+ }
+ //set expert_dfi_status_override_to_shim = 0x7
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U;
+ //set expert_mode_en = 0x21
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x21U;
+ //set dyn_ovr_dlycnt_dq_load* = 1
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 =\
+ (0xFFU << (lane * 8U));
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 |=\
+ 0x0FU;
+ }
+ //set dyn_ovr_dlycnt_dq_load* = 0
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 = 0U;
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1\
+ & (uint32_t)~0x0FU);
+ }
+ //set expert_mode_en = 0x8
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U;
+}
+
+/***************************************************************************//**
+ * increment_dq()
+ * set dyn_ovr_dlycnt_dq_move* = 0
+ * set dyn_ovr_dlycnt_dq_direction* = 1
+ * set expert_dfi_status_override_to_shim = 0x7
+ * set expert_mode_en = 0x21
+ *
+ * #to increment multiple times loop the move=0/1 multiple times
+ * set dyn_ovr_dlycnt_dq_move* = 1
+ * set dyn_ovr_dlycnt_dq_move* = 0
+ * #
+ * set expert_mode_en = 0x8
+ * @param lane
+ * @param move_count
+ */
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+static void increment_dq(uint8_t lane, uint32_t move_count)
+{
+ //set dyn_ovr_dlycnt_dq_move* = 0
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\
+ & ~0x0FU);
+ }
+ //set dyn_ovr_dlycnt_dq_direction* = 1
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg0.expert_dlycnt_direction_reg0\
+ = (0xFFU << (lane * 8U));
+ }
+ else
+ {
+ /* only four lines, use 0xFU */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 |= 0xFU;
+ }
+ /* set expert_dfi_status_override_to_shim = 0x7 */
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U;
+ /* set expert_mode_en = 0x21 */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x21U;
+ /* #to increment multiple times loop the move=0/1 multiple times */
+ move_count = move_count + move_count + move_count;
+ while(move_count)
+ {
+ // set dyn_ovr_dlycnt_dq_move* = 1
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0\
+ = (0xFFU << (lane * 8U));
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\
+ |= 0x0FU;
+ }
+ // set dyn_ovr_dlycnt_dq_move* = 0
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U;
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0\
+ = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 & ~0x0FU);
+ }
+ move_count--;
+ }
+ /* set expert_mode_en = 0x8 */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U;
+}
+#endif
+
+/***************************************************************************//**
+ *
+ */
+static void set_write_calib(uint8_t user_lanes)
+{
+ uint32_t temp = 0U;
+ uint8_t lane_to_set;
+ uint8_t shift = 0U;
+
+ /*
+ * Calculate the calibrated value and write back
+ */
+ calib_data.write_cal.lane_calib_result = 0U;
+ for (lane_to_set = 0x00U;\
+ lane_to_setexpert_mode_en.expert_mode_en = 0x00000008U;
+
+ SIM_FEEDBACK1(0xFF000000);
+ SIM_FEEDBACK1(calib_data.write_cal.lane_calib_result);
+ SIM_FEEDBACK1(0xFF000000);
+
+ /* set the calibrated value */
+ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib =\
+ calib_data.write_cal.lane_calib_result;
+}
+
+/***************************************************************************//**
+ *
+ * @param lane_to_set
+ */
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+static void set_calc_dq_delay_offset(uint8_t lane_to_set)
+{
+ uint32_t move_count;
+
+ load_dq(lane_to_set); /* set to start */
+
+ /* shift by 1 to divide by two */
+ move_count = ((calib_data.dq_cal.upper[lane_to_set] -\
+ calib_data.dq_cal.lower[lane_to_set] ) >> 1U) +\
+ calib_data.dq_cal.lower[lane_to_set];
+
+ increment_dq(lane_to_set, move_count);
+
+}
+#endif
+
+/***************************************************************************//**
+ *
+ * @param user_lanes
+ */
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+static void set_calib_values(uint8_t user_lanes)
+{
+ uint8_t lane_to_set;
+ uint32_t move_count;
+
+ for (lane_to_set = 0x00U;\
+ lane_to_set< user_lanes ; lane_to_set++)
+ {
+ set_calc_dq_delay_offset(lane_to_set);
+ }
+
+ /* and set the write calibration calculated */
+ set_write_calib(user_lanes);
+}
+#endif
+
+
+/***************************************************************************//**
+ * write_calibration_using_mtc
+ * Use Memory Test Core plugged in to the front end of the DDR controller to
+ * perform lane-based writes and read backs and increment write calibration
+ * offset for each lane until data match occurs. The Memory Test Core is the
+ * basis for all training.
+ *
+ * @param number_of_lanes_to_calibrate
+ * @return
+ */
+static uint8_t \
+ write_calibration_using_mtc(uint8_t number_of_lanes_to_calibrate)
+{
+ uint8_t laneToTest;
+ uint32_t result = 0U;
+ uint32_t cal_data;
+ uint64_t start_address = 0x0000000000000000ULL;
+ uint32_t size = ONE_MB_MTC; /* Number of reads for each iteration 2**size*/
+
+ calib_data.write_cal.status_lower = 0U;
+ /*
+ * bit 3 must be set if we want to use the
+ * expert_wrcalib
+ * register
+ */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000008U;
+
+ /*
+ * training carried out here- sweeping write calibration offset from 0 to F
+ * Explanation: A register, expert_wrcalib, is described in MSS DDR TIP
+ * Register Map [1], and its purpose is to delay--by X number of memory clock
+ * cycles--the write data, write data mask, and write output enable with the
+ * respect to the address and command for each lane.
+ */
+ for (cal_data=0x00000U;cal_data<0xfffffU;cal_data=cal_data+0x11111U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\rCalibration offset used:",cal_data &0xFUL);
+#endif
+ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib = cal_data;
+
+ for (laneToTest = 0x00U; laneToTestMC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE = 0x01;
+ DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = MR_ADDR ;
+ /*
+ * next:
+ * write desired VREF calibration range (0=Range 1, 1=Range 2) to bit 6
+ * of MR6
+ * write 0x00 to bits 5:0 of MR6 (base calibration value)
+ */
+ DDRCFG->MC_BASE2.INIT_MR_WR_DATA.INIT_MR_WR_DATA = MR_DATA;
+ DDRCFG->MC_BASE2.INIT_MR_WR_MASK.INIT_MR_WR_MASK = 0U;
+
+ DDRCFG->MC_BASE2.INIT_MR_W_REQ.INIT_MR_W_REQ = 0x01U;
+ while((DDRCFG->MC_BASE2.INIT_ACK.INIT_ACK & 0x01U) == 0U) /* wait for ack-
+ to confirm register is written */
+ {
+ test--;
+ if(test-- == 0U)
+ {
+ result = 1U;
+ break;
+ }
+ }
+ return result;
+}
+#endif
+
+#define VREF_INVALID 0x01U
+/***************************************************************************//**
+ * FPGA_VREFDQ_calibration_using_mtc(void)
+ * vary DQ voltage and set optimum DQ voltage
+ * @return
+ */
+#ifdef VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+static uint8_t FPGA_VREFDQ_calibration_using_mtc(void)
+{
+ uint8_t laneToTest, result = 0U;
+ uint64_t mask;
+ uint32_t vRef;
+ uint64_t start_address = 0x0000000000000000ULL;
+ uint64_t size = 4U;
+
+ /*
+ * Step 2a. FPGA VREF (Local VREF training)
+ * Train FPGA VREF using the vrgen_h and vrgen_v registers
+ */
+ {
+ /*
+ * To manipulate the FPGA VREF value, firmware must write to the
+ * DPC_BITS register, located at physical address 0x2000 7184.
+ * Full documentation for this register can be found in
+ * DFICFG Register Map [4].
+ */
+ /*
+ * See DPC_BITS definition in .h file
+ */
+ /* CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_h; */
+ /* CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_v; */
+
+ }
+
+ /*
+ * training carried out here- sweeping write calibration offset from 0 to F
+ * Explanation: A register, expert_wrcalib, is described in MSS DDR TIP
+ * Register Map [1], and its purpose is to delay--by X number of memory
+ * clock cycles--the write data, write data mask, and write output enable
+ * with the respect to the address and command for each lane.
+ */
+ calib_data.fpga_vref.vref_result = 0U;
+ calib_data.fpga_vref.lower = VREF_INVALID;
+ calib_data.fpga_vref.upper = VREF_INVALID;
+ calib_data.fpga_vref.status_lower = 0x00U;
+ calib_data.fpga_vref.status_upper = 0x00U;
+ mask = 0xFU; /* todo: obtain data width from user parameters */
+ uint32_t count = 0U;
+ /* each bit .25% of VDD ?? */
+ for (vRef=(0x1U<<4U);vRef<(0x1fU<<4U);vRef=vRef+(0x1U<<4U))
+ {
+ /*
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (~(0x1U<<10U)));
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (~(0x1fU<<4U))) | vRef;
+ */
+ /* need to set via the SCB, otherwise reset required. So lines below
+ * rather than above used */
+
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits &\
+ (~(0x1U<<10U)));
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits &\
+ (~(0x1fU<<4U))) | vRef;
+
+
+ /* read one to flush MTC - this is required */
+ result = MTC_test(1U<>1U);
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (0x1fU<<4U)) | vRef;
+ /* need to set via the SCB, otherwise reset required. */
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits &\
+ (0x1fU<<4U)) | vRef;
+ }
+ else
+ {
+ result = 1U; /* failed to get good data at any voltage level */
+ }
+
+ return result;
+}
+
+#endif
+
+#ifdef VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+#define MEM_VREF_INVALID 0xFFFFFFFFU
+/***************************************************************************//**
+ *
+ * VREFDQ_calibration_using_mtc
+ * In order to write to mode registers, the E51 must use the INIT_* interface
+ * at the front end of the DDR controller,
+ * which is available via a series of control registers described in the DDR
+ * CSR APB Register Map.
+ *
+ * @return
+ */
+static uint8_t VREFDQ_calibration_using_mtc(void)
+{
+ uint8_t laneToTest, result = 0U;
+ uint64_t mask;
+ uint32_t vRef;
+ uint64_t start_address = 0x00000000C0000000ULL;
+ uint64_t size = 4U;
+
+ /*
+ * Step 2a. FPGA VREF (Local VREF training)
+ * Train FPGA VREF using the vrgen_h and vrgen_v registers
+ */
+ {
+ /*
+ *
+ */
+ DDRCFG->MC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE = 0x01U;
+ DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = 6U ;
+ /*
+ * next:
+ * write desired VREF calibration range (0=Range 1, 1=Range 2) to bit 6
+ * of MR6
+ * write 0x00 to bits 5:0 of MR6 (base calibration value)
+ */
+ DDRCFG->MC_BASE2.INIT_MR_WR_DATA.INIT_MR_WR_DATA = 0U;
+ DDRCFG->MC_BASE2.INIT_MR_WR_MASK.INIT_MR_WR_MASK = (0x01U <<6U) |\
+ (0x3FU) ;
+
+ DDRCFG->MC_BASE2.INIT_MR_W_REQ.INIT_MR_W_REQ = 0x01U;
+ if((DDRCFG->MC_BASE2.INIT_ACK.INIT_ACK & 0x01U) == 0U) /* wait for ack-
+ to confirm register is written */
+ {
+
+ }
+ }
+
+ /*
+ * training carried out here- sweeping write calibration offset from 0 to F
+ * Explanation: A register, expert_wrcalib, is described in MSS DDR TIP
+ * Register Map [1], and its purpose is to delay--by X number of memory clock
+ * cycles--the write data, write data mask, and write output enable with the
+ * respect to the address and command for each lane.
+ */
+ calib_data.mem_vref.vref_result = 0U;
+ calib_data.mem_vref.lower = MEM_VREF_INVALID;
+ calib_data.mem_vref.upper = MEM_VREF_INVALID;
+ calib_data.mem_vref.status_lower = 0x00U;
+ calib_data.mem_vref.status_upper = 0x00U;
+ mask = 0xFU; /* todo: obtain data width from user paramaters */
+
+ for (vRef=(0x1U<<4U);vRef<0x3fU;vRef=(vRef+0x1U))
+ {
+ /*
+ * We change the value in the RPC register, but we will lso need to
+ * change SCB as will not be reflected without a soft reset
+ */
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (0x1fU<<4U)) | vRef;
+ /* need to set via the SCB, otherwise reset required. */
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits\
+ & (0x1fU<<4U)) | vRef;
+
+ /* read one to flush MTC - this is required */
+ result = MTC_test(1U<1U);
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (0x1fU<<4U)) | vRef;
+ /* need to set via the SCB, otherwise reset required. */
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits & (0x1fU<<4U)) | vRef;
+ }
+ else
+ {
+ result = 1U; /* failed to get good data at any voltage level */
+ }
+
+ return result;
+ }
+#endif
+
+/***************************************************************************//**
+ * MTC_test
+ * test memory using the NWL memory test core
+ * There are numerous options
+ * todo: Add user input as to option to use?
+ * @param laneToTest
+ * @param mask0
+ * @param mask1 some lane less DQ as only used for parity
+ * @param start_address
+ * @param size = x, where x is used as power of two 2**x e.g. 256K => x == 18
+ * @return pass/fail
+ */
+static uint8_t MTC_test(uint8_t mask, uint64_t start_address, uint32_t size, MTC_PATTERN data_pattern, MTC_ADD_PATTERN add_pattern, uint32_t *error)
+{
+ if((*error & MTC_TIMEOUT_ERROR) == MTC_TIMEOUT_ERROR)
+ {
+ return (uint8_t)*error;
+ }
+ /* Write Calibration - first configure memory test */
+ {
+ /*
+ * write calibration
+ * configure common memory test interface by writing registers:
+ * MT_STOP_ON_ERROR, MT_DATA_PATTERN, MT_ADDR_PATTERN, MT_ADDR_BITS
+ */
+ /* see MTC user guide */
+ DDRCFG->MEM_TEST.MT_STOP_ON_ERROR.MT_STOP_ON_ERROR = 0U;
+ /* make sure off, will turn on later. */
+ DDRCFG->MEM_TEST.MT_EN_SINGLE.MT_EN_SINGLE = 0x00U;
+ /*
+ * MT_DATA_PATTERN
+ *
+ * 0x00 => Counting pattern
+ * 0x01 => walking 1's
+ * 0x02 => pseudo random
+ * 0x03 => no repeating pseudo random
+ * 0x04 => alt 1's and 0's
+ * 0x05 => alt 5's and A's
+ * 0x06 => User specified
+ * 0x07 => pseudo random 16-bit
+ * 0x08 => pseudo random 8-bit
+ * 0x09- 0x0f reserved
+ *
+ */
+ {
+ /*
+ * Added changing pattern so write pattern is different, read back
+ * can not pass on previously written data
+ */
+ DDRCFG->MEM_TEST.MT_DATA_PATTERN.MT_DATA_PATTERN = data_pattern;
+ }
+ if(add_pattern == MTC_ADD_RANDOM)
+ {
+ /*
+ * MT_ADDR_PATTERN
+ * 0x00 => Count in pattern
+ * 0x01 => Pseudo Random Pattern
+ * 0x02 => Arbiatry Pattern Gen (user defined ) - Using RAMS
+ */
+ DDRCFG->MEM_TEST.MT_ADDR_PATTERN.MT_ADDR_PATTERN = 1U;
+ }
+ else
+ {
+ DDRCFG->MEM_TEST.MT_ADDR_PATTERN.MT_ADDR_PATTERN = 0U;
+ }
+ }
+
+ if(add_pattern != MTC_ADD_RANDOM)
+ {
+ /*
+ * Set the starting address and number to test
+ *
+ * MT_START_ADDR
+ * Starting address
+ * MT_ADRESS_BITS
+ * Length to test = 2 ** MT_ADRESS_BITS
+ */
+ DDRCFG->MEM_TEST.MT_START_ADDR_0.MT_START_ADDR_0 =\
+ (uint32_t)(start_address & 0xFFFFFFFFUL);
+ /* The address here is as see from DDR controller => start at 0x0*/
+ DDRCFG->MEM_TEST.MT_START_ADDR_1.MT_START_ADDR_1 =\
+ (uint32_t)((start_address >> 32U));
+ }
+ else
+ {
+ DDRCFG->MEM_TEST.MT_START_ADDR_0.MT_START_ADDR_0 = 0U;
+ DDRCFG->MEM_TEST.MT_START_ADDR_1.MT_START_ADDR_1 = 0U;
+ }
+ DDRCFG->MEM_TEST.MT_ADDR_BITS.MT_ADDR_BITS =\
+ size; /* 2 power 24 => 256k to do- make user programmable */
+
+ {
+ /*
+ * FOR each DQ lane
+ * set error mask registers MT_ERROR_MASK_* to mask out
+ * all error bits but the ones for the current DQ lane
+ * WHILE timeout counter is less than a threshold
+ * perform memory test by writing MT_EN or MT_EN_SINGLE
+ * wait for memory test completion by polling MT_DONE_ACK
+ * read back memory test error status from MT_ERROR_STS
+ * IF no error detected
+ * exit loop
+ * ELSE
+ * increment write calibration offset for current DQ lane
+ * by writing EXPERT_WRCALIB
+ * ENDWHILE
+ * ENDFOR
+ */
+ {
+ /*
+ * MT_ERROR_MASK
+ * All bits set in this field mask corresponding bits in data fields
+ * i.e. mt_error and mt_error_hold will not be set for errors in
+ * those fields
+ *
+ * Structure of 144 bits same as DFI bus
+ * 36 bits per lane ( 8 physical * 4) + (1ECC * 4) = 36
+ *
+ * If we wrote out the following pattern from software:
+ * 0x12345678
+ * 0x87654321
+ * 0x56789876
+ * 0x43211234
+ * We should see:
+ * NNNN_YXXX_XXX3_4YXX_XXXX_76YX_XXXX_X21Y_XXXX_XX78
+ * N: not used
+ * Y:
+ */
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 = 0xFFFFFFFFU;
+
+ if (mask & 0x1U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFFFFFF00U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xFFFFF00FU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFFFF00FFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xFFF00FFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFFFFFU;
+ }
+ if (mask & 0x2U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFFFF00FFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xFFF00FFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFF00FFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xF00FFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFFFFFU;
+ }
+ if (mask & 0x4U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFF00FFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xF00FFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0x00FFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0x0FFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFFFF0U;
+ }
+ if (mask & 0x8U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0x00FFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0x0FFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFFFFFFF0U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xFFFFFF00U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFF00FU;
+ }
+ if (mask & 0x10U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xFFFFFFF0U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFFFFFF0FU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xFFFFF0FFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFF0FFFU;
+ }
+
+ /*
+ * MT_EN
+ * Enables memory test
+ * If asserted at end of memory test, will keep going
+ */
+ DDRCFG->MEM_TEST.MT_EN.MT_EN = 0U;
+ /*
+ * MT_EN_SINGLE
+ * Will not repeat if this is set
+ */
+ DDRCFG->MEM_TEST.MT_EN_SINGLE.MT_EN_SINGLE = 0x00U;
+ DDRCFG->MEM_TEST.MT_EN_SINGLE.MT_EN_SINGLE = 0x01U;
+ /*
+ * MT_DONE_ACK
+ * Set when test completes
+ */
+ volatile uint64_t something_to_do = 0U;
+ #ifndef UNITTEST
+ while (( DDRCFG->MEM_TEST.MT_DONE_ACK.MT_DONE_ACK & 0x01U) == 0U)
+ {
+ something_to_do++;
+ if(something_to_do > 0xFFFFFFUL)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\rmtc test error:",MTC_TIMEOUT_ERROR);
+#endif
+ return (MTC_TIMEOUT_ERROR);
+ }
+ #ifdef RENODE_DEBUG
+ break;
+ #endif
+ }
+ #endif
+ }
+ }
+ /*
+ * MT_ERROR_STS
+ * Return the error status
+ * todo:Check NWL data and detail error states here
+ */
+
+ return (DDRCFG->MEM_TEST.MT_ERROR_STS.MT_ERROR_STS & 0x01U);
+
+}
+
+
+/***************************************************************************//**
+ * Setup DDRC
+ * These settings come from config tool
+ *
+ */
+#define _USE_SETTINGS_USED_IN_DDR3_FULL_CHIP_TEST
+
+static void init_ddrc(void)
+{
+ DDRCFG->ADDR_MAP.CFG_MANUAL_ADDRESS_MAP.CFG_MANUAL_ADDRESS_MAP =\
+ LIBERO_SETTING_CFG_MANUAL_ADDRESS_MAP;
+ DDRCFG->ADDR_MAP.CFG_CHIPADDR_MAP.CFG_CHIPADDR_MAP =\
+ LIBERO_SETTING_CFG_CHIPADDR_MAP;
+ DDRCFG->ADDR_MAP.CFG_CIDADDR_MAP.CFG_CIDADDR_MAP =\
+ LIBERO_SETTING_CFG_CIDADDR_MAP;
+ DDRCFG->ADDR_MAP.CFG_MB_AUTOPCH_COL_BIT_POS_LOW.CFG_MB_AUTOPCH_COL_BIT_POS_LOW =\
+ LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_LOW;
+ DDRCFG->ADDR_MAP.CFG_MB_AUTOPCH_COL_BIT_POS_HIGH.CFG_MB_AUTOPCH_COL_BIT_POS_HIGH =\
+ LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH;
+ DDRCFG->ADDR_MAP.CFG_BANKADDR_MAP_0.CFG_BANKADDR_MAP_0 =\
+ LIBERO_SETTING_CFG_BANKADDR_MAP_0;
+ DDRCFG->ADDR_MAP.CFG_BANKADDR_MAP_1.CFG_BANKADDR_MAP_1 =\
+ LIBERO_SETTING_CFG_BANKADDR_MAP_1;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_0.CFG_ROWADDR_MAP_0 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_0;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_1.CFG_ROWADDR_MAP_1 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_1;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_2.CFG_ROWADDR_MAP_2 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_2;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_3.CFG_ROWADDR_MAP_3 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_3;
+ DDRCFG->ADDR_MAP.CFG_COLADDR_MAP_0.CFG_COLADDR_MAP_0 =\
+ LIBERO_SETTING_CFG_COLADDR_MAP_0;
+ DDRCFG->ADDR_MAP.CFG_COLADDR_MAP_1.CFG_COLADDR_MAP_1 =\
+ LIBERO_SETTING_CFG_COLADDR_MAP_1;
+ DDRCFG->ADDR_MAP.CFG_COLADDR_MAP_2.CFG_COLADDR_MAP_2 =\
+ LIBERO_SETTING_CFG_COLADDR_MAP_2;
+ DDRCFG->MC_BASE3.CFG_VRCG_ENABLE.CFG_VRCG_ENABLE =\
+ LIBERO_SETTING_CFG_VRCG_ENABLE;
+ DDRCFG->MC_BASE3.CFG_VRCG_DISABLE.CFG_VRCG_DISABLE =\
+ LIBERO_SETTING_CFG_VRCG_DISABLE;
+ DDRCFG->MC_BASE3.CFG_WRITE_LATENCY_SET.CFG_WRITE_LATENCY_SET =\
+ LIBERO_SETTING_CFG_WRITE_LATENCY_SET;
+ DDRCFG->MC_BASE3.CFG_THERMAL_OFFSET.CFG_THERMAL_OFFSET =\
+ LIBERO_SETTING_CFG_THERMAL_OFFSET;
+ DDRCFG->MC_BASE3.CFG_SOC_ODT.CFG_SOC_ODT = LIBERO_SETTING_CFG_SOC_ODT;
+ DDRCFG->MC_BASE3.CFG_ODTE_CK.CFG_ODTE_CK = LIBERO_SETTING_CFG_ODTE_CK;
+ DDRCFG->MC_BASE3.CFG_ODTE_CS.CFG_ODTE_CS = LIBERO_SETTING_CFG_ODTE_CS;
+ DDRCFG->MC_BASE3.CFG_ODTD_CA.CFG_ODTD_CA = LIBERO_SETTING_CFG_ODTD_CA;
+ DDRCFG->MC_BASE3.CFG_LPDDR4_FSP_OP.CFG_LPDDR4_FSP_OP =\
+ LIBERO_SETTING_CFG_LPDDR4_FSP_OP;
+ DDRCFG->MC_BASE3.CFG_GENERATE_REFRESH_ON_SRX.CFG_GENERATE_REFRESH_ON_SRX =\
+ LIBERO_SETTING_CFG_GENERATE_REFRESH_ON_SRX;
+ DDRCFG->MC_BASE3.CFG_DBI_CL.CFG_DBI_CL = LIBERO_SETTING_CFG_DBI_CL;
+ DDRCFG->MC_BASE3.CFG_NON_DBI_CL.CFG_NON_DBI_CL =\
+ LIBERO_SETTING_CFG_NON_DBI_CL;
+ DDRCFG->MC_BASE3.INIT_FORCE_WRITE_DATA_0.INIT_FORCE_WRITE_DATA_0 =\
+ LIBERO_SETTING_INIT_FORCE_WRITE_DATA_0;
+ DDRCFG->MC_BASE1.CFG_WRITE_CRC.CFG_WRITE_CRC =\
+ LIBERO_SETTING_CFG_WRITE_CRC;
+ DDRCFG->MC_BASE1.CFG_MPR_READ_FORMAT.CFG_MPR_READ_FORMAT =\
+ LIBERO_SETTING_CFG_MPR_READ_FORMAT;
+ DDRCFG->MC_BASE1.CFG_WR_CMD_LAT_CRC_DM.CFG_WR_CMD_LAT_CRC_DM =\
+ LIBERO_SETTING_CFG_WR_CMD_LAT_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_FINE_GRAN_REF_MODE.CFG_FINE_GRAN_REF_MODE =\
+ LIBERO_SETTING_CFG_FINE_GRAN_REF_MODE;
+ DDRCFG->MC_BASE1.CFG_TEMP_SENSOR_READOUT.CFG_TEMP_SENSOR_READOUT =\
+ LIBERO_SETTING_CFG_TEMP_SENSOR_READOUT;
+ DDRCFG->MC_BASE1.CFG_PER_DRAM_ADDR_EN.CFG_PER_DRAM_ADDR_EN =\
+ LIBERO_SETTING_CFG_PER_DRAM_ADDR_EN;
+ DDRCFG->MC_BASE1.CFG_GEARDOWN_MODE.CFG_GEARDOWN_MODE =\
+ LIBERO_SETTING_CFG_GEARDOWN_MODE;
+ DDRCFG->MC_BASE1.CFG_WR_PREAMBLE.CFG_WR_PREAMBLE =\
+ LIBERO_SETTING_CFG_WR_PREAMBLE;
+ DDRCFG->MC_BASE1.CFG_RD_PREAMBLE.CFG_RD_PREAMBLE =\
+ LIBERO_SETTING_CFG_RD_PREAMBLE;
+ DDRCFG->MC_BASE1.CFG_RD_PREAMB_TRN_MODE.CFG_RD_PREAMB_TRN_MODE =\
+ LIBERO_SETTING_CFG_RD_PREAMB_TRN_MODE;
+ DDRCFG->MC_BASE1.CFG_SR_ABORT.CFG_SR_ABORT = LIBERO_SETTING_CFG_SR_ABORT;
+ DDRCFG->MC_BASE1.CFG_CS_TO_CMDADDR_LATENCY.CFG_CS_TO_CMDADDR_LATENCY =\
+ LIBERO_SETTING_CFG_CS_TO_CMDADDR_LATENCY;
+ DDRCFG->MC_BASE1.CFG_INT_VREF_MON.CFG_INT_VREF_MON =\
+ LIBERO_SETTING_CFG_INT_VREF_MON;
+ DDRCFG->MC_BASE1.CFG_TEMP_CTRL_REF_MODE.CFG_TEMP_CTRL_REF_MODE =\
+ LIBERO_SETTING_CFG_TEMP_CTRL_REF_MODE;
+ DDRCFG->MC_BASE1.CFG_TEMP_CTRL_REF_RANGE.CFG_TEMP_CTRL_REF_RANGE =\
+ LIBERO_SETTING_CFG_TEMP_CTRL_REF_RANGE;
+ DDRCFG->MC_BASE1.CFG_MAX_PWR_DOWN_MODE.CFG_MAX_PWR_DOWN_MODE =\
+ LIBERO_SETTING_CFG_MAX_PWR_DOWN_MODE;
+ DDRCFG->MC_BASE1.CFG_READ_DBI.CFG_READ_DBI = LIBERO_SETTING_CFG_READ_DBI;
+ DDRCFG->MC_BASE1.CFG_WRITE_DBI.CFG_WRITE_DBI =\
+ LIBERO_SETTING_CFG_WRITE_DBI;
+ DDRCFG->MC_BASE1.CFG_DATA_MASK.CFG_DATA_MASK =\
+ LIBERO_SETTING_CFG_DATA_MASK;
+ DDRCFG->MC_BASE1.CFG_CA_PARITY_PERSIST_ERR.CFG_CA_PARITY_PERSIST_ERR =\
+ LIBERO_SETTING_CFG_CA_PARITY_PERSIST_ERR;
+ DDRCFG->MC_BASE1.CFG_RTT_PARK.CFG_RTT_PARK = LIBERO_SETTING_CFG_RTT_PARK;
+ DDRCFG->MC_BASE1.CFG_ODT_INBUF_4_PD.CFG_ODT_INBUF_4_PD =\
+ LIBERO_SETTING_CFG_ODT_INBUF_4_PD;
+ DDRCFG->MC_BASE1.CFG_CA_PARITY_ERR_STATUS.CFG_CA_PARITY_ERR_STATUS =\
+ LIBERO_SETTING_CFG_CA_PARITY_ERR_STATUS;
+ DDRCFG->MC_BASE1.CFG_CRC_ERROR_CLEAR.CFG_CRC_ERROR_CLEAR =\
+ LIBERO_SETTING_CFG_CRC_ERROR_CLEAR;
+ DDRCFG->MC_BASE1.CFG_CA_PARITY_LATENCY.CFG_CA_PARITY_LATENCY =\
+ LIBERO_SETTING_CFG_CA_PARITY_LATENCY;
+ DDRCFG->MC_BASE1.CFG_CCD_S.CFG_CCD_S = LIBERO_SETTING_CFG_CCD_S;
+ DDRCFG->MC_BASE1.CFG_CCD_L.CFG_CCD_L = LIBERO_SETTING_CFG_CCD_L;
+ DDRCFG->MC_BASE1.CFG_VREFDQ_TRN_ENABLE.CFG_VREFDQ_TRN_ENABLE =\
+ LIBERO_SETTING_CFG_VREFDQ_TRN_ENABLE;
+ DDRCFG->MC_BASE1.CFG_VREFDQ_TRN_RANGE.CFG_VREFDQ_TRN_RANGE =\
+ LIBERO_SETTING_CFG_VREFDQ_TRN_RANGE;
+ DDRCFG->MC_BASE1.CFG_VREFDQ_TRN_VALUE.CFG_VREFDQ_TRN_VALUE =\
+ LIBERO_SETTING_CFG_VREFDQ_TRN_VALUE;
+ DDRCFG->MC_BASE1.CFG_RRD_S.CFG_RRD_S = LIBERO_SETTING_CFG_RRD_S;
+ DDRCFG->MC_BASE1.CFG_RRD_L.CFG_RRD_L = LIBERO_SETTING_CFG_RRD_L;
+ DDRCFG->MC_BASE1.CFG_WTR_S.CFG_WTR_S = LIBERO_SETTING_CFG_WTR_S;
+ DDRCFG->MC_BASE1.CFG_WTR_L.CFG_WTR_L = LIBERO_SETTING_CFG_WTR_L;
+ DDRCFG->MC_BASE1.CFG_WTR_S_CRC_DM.CFG_WTR_S_CRC_DM =\
+ LIBERO_SETTING_CFG_WTR_S_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_WTR_L_CRC_DM.CFG_WTR_L_CRC_DM =\
+ LIBERO_SETTING_CFG_WTR_L_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_WR_CRC_DM.CFG_WR_CRC_DM =\
+ LIBERO_SETTING_CFG_WR_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_RFC1.CFG_RFC1 = LIBERO_SETTING_CFG_RFC1;
+ DDRCFG->MC_BASE1.CFG_RFC2.CFG_RFC2 = LIBERO_SETTING_CFG_RFC2;
+ DDRCFG->MC_BASE1.CFG_RFC4.CFG_RFC4 = LIBERO_SETTING_CFG_RFC4;
+ DDRCFG->MC_BASE1.CFG_NIBBLE_DEVICES.CFG_NIBBLE_DEVICES =\
+ LIBERO_SETTING_CFG_NIBBLE_DEVICES;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS0_0.CFG_BIT_MAP_INDEX_CS0_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS0_1.CFG_BIT_MAP_INDEX_CS0_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS1_0.CFG_BIT_MAP_INDEX_CS1_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS1_1.CFG_BIT_MAP_INDEX_CS1_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS2_0.CFG_BIT_MAP_INDEX_CS2_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS2_1.CFG_BIT_MAP_INDEX_CS2_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS3_0.CFG_BIT_MAP_INDEX_CS3_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS3_1.CFG_BIT_MAP_INDEX_CS3_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS4_0.CFG_BIT_MAP_INDEX_CS4_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS4_1.CFG_BIT_MAP_INDEX_CS4_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS5_0.CFG_BIT_MAP_INDEX_CS5_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS5_1.CFG_BIT_MAP_INDEX_CS5_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS6_0.CFG_BIT_MAP_INDEX_CS6_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS6_1.CFG_BIT_MAP_INDEX_CS6_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS7_0.CFG_BIT_MAP_INDEX_CS7_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS7_1.CFG_BIT_MAP_INDEX_CS7_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS8_0.CFG_BIT_MAP_INDEX_CS8_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS8_1.CFG_BIT_MAP_INDEX_CS8_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS9_0.CFG_BIT_MAP_INDEX_CS9_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS9_1.CFG_BIT_MAP_INDEX_CS9_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS10_0.CFG_BIT_MAP_INDEX_CS10_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS10_1.CFG_BIT_MAP_INDEX_CS10_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS11_0.CFG_BIT_MAP_INDEX_CS11_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS11_1.CFG_BIT_MAP_INDEX_CS11_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS12_0.CFG_BIT_MAP_INDEX_CS12_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS12_1.CFG_BIT_MAP_INDEX_CS12_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS13_0.CFG_BIT_MAP_INDEX_CS13_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS13_1.CFG_BIT_MAP_INDEX_CS13_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS14_0.CFG_BIT_MAP_INDEX_CS14_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS14_1.CFG_BIT_MAP_INDEX_CS14_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS15_0.CFG_BIT_MAP_INDEX_CS15_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS15_1.CFG_BIT_MAP_INDEX_CS15_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_1;
+ DDRCFG->MC_BASE1.CFG_NUM_LOGICAL_RANKS_PER_3DS.CFG_NUM_LOGICAL_RANKS_PER_3DS =\
+ LIBERO_SETTING_CFG_NUM_LOGICAL_RANKS_PER_3DS;
+ DDRCFG->MC_BASE1.CFG_RFC_DLR1.CFG_RFC_DLR1 = LIBERO_SETTING_CFG_RFC_DLR1;
+ DDRCFG->MC_BASE1.CFG_RFC_DLR2.CFG_RFC_DLR2 = LIBERO_SETTING_CFG_RFC_DLR2;
+ DDRCFG->MC_BASE1.CFG_RFC_DLR4.CFG_RFC_DLR4 = LIBERO_SETTING_CFG_RFC_DLR4;
+ DDRCFG->MC_BASE1.CFG_RRD_DLR.CFG_RRD_DLR = LIBERO_SETTING_CFG_RRD_DLR;
+ DDRCFG->MC_BASE1.CFG_FAW_DLR.CFG_FAW_DLR = LIBERO_SETTING_CFG_FAW_DLR;
+ DDRCFG->MC_BASE1.CFG_ADVANCE_ACTIVATE_READY.CFG_ADVANCE_ACTIVATE_READY =\
+ LIBERO_SETTING_CFG_ADVANCE_ACTIVATE_READY;
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ LIBERO_SETTING_CTRLR_SOFT_RESET_N;
+ DDRCFG->MC_BASE2.CFG_LOOKAHEAD_PCH.CFG_LOOKAHEAD_PCH =\
+ LIBERO_SETTING_CFG_LOOKAHEAD_PCH;
+ DDRCFG->MC_BASE2.CFG_LOOKAHEAD_ACT.CFG_LOOKAHEAD_ACT =\
+ LIBERO_SETTING_CFG_LOOKAHEAD_ACT;
+ DDRCFG->MC_BASE2.INIT_AUTOINIT_DISABLE.INIT_AUTOINIT_DISABLE =\
+ LIBERO_SETTING_INIT_AUTOINIT_DISABLE;
+ DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET =\
+ LIBERO_SETTING_INIT_FORCE_RESET;
+ DDRCFG->MC_BASE2.INIT_GEARDOWN_EN.INIT_GEARDOWN_EN =\
+ LIBERO_SETTING_INIT_GEARDOWN_EN;
+ DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE =\
+ LIBERO_SETTING_INIT_DISABLE_CKE;
+ DDRCFG->MC_BASE2.INIT_CS.INIT_CS = LIBERO_SETTING_INIT_CS;
+ DDRCFG->MC_BASE2.INIT_PRECHARGE_ALL.INIT_PRECHARGE_ALL =\
+ LIBERO_SETTING_INIT_PRECHARGE_ALL;
+ DDRCFG->MC_BASE2.INIT_REFRESH.INIT_REFRESH = LIBERO_SETTING_INIT_REFRESH;
+ DDRCFG->MC_BASE2.INIT_ZQ_CAL_REQ.INIT_ZQ_CAL_REQ =\
+ LIBERO_SETTING_INIT_ZQ_CAL_REQ;
+ DDRCFG->MC_BASE2.CFG_BL.CFG_BL = LIBERO_SETTING_CFG_BL;
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = LIBERO_SETTING_CTRLR_INIT;
+ DDRCFG->MC_BASE2.CFG_AUTO_REF_EN.CFG_AUTO_REF_EN =\
+ LIBERO_SETTING_CFG_AUTO_REF_EN;
+ DDRCFG->MC_BASE2.CFG_RAS.CFG_RAS = LIBERO_SETTING_CFG_RAS;
+ DDRCFG->MC_BASE2.CFG_RCD.CFG_RCD = LIBERO_SETTING_CFG_RCD;
+ DDRCFG->MC_BASE2.CFG_RRD.CFG_RRD = LIBERO_SETTING_CFG_RRD;
+ DDRCFG->MC_BASE2.CFG_RP.CFG_RP = LIBERO_SETTING_CFG_RP;
+ DDRCFG->MC_BASE2.CFG_RC.CFG_RC = LIBERO_SETTING_CFG_RC;
+ DDRCFG->MC_BASE2.CFG_FAW.CFG_FAW = LIBERO_SETTING_CFG_FAW;
+ DDRCFG->MC_BASE2.CFG_RFC.CFG_RFC = LIBERO_SETTING_CFG_RFC;
+ DDRCFG->MC_BASE2.CFG_RTP.CFG_RTP = LIBERO_SETTING_CFG_RTP;
+ DDRCFG->MC_BASE2.CFG_WR.CFG_WR = LIBERO_SETTING_CFG_WR;
+ DDRCFG->MC_BASE2.CFG_WTR.CFG_WTR = LIBERO_SETTING_CFG_WTR;
+ DDRCFG->MC_BASE2.CFG_PASR.CFG_PASR = LIBERO_SETTING_CFG_PASR;
+ DDRCFG->MC_BASE2.CFG_XP.CFG_XP = LIBERO_SETTING_CFG_XP;
+ DDRCFG->MC_BASE2.CFG_XSR.CFG_XSR = LIBERO_SETTING_CFG_XSR;
+ DDRCFG->MC_BASE2.CFG_CL.CFG_CL = LIBERO_SETTING_CFG_CL;
+ DDRCFG->MC_BASE2.CFG_READ_TO_WRITE.CFG_READ_TO_WRITE =\
+ LIBERO_SETTING_CFG_READ_TO_WRITE;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_WRITE.CFG_WRITE_TO_WRITE =\
+ LIBERO_SETTING_CFG_WRITE_TO_WRITE;
+ DDRCFG->MC_BASE2.CFG_READ_TO_READ.CFG_READ_TO_READ =\
+ LIBERO_SETTING_CFG_READ_TO_READ;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_READ.CFG_WRITE_TO_READ =\
+ LIBERO_SETTING_CFG_WRITE_TO_READ;
+ DDRCFG->MC_BASE2.CFG_READ_TO_WRITE_ODT.CFG_READ_TO_WRITE_ODT =\
+ LIBERO_SETTING_CFG_READ_TO_WRITE_ODT;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_WRITE_ODT.CFG_WRITE_TO_WRITE_ODT =\
+ LIBERO_SETTING_CFG_WRITE_TO_WRITE_ODT;
+ DDRCFG->MC_BASE2.CFG_READ_TO_READ_ODT.CFG_READ_TO_READ_ODT =\
+ LIBERO_SETTING_CFG_READ_TO_READ_ODT;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_READ_ODT.CFG_WRITE_TO_READ_ODT =\
+ LIBERO_SETTING_CFG_WRITE_TO_READ_ODT;
+ DDRCFG->MC_BASE2.CFG_MIN_READ_IDLE.CFG_MIN_READ_IDLE =\
+ LIBERO_SETTING_CFG_MIN_READ_IDLE;
+ DDRCFG->MC_BASE2.CFG_MRD.CFG_MRD = LIBERO_SETTING_CFG_MRD;
+ DDRCFG->MC_BASE2.CFG_BT.CFG_BT = LIBERO_SETTING_CFG_BT;
+ DDRCFG->MC_BASE2.CFG_DS.CFG_DS = LIBERO_SETTING_CFG_DS;
+ DDRCFG->MC_BASE2.CFG_QOFF.CFG_QOFF = LIBERO_SETTING_CFG_QOFF;
+ DDRCFG->MC_BASE2.CFG_RTT.CFG_RTT = LIBERO_SETTING_CFG_RTT;
+ DDRCFG->MC_BASE2.CFG_DLL_DISABLE.CFG_DLL_DISABLE =\
+ LIBERO_SETTING_CFG_DLL_DISABLE;
+ DDRCFG->MC_BASE2.CFG_REF_PER.CFG_REF_PER = LIBERO_SETTING_CFG_REF_PER;
+ DDRCFG->MC_BASE2.CFG_STARTUP_DELAY.CFG_STARTUP_DELAY =\
+ LIBERO_SETTING_CFG_STARTUP_DELAY;
+ DDRCFG->MC_BASE2.CFG_MEM_COLBITS.CFG_MEM_COLBITS =\
+ LIBERO_SETTING_CFG_MEM_COLBITS;
+ DDRCFG->MC_BASE2.CFG_MEM_ROWBITS.CFG_MEM_ROWBITS =\
+ LIBERO_SETTING_CFG_MEM_ROWBITS;
+ DDRCFG->MC_BASE2.CFG_MEM_BANKBITS.CFG_MEM_BANKBITS =\
+ LIBERO_SETTING_CFG_MEM_BANKBITS;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS0.CFG_ODT_RD_MAP_CS0 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS0;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS1.CFG_ODT_RD_MAP_CS1 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS1;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS2.CFG_ODT_RD_MAP_CS2 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS2;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS3.CFG_ODT_RD_MAP_CS3 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS3;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS4.CFG_ODT_RD_MAP_CS4 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS4;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS5.CFG_ODT_RD_MAP_CS5 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS5;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS6.CFG_ODT_RD_MAP_CS6 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS6;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS7.CFG_ODT_RD_MAP_CS7 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS7;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS0.CFG_ODT_WR_MAP_CS0 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS0;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS1.CFG_ODT_WR_MAP_CS1 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS1;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS2.CFG_ODT_WR_MAP_CS2 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS2;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS3.CFG_ODT_WR_MAP_CS3 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS3;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS4.CFG_ODT_WR_MAP_CS4 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS4;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS5.CFG_ODT_WR_MAP_CS5 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS5;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS6.CFG_ODT_WR_MAP_CS6 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS6;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS7.CFG_ODT_WR_MAP_CS7 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS7;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_TURN_ON.CFG_ODT_RD_TURN_ON =\
+ LIBERO_SETTING_CFG_ODT_RD_TURN_ON;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_TURN_ON.CFG_ODT_WR_TURN_ON =\
+ LIBERO_SETTING_CFG_ODT_WR_TURN_ON;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_TURN_OFF.CFG_ODT_RD_TURN_OFF =\
+ LIBERO_SETTING_CFG_ODT_RD_TURN_OFF;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_TURN_OFF.CFG_ODT_WR_TURN_OFF =\
+ LIBERO_SETTING_CFG_ODT_WR_TURN_OFF;
+ DDRCFG->MC_BASE2.CFG_EMR3.CFG_EMR3 = LIBERO_SETTING_CFG_EMR3;
+ DDRCFG->MC_BASE2.CFG_TWO_T.CFG_TWO_T = LIBERO_SETTING_CFG_TWO_T;
+ DDRCFG->MC_BASE2.CFG_TWO_T_SEL_CYCLE.CFG_TWO_T_SEL_CYCLE =\
+ LIBERO_SETTING_CFG_TWO_T_SEL_CYCLE;
+ DDRCFG->MC_BASE2.CFG_REGDIMM.CFG_REGDIMM = LIBERO_SETTING_CFG_REGDIMM;
+ DDRCFG->MC_BASE2.CFG_MOD.CFG_MOD = LIBERO_SETTING_CFG_MOD;
+ DDRCFG->MC_BASE2.CFG_XS.CFG_XS = LIBERO_SETTING_CFG_XS;
+ DDRCFG->MC_BASE2.CFG_XSDLL.CFG_XSDLL = LIBERO_SETTING_CFG_XSDLL;
+ DDRCFG->MC_BASE2.CFG_XPR.CFG_XPR = LIBERO_SETTING_CFG_XPR;
+ DDRCFG->MC_BASE2.CFG_AL_MODE.CFG_AL_MODE = LIBERO_SETTING_CFG_AL_MODE;
+ DDRCFG->MC_BASE2.CFG_CWL.CFG_CWL = LIBERO_SETTING_CFG_CWL;
+ DDRCFG->MC_BASE2.CFG_BL_MODE.CFG_BL_MODE = LIBERO_SETTING_CFG_BL_MODE;
+ DDRCFG->MC_BASE2.CFG_TDQS.CFG_TDQS = LIBERO_SETTING_CFG_TDQS;
+ DDRCFG->MC_BASE2.CFG_RTT_WR.CFG_RTT_WR = LIBERO_SETTING_CFG_RTT_WR;
+ DDRCFG->MC_BASE2.CFG_LP_ASR.CFG_LP_ASR = LIBERO_SETTING_CFG_LP_ASR;
+ DDRCFG->MC_BASE2.CFG_AUTO_SR.CFG_AUTO_SR = LIBERO_SETTING_CFG_AUTO_SR;
+ DDRCFG->MC_BASE2.CFG_SRT.CFG_SRT = LIBERO_SETTING_CFG_SRT;
+ DDRCFG->MC_BASE2.CFG_ADDR_MIRROR.CFG_ADDR_MIRROR =\
+ LIBERO_SETTING_CFG_ADDR_MIRROR;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_TYPE.CFG_ZQ_CAL_TYPE =\
+ LIBERO_SETTING_CFG_ZQ_CAL_TYPE;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_PER.CFG_ZQ_CAL_PER =\
+ LIBERO_SETTING_CFG_ZQ_CAL_PER;
+ DDRCFG->MC_BASE2.CFG_AUTO_ZQ_CAL_EN.CFG_AUTO_ZQ_CAL_EN =\
+ LIBERO_SETTING_CFG_AUTO_ZQ_CAL_EN;
+ DDRCFG->MC_BASE2.CFG_MEMORY_TYPE.CFG_MEMORY_TYPE =\
+ LIBERO_SETTING_CFG_MEMORY_TYPE;
+ DDRCFG->MC_BASE2.CFG_ONLY_SRANK_CMDS.CFG_ONLY_SRANK_CMDS =\
+ LIBERO_SETTING_CFG_ONLY_SRANK_CMDS;
+ DDRCFG->MC_BASE2.CFG_NUM_RANKS.CFG_NUM_RANKS =\
+ LIBERO_SETTING_CFG_NUM_RANKS;
+ DDRCFG->MC_BASE2.CFG_QUAD_RANK.CFG_QUAD_RANK =\
+ LIBERO_SETTING_CFG_QUAD_RANK;
+ DDRCFG->MC_BASE2.CFG_EARLY_RANK_TO_WR_START.CFG_EARLY_RANK_TO_WR_START =\
+ LIBERO_SETTING_CFG_EARLY_RANK_TO_WR_START;
+ DDRCFG->MC_BASE2.CFG_EARLY_RANK_TO_RD_START.CFG_EARLY_RANK_TO_RD_START =\
+ LIBERO_SETTING_CFG_EARLY_RANK_TO_RD_START;
+ DDRCFG->MC_BASE2.CFG_PASR_BANK.CFG_PASR_BANK =\
+ LIBERO_SETTING_CFG_PASR_BANK;
+ DDRCFG->MC_BASE2.CFG_PASR_SEG.CFG_PASR_SEG = LIBERO_SETTING_CFG_PASR_SEG;
+ DDRCFG->MC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE =\
+ LIBERO_SETTING_INIT_MRR_MODE;
+ DDRCFG->MC_BASE2.INIT_MR_W_REQ.INIT_MR_W_REQ =\
+ LIBERO_SETTING_INIT_MR_W_REQ;
+ DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = LIBERO_SETTING_INIT_MR_ADDR;
+ DDRCFG->MC_BASE2.INIT_MR_WR_DATA.INIT_MR_WR_DATA =\
+ LIBERO_SETTING_INIT_MR_WR_DATA;
+ DDRCFG->MC_BASE2.INIT_MR_WR_MASK.INIT_MR_WR_MASK =\
+ LIBERO_SETTING_INIT_MR_WR_MASK;
+ DDRCFG->MC_BASE2.INIT_NOP.INIT_NOP = LIBERO_SETTING_INIT_NOP;
+ DDRCFG->MC_BASE2.CFG_INIT_DURATION.CFG_INIT_DURATION =\
+ LIBERO_SETTING_CFG_INIT_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQINIT_CAL_DURATION.CFG_ZQINIT_CAL_DURATION =\
+ LIBERO_SETTING_CFG_ZQINIT_CAL_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_L_DURATION.CFG_ZQ_CAL_L_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_L_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_S_DURATION.CFG_ZQ_CAL_S_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_S_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_R_DURATION.CFG_ZQ_CAL_R_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_R_DURATION;
+ DDRCFG->MC_BASE2.CFG_MRR.CFG_MRR = LIBERO_SETTING_CFG_MRR;
+ DDRCFG->MC_BASE2.CFG_MRW.CFG_MRW = LIBERO_SETTING_CFG_MRW;
+ DDRCFG->MC_BASE2.CFG_ODT_POWERDOWN.CFG_ODT_POWERDOWN =\
+ LIBERO_SETTING_CFG_ODT_POWERDOWN;
+ DDRCFG->MC_BASE2.CFG_WL.CFG_WL = LIBERO_SETTING_CFG_WL;
+ DDRCFG->MC_BASE2.CFG_RL.CFG_RL = LIBERO_SETTING_CFG_RL;
+ DDRCFG->MC_BASE2.CFG_CAL_READ_PERIOD.CFG_CAL_READ_PERIOD =\
+ LIBERO_SETTING_CFG_CAL_READ_PERIOD;
+ DDRCFG->MC_BASE2.CFG_NUM_CAL_READS.CFG_NUM_CAL_READS =\
+ LIBERO_SETTING_CFG_NUM_CAL_READS;
+ DDRCFG->MC_BASE2.INIT_SELF_REFRESH.INIT_SELF_REFRESH =\
+ LIBERO_SETTING_INIT_SELF_REFRESH;
+ DDRCFG->MC_BASE2.INIT_POWER_DOWN.INIT_POWER_DOWN =\
+ LIBERO_SETTING_INIT_POWER_DOWN;
+ DDRCFG->MC_BASE2.INIT_FORCE_WRITE.INIT_FORCE_WRITE =\
+ LIBERO_SETTING_INIT_FORCE_WRITE;
+ DDRCFG->MC_BASE2.INIT_FORCE_WRITE_CS.INIT_FORCE_WRITE_CS =\
+ LIBERO_SETTING_INIT_FORCE_WRITE_CS;
+ DDRCFG->MC_BASE2.CFG_CTRLR_INIT_DISABLE.CFG_CTRLR_INIT_DISABLE =\
+ LIBERO_SETTING_CFG_CTRLR_INIT_DISABLE;
+ DDRCFG->MC_BASE2.INIT_RDIMM_COMPLETE.INIT_RDIMM_COMPLETE =\
+ LIBERO_SETTING_INIT_RDIMM_COMPLETE;
+ DDRCFG->MC_BASE2.CFG_RDIMM_LAT.CFG_RDIMM_LAT =\
+ LIBERO_SETTING_CFG_RDIMM_LAT;
+ DDRCFG->MC_BASE2.CFG_RDIMM_BSIDE_INVERT.CFG_RDIMM_BSIDE_INVERT =\
+ LIBERO_SETTING_CFG_RDIMM_BSIDE_INVERT;
+ DDRCFG->MC_BASE2.CFG_LRDIMM.CFG_LRDIMM = LIBERO_SETTING_CFG_LRDIMM;
+ DDRCFG->MC_BASE2.INIT_MEMORY_RESET_MASK.INIT_MEMORY_RESET_MASK =\
+ LIBERO_SETTING_INIT_MEMORY_RESET_MASK;
+ DDRCFG->MC_BASE2.CFG_RD_PREAMB_TOGGLE.CFG_RD_PREAMB_TOGGLE =\
+ LIBERO_SETTING_CFG_RD_PREAMB_TOGGLE;
+ DDRCFG->MC_BASE2.CFG_RD_POSTAMBLE.CFG_RD_POSTAMBLE =\
+ LIBERO_SETTING_CFG_RD_POSTAMBLE;
+ DDRCFG->MC_BASE2.CFG_PU_CAL.CFG_PU_CAL = LIBERO_SETTING_CFG_PU_CAL;
+ DDRCFG->MC_BASE2.CFG_DQ_ODT.CFG_DQ_ODT = LIBERO_SETTING_CFG_DQ_ODT;
+ DDRCFG->MC_BASE2.CFG_CA_ODT.CFG_CA_ODT = LIBERO_SETTING_CFG_CA_ODT;
+ DDRCFG->MC_BASE2.CFG_ZQLATCH_DURATION.CFG_ZQLATCH_DURATION =\
+ LIBERO_SETTING_CFG_ZQLATCH_DURATION;
+ DDRCFG->MC_BASE2.INIT_CAL_SELECT.INIT_CAL_SELECT =\
+ LIBERO_SETTING_INIT_CAL_SELECT;
+ DDRCFG->MC_BASE2.INIT_CAL_L_R_REQ.INIT_CAL_L_R_REQ =\
+ LIBERO_SETTING_INIT_CAL_L_R_REQ;
+ DDRCFG->MC_BASE2.INIT_CAL_L_B_SIZE.INIT_CAL_L_B_SIZE =\
+ LIBERO_SETTING_INIT_CAL_L_B_SIZE;
+ DDRCFG->MC_BASE2.INIT_RWFIFO.INIT_RWFIFO = LIBERO_SETTING_INIT_RWFIFO;
+ DDRCFG->MC_BASE2.INIT_RD_DQCAL.INIT_RD_DQCAL =\
+ LIBERO_SETTING_INIT_RD_DQCAL;
+ DDRCFG->MC_BASE2.INIT_START_DQSOSC.INIT_START_DQSOSC =\
+ LIBERO_SETTING_INIT_START_DQSOSC;
+ DDRCFG->MC_BASE2.INIT_STOP_DQSOSC.INIT_STOP_DQSOSC =\
+ LIBERO_SETTING_INIT_STOP_DQSOSC;
+ DDRCFG->MC_BASE2.INIT_ZQ_CAL_START.INIT_ZQ_CAL_START =\
+ LIBERO_SETTING_INIT_ZQ_CAL_START;
+ DDRCFG->MC_BASE2.CFG_WR_POSTAMBLE.CFG_WR_POSTAMBLE =\
+ LIBERO_SETTING_CFG_WR_POSTAMBLE;
+ DDRCFG->MC_BASE2.INIT_CAL_L_ADDR_0.INIT_CAL_L_ADDR_0 =\
+ LIBERO_SETTING_INIT_CAL_L_ADDR_0;
+ DDRCFG->MC_BASE2.INIT_CAL_L_ADDR_1.INIT_CAL_L_ADDR_1 =\
+ LIBERO_SETTING_INIT_CAL_L_ADDR_1;
+ DDRCFG->MC_BASE2.CFG_CTRLUPD_TRIG.CFG_CTRLUPD_TRIG =\
+ LIBERO_SETTING_CFG_CTRLUPD_TRIG;
+ DDRCFG->MC_BASE2.CFG_CTRLUPD_START_DELAY.CFG_CTRLUPD_START_DELAY =\
+ LIBERO_SETTING_CFG_CTRLUPD_START_DELAY;
+ DDRCFG->MC_BASE2.CFG_DFI_T_CTRLUPD_MAX.CFG_DFI_T_CTRLUPD_MAX =\
+ LIBERO_SETTING_CFG_DFI_T_CTRLUPD_MAX;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_SEL.CFG_CTRLR_BUSY_SEL =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_SEL;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_VALUE.CFG_CTRLR_BUSY_VALUE =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_VALUE;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_TURN_OFF_DELAY.CFG_CTRLR_BUSY_TURN_OFF_DELAY =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_TURN_OFF_DELAY;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW.CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_RESTART_HOLDOFF.CFG_CTRLR_BUSY_RESTART_HOLDOFF =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_RESTART_HOLDOFF;
+ DDRCFG->MC_BASE2.CFG_PARITY_RDIMM_DELAY.CFG_PARITY_RDIMM_DELAY =\
+ LIBERO_SETTING_CFG_PARITY_RDIMM_DELAY;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_ENABLE.CFG_CTRLR_BUSY_ENABLE =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_ENABLE;
+ DDRCFG->MC_BASE2.CFG_ASYNC_ODT.CFG_ASYNC_ODT =\
+ LIBERO_SETTING_CFG_ASYNC_ODT;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_DURATION.CFG_ZQ_CAL_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_DURATION;
+ DDRCFG->MC_BASE2.CFG_MRRI.CFG_MRRI = LIBERO_SETTING_CFG_MRRI;
+ DDRCFG->MC_BASE2.INIT_ODT_FORCE_EN.INIT_ODT_FORCE_EN =\
+ LIBERO_SETTING_INIT_ODT_FORCE_EN;
+ DDRCFG->MC_BASE2.INIT_ODT_FORCE_RANK.INIT_ODT_FORCE_RANK =\
+ LIBERO_SETTING_INIT_ODT_FORCE_RANK;
+ DDRCFG->MC_BASE2.CFG_PHYUPD_ACK_DELAY.CFG_PHYUPD_ACK_DELAY =\
+ LIBERO_SETTING_CFG_PHYUPD_ACK_DELAY;
+ DDRCFG->MC_BASE2.CFG_MIRROR_X16_BG0_BG1.CFG_MIRROR_X16_BG0_BG1 =\
+ LIBERO_SETTING_CFG_MIRROR_X16_BG0_BG1;
+ DDRCFG->MC_BASE2.INIT_PDA_MR_W_REQ.INIT_PDA_MR_W_REQ =\
+ LIBERO_SETTING_INIT_PDA_MR_W_REQ;
+ DDRCFG->MC_BASE2.INIT_PDA_NIBBLE_SELECT.INIT_PDA_NIBBLE_SELECT =\
+ LIBERO_SETTING_INIT_PDA_NIBBLE_SELECT;
+ DDRCFG->MC_BASE2.CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH.CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH =\
+ LIBERO_SETTING_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH;
+ DDRCFG->MC_BASE2.CFG_CKSRE.CFG_CKSRE = LIBERO_SETTING_CFG_CKSRE;
+ DDRCFG->MC_BASE2.CFG_CKSRX.CFG_CKSRX = LIBERO_SETTING_CFG_CKSRX;
+ DDRCFG->MC_BASE2.CFG_RCD_STAB.CFG_RCD_STAB = LIBERO_SETTING_CFG_RCD_STAB;
+ DDRCFG->MC_BASE2.CFG_DFI_T_CTRL_DELAY.CFG_DFI_T_CTRL_DELAY =\
+ LIBERO_SETTING_CFG_DFI_T_CTRL_DELAY;
+ DDRCFG->MC_BASE2.CFG_DFI_T_DRAM_CLK_ENABLE.CFG_DFI_T_DRAM_CLK_ENABLE =\
+ LIBERO_SETTING_CFG_DFI_T_DRAM_CLK_ENABLE;
+ DDRCFG->MC_BASE2.CFG_IDLE_TIME_TO_SELF_REFRESH.CFG_IDLE_TIME_TO_SELF_REFRESH =\
+ LIBERO_SETTING_CFG_IDLE_TIME_TO_SELF_REFRESH;
+ DDRCFG->MC_BASE2.CFG_IDLE_TIME_TO_POWER_DOWN.CFG_IDLE_TIME_TO_POWER_DOWN =\
+ LIBERO_SETTING_CFG_IDLE_TIME_TO_POWER_DOWN;
+ DDRCFG->MC_BASE2.CFG_BURST_RW_REFRESH_HOLDOFF.CFG_BURST_RW_REFRESH_HOLDOFF =\
+ LIBERO_SETTING_CFG_BURST_RW_REFRESH_HOLDOFF;
+ DDRCFG->MC_BASE2.CFG_BG_INTERLEAVE.CFG_BG_INTERLEAVE =\
+ LIBERO_SETTING_CFG_BG_INTERLEAVE;
+ DDRCFG->MC_BASE2.CFG_REFRESH_DURING_PHY_TRAINING.CFG_REFRESH_DURING_PHY_TRAINING =\
+ LIBERO_SETTING_CFG_REFRESH_DURING_PHY_TRAINING;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P0.CFG_STARVE_TIMEOUT_P0 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P0;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P1.CFG_STARVE_TIMEOUT_P1 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P1;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P2.CFG_STARVE_TIMEOUT_P2 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P2;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P3.CFG_STARVE_TIMEOUT_P3 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P3;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P4.CFG_STARVE_TIMEOUT_P4 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P4;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P5.CFG_STARVE_TIMEOUT_P5 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P5;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P6.CFG_STARVE_TIMEOUT_P6 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P6;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P7.CFG_STARVE_TIMEOUT_P7 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P7;
+ DDRCFG->REORDER.CFG_REORDER_EN.CFG_REORDER_EN =\
+ LIBERO_SETTING_CFG_REORDER_EN;
+ DDRCFG->REORDER.CFG_REORDER_QUEUE_EN.CFG_REORDER_QUEUE_EN =\
+ LIBERO_SETTING_CFG_REORDER_QUEUE_EN;
+ DDRCFG->REORDER.CFG_INTRAPORT_REORDER_EN.CFG_INTRAPORT_REORDER_EN =\
+ LIBERO_SETTING_CFG_INTRAPORT_REORDER_EN;
+ DDRCFG->REORDER.CFG_MAINTAIN_COHERENCY.CFG_MAINTAIN_COHERENCY =\
+ LIBERO_SETTING_CFG_MAINTAIN_COHERENCY;
+ DDRCFG->REORDER.CFG_Q_AGE_LIMIT.CFG_Q_AGE_LIMIT =\
+ LIBERO_SETTING_CFG_Q_AGE_LIMIT;
+ DDRCFG->REORDER.CFG_RO_CLOSED_PAGE_POLICY.CFG_RO_CLOSED_PAGE_POLICY =\
+ LIBERO_SETTING_CFG_RO_CLOSED_PAGE_POLICY;
+ DDRCFG->REORDER.CFG_REORDER_RW_ONLY.CFG_REORDER_RW_ONLY =\
+ LIBERO_SETTING_CFG_REORDER_RW_ONLY;
+ DDRCFG->REORDER.CFG_RO_PRIORITY_EN.CFG_RO_PRIORITY_EN =\
+ LIBERO_SETTING_CFG_RO_PRIORITY_EN;
+ DDRCFG->RMW.CFG_DM_EN.CFG_DM_EN = LIBERO_SETTING_CFG_DM_EN;
+ DDRCFG->RMW.CFG_RMW_EN.CFG_RMW_EN = LIBERO_SETTING_CFG_RMW_EN;
+ DDRCFG->ECC.CFG_ECC_CORRECTION_EN.CFG_ECC_CORRECTION_EN =\
+ LIBERO_SETTING_CFG_ECC_CORRECTION_EN;
+ DDRCFG->ECC.CFG_ECC_BYPASS.CFG_ECC_BYPASS = LIBERO_SETTING_CFG_ECC_BYPASS;
+ DDRCFG->ECC.INIT_WRITE_DATA_1B_ECC_ERROR_GEN.INIT_WRITE_DATA_1B_ECC_ERROR_GEN =\
+ LIBERO_SETTING_INIT_WRITE_DATA_1B_ECC_ERROR_GEN;
+ DDRCFG->ECC.INIT_WRITE_DATA_2B_ECC_ERROR_GEN.INIT_WRITE_DATA_2B_ECC_ERROR_GEN =\
+ LIBERO_SETTING_INIT_WRITE_DATA_2B_ECC_ERROR_GEN;
+ DDRCFG->ECC.CFG_ECC_1BIT_INT_THRESH.CFG_ECC_1BIT_INT_THRESH =\
+ LIBERO_SETTING_CFG_ECC_1BIT_INT_THRESH;
+ DDRCFG->READ_CAPT.INIT_READ_CAPTURE_ADDR.INIT_READ_CAPTURE_ADDR =\
+ LIBERO_SETTING_INIT_READ_CAPTURE_ADDR;
+ DDRCFG->MTA.CFG_ERROR_GROUP_SEL.CFG_ERROR_GROUP_SEL =\
+ LIBERO_SETTING_CFG_ERROR_GROUP_SEL;
+ DDRCFG->MTA.CFG_DATA_SEL.CFG_DATA_SEL = LIBERO_SETTING_CFG_DATA_SEL;
+ DDRCFG->MTA.CFG_TRIG_MODE.CFG_TRIG_MODE = LIBERO_SETTING_CFG_TRIG_MODE;
+ DDRCFG->MTA.CFG_POST_TRIG_CYCS.CFG_POST_TRIG_CYCS =\
+ LIBERO_SETTING_CFG_POST_TRIG_CYCS;
+ DDRCFG->MTA.CFG_TRIG_MASK.CFG_TRIG_MASK = LIBERO_SETTING_CFG_TRIG_MASK;
+ DDRCFG->MTA.CFG_EN_MASK.CFG_EN_MASK = LIBERO_SETTING_CFG_EN_MASK;
+ DDRCFG->MTA.MTC_ACQ_ADDR.MTC_ACQ_ADDR = LIBERO_SETTING_MTC_ACQ_ADDR;
+ DDRCFG->MTA.CFG_TRIG_MT_ADDR_0.CFG_TRIG_MT_ADDR_0 =\
+ LIBERO_SETTING_CFG_TRIG_MT_ADDR_0;
+ DDRCFG->MTA.CFG_TRIG_MT_ADDR_1.CFG_TRIG_MT_ADDR_1 =\
+ LIBERO_SETTING_CFG_TRIG_MT_ADDR_1;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_0.CFG_TRIG_ERR_MASK_0 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_0;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_1.CFG_TRIG_ERR_MASK_1 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_1;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_2.CFG_TRIG_ERR_MASK_2 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_2;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_3.CFG_TRIG_ERR_MASK_3 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_3;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_4.CFG_TRIG_ERR_MASK_4 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_4;
+ DDRCFG->MTA.MTC_ACQ_WR_DATA_0.MTC_ACQ_WR_DATA_0 =\
+ LIBERO_SETTING_MTC_ACQ_WR_DATA_0;
+ DDRCFG->MTA.MTC_ACQ_WR_DATA_1.MTC_ACQ_WR_DATA_1 =\
+ LIBERO_SETTING_MTC_ACQ_WR_DATA_1;
+ DDRCFG->MTA.MTC_ACQ_WR_DATA_2.MTC_ACQ_WR_DATA_2 =\
+ LIBERO_SETTING_MTC_ACQ_WR_DATA_2;
+ DDRCFG->MTA.CFG_PRE_TRIG_CYCS.CFG_PRE_TRIG_CYCS =\
+ LIBERO_SETTING_CFG_PRE_TRIG_CYCS;
+ DDRCFG->MTA.CFG_DATA_SEL_FIRST_ERROR.CFG_DATA_SEL_FIRST_ERROR =\
+ LIBERO_SETTING_CFG_DATA_SEL_FIRST_ERROR;
+ DDRCFG->DYN_WIDTH_ADJ.CFG_DQ_WIDTH.CFG_DQ_WIDTH =\
+ LIBERO_SETTING_CFG_DQ_WIDTH;
+ DDRCFG->DYN_WIDTH_ADJ.CFG_ACTIVE_DQ_SEL.CFG_ACTIVE_DQ_SEL =\
+ LIBERO_SETTING_CFG_ACTIVE_DQ_SEL;
+ DDRCFG->CA_PAR_ERR.INIT_CA_PARITY_ERROR_GEN_REQ.INIT_CA_PARITY_ERROR_GEN_REQ =\
+ LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_REQ;
+ DDRCFG->CA_PAR_ERR.INIT_CA_PARITY_ERROR_GEN_CMD.INIT_CA_PARITY_ERROR_GEN_CMD =\
+ LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_CMD;
+ DDRCFG->DFI.CFG_DFI_T_RDDATA_EN.CFG_DFI_T_RDDATA_EN =\
+ LIBERO_SETTING_CFG_DFI_T_RDDATA_EN;
+ DDRCFG->DFI.CFG_DFI_T_PHY_RDLAT.CFG_DFI_T_PHY_RDLAT =\
+ LIBERO_SETTING_CFG_DFI_T_PHY_RDLAT;
+ DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT =\
+ LIBERO_SETTING_CFG_DFI_T_PHY_WRLAT;
+ DDRCFG->DFI.CFG_DFI_PHYUPD_EN.CFG_DFI_PHYUPD_EN =\
+ LIBERO_SETTING_CFG_DFI_PHYUPD_EN;
+ DDRCFG->DFI.INIT_DFI_LP_DATA_REQ.INIT_DFI_LP_DATA_REQ =\
+ LIBERO_SETTING_INIT_DFI_LP_DATA_REQ;
+ DDRCFG->DFI.INIT_DFI_LP_CTRL_REQ.INIT_DFI_LP_CTRL_REQ =\
+ LIBERO_SETTING_INIT_DFI_LP_CTRL_REQ;
+ DDRCFG->DFI.INIT_DFI_LP_WAKEUP.INIT_DFI_LP_WAKEUP =\
+ LIBERO_SETTING_INIT_DFI_LP_WAKEUP;
+ DDRCFG->DFI.INIT_DFI_DRAM_CLK_DISABLE.INIT_DFI_DRAM_CLK_DISABLE =\
+ LIBERO_SETTING_INIT_DFI_DRAM_CLK_DISABLE;
+ DDRCFG->DFI.CFG_DFI_DATA_BYTE_DISABLE.CFG_DFI_DATA_BYTE_DISABLE =\
+ LIBERO_SETTING_CFG_DFI_DATA_BYTE_DISABLE;
+ DDRCFG->DFI.CFG_DFI_LVL_SEL.CFG_DFI_LVL_SEL =\
+ LIBERO_SETTING_CFG_DFI_LVL_SEL;
+ DDRCFG->DFI.CFG_DFI_LVL_PERIODIC.CFG_DFI_LVL_PERIODIC =\
+ LIBERO_SETTING_CFG_DFI_LVL_PERIODIC;
+ DDRCFG->DFI.CFG_DFI_LVL_PATTERN.CFG_DFI_LVL_PATTERN =\
+ LIBERO_SETTING_CFG_DFI_LVL_PATTERN;
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START =\
+ LIBERO_SETTING_PHY_DFI_INIT_START;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI1_0.CFG_AXI_START_ADDRESS_AXI1_0 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_0;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI1_1.CFG_AXI_START_ADDRESS_AXI1_1 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_1;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI2_0.CFG_AXI_START_ADDRESS_AXI2_0 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_0;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI2_1.CFG_AXI_START_ADDRESS_AXI2_1 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_1;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI1_0.CFG_AXI_END_ADDRESS_AXI1_0 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_0;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI1_1.CFG_AXI_END_ADDRESS_AXI1_1 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_1;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI2_0.CFG_AXI_END_ADDRESS_AXI2_0 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI2_1.CFG_AXI_END_ADDRESS_AXI2_1 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI1_0.CFG_MEM_START_ADDRESS_AXI1_0 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_0;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI1_1.CFG_MEM_START_ADDRESS_AXI1_1 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_1;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI2_0.CFG_MEM_START_ADDRESS_AXI2_0 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_0;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI2_1.CFG_MEM_START_ADDRESS_AXI2_1 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_1;
+ DDRCFG->AXI_IF.CFG_ENABLE_BUS_HOLD_AXI1.CFG_ENABLE_BUS_HOLD_AXI1 =\
+ LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI1;
+ DDRCFG->AXI_IF.CFG_ENABLE_BUS_HOLD_AXI2.CFG_ENABLE_BUS_HOLD_AXI2 =\
+ LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI2;
+ DDRCFG->AXI_IF.CFG_AXI_AUTO_PCH.CFG_AXI_AUTO_PCH =\
+ LIBERO_SETTING_CFG_AXI_AUTO_PCH;
+ DDRCFG->csr_custom.PHY_RESET_CONTROL.PHY_RESET_CONTROL =\
+ LIBERO_SETTING_PHY_RESET_CONTROL;
+ DDRCFG->csr_custom.PHY_RESET_CONTROL.PHY_RESET_CONTROL =\
+ (LIBERO_SETTING_PHY_RESET_CONTROL & ~0x8000UL);
+ DDRCFG->csr_custom.PHY_PC_RANK.PHY_PC_RANK = LIBERO_SETTING_PHY_PC_RANK;
+ DDRCFG->csr_custom.PHY_RANKS_TO_TRAIN.PHY_RANKS_TO_TRAIN =\
+ LIBERO_SETTING_PHY_RANKS_TO_TRAIN;
+ DDRCFG->csr_custom.PHY_WRITE_REQUEST.PHY_WRITE_REQUEST =\
+ LIBERO_SETTING_PHY_WRITE_REQUEST;
+ DDRCFG->csr_custom.PHY_READ_REQUEST.PHY_READ_REQUEST =\
+ LIBERO_SETTING_PHY_READ_REQUEST;
+ DDRCFG->csr_custom.PHY_WRITE_LEVEL_DELAY.PHY_WRITE_LEVEL_DELAY =\
+ LIBERO_SETTING_PHY_WRITE_LEVEL_DELAY;
+ DDRCFG->csr_custom.PHY_GATE_TRAIN_DELAY.PHY_GATE_TRAIN_DELAY =\
+ LIBERO_SETTING_PHY_GATE_TRAIN_DELAY;
+ DDRCFG->csr_custom.PHY_EYE_TRAIN_DELAY.PHY_EYE_TRAIN_DELAY =\
+ LIBERO_SETTING_PHY_EYE_TRAIN_DELAY;
+ DDRCFG->csr_custom.PHY_EYE_PAT.PHY_EYE_PAT = LIBERO_SETTING_PHY_EYE_PAT;
+ DDRCFG->csr_custom.PHY_START_RECAL.PHY_START_RECAL =\
+ LIBERO_SETTING_PHY_START_RECAL;
+ DDRCFG->csr_custom.PHY_CLR_DFI_LVL_PERIODIC.PHY_CLR_DFI_LVL_PERIODIC =\
+ LIBERO_SETTING_PHY_CLR_DFI_LVL_PERIODIC;
+ DDRCFG->csr_custom.PHY_TRAIN_STEP_ENABLE.PHY_TRAIN_STEP_ENABLE =\
+ LIBERO_SETTING_PHY_TRAIN_STEP_ENABLE;
+ DDRCFG->csr_custom.PHY_LPDDR_DQ_CAL_PAT.PHY_LPDDR_DQ_CAL_PAT =\
+ LIBERO_SETTING_PHY_LPDDR_DQ_CAL_PAT;
+ DDRCFG->csr_custom.PHY_INDPNDT_TRAINING.PHY_INDPNDT_TRAINING =\
+ LIBERO_SETTING_PHY_INDPNDT_TRAINING;
+ DDRCFG->csr_custom.PHY_ENCODED_QUAD_CS.PHY_ENCODED_QUAD_CS =\
+ LIBERO_SETTING_PHY_ENCODED_QUAD_CS;
+ DDRCFG->csr_custom.PHY_HALF_CLK_DLY_ENABLE.PHY_HALF_CLK_DLY_ENABLE =\
+ LIBERO_SETTING_PHY_HALF_CLK_DLY_ENABLE;
+
+}
+
+
+/**
+ * setup_ddr_segments(void)
+ * setup segment registers- translated DDR address as user requires
+ */
+void setup_ddr_segments(SEG_SETUP option)
+{
+ if(option == DEFAULT_SEG_SETUP)
+ {
+ SEG[0].u[0].raw = (INIT_SETTING_SEG0_0 & 0x7FFFUL);
+ SEG[0].u[1].raw = (INIT_SETTING_SEG0_1 & 0x7FFFUL);
+ SEG[1].u[2].raw = (INIT_SETTING_SEG1_2 & 0x7FFFUL);
+ SEG[1].u[3].raw = (INIT_SETTING_SEG1_3 & 0x7FFFUL);
+ SEG[1].u[4].raw = (INIT_SETTING_SEG1_4 & 0x7FFFUL);
+ SEG[1].u[5].raw = (INIT_SETTING_SEG1_5 & 0x7FFFUL);
+ }
+ else
+ {
+ SEG[0].u[0].raw = (LIBERO_SETTING_SEG0_0 & 0x7FFFUL);
+ SEG[0].u[1].raw = (LIBERO_SETTING_SEG0_1 & 0x7FFFUL);
+ SEG[1].u[2].raw = (LIBERO_SETTING_SEG1_2 & 0x7FFFUL);
+ SEG[1].u[3].raw = (LIBERO_SETTING_SEG1_3 & 0x7FFFUL);
+ SEG[1].u[4].raw = (LIBERO_SETTING_SEG1_4 & 0x7FFFUL);
+ SEG[1].u[5].raw = (LIBERO_SETTING_SEG1_5 & 0x7FFFUL);
+ }
+ /*
+ * disable ddr blocker
+ * Is cleared at reset. When written to '1' disables the blocker function
+ * allowing the L2 cache controller to access the DDRC. Once written to '1'
+ * the register cannot be written to 0, only an MSS reset will clear the
+ * register
+ */
+ SEG[0].u[7].raw = 0x01U;
+}
+
+/**
+ * use_software_bclk_sclk_training()
+ * @param ddr_type
+ * @return returns 1U if required, otherwise 0U
+ */
+static uint8_t use_software_bclk_sclk_training(DDR_TYPE ddr_type)
+{
+ uint8_t result = 0U;
+ switch (ddr_type)
+ {
+ default:
+ case DDR_OFF_MODE:
+ break;
+ case DDR3L:
+ result = 1U;
+ break;
+ case DDR3:
+ result = 1U;
+ break;
+ case DDR4:
+ result = 1U;
+ break;
+ case LPDDR3:
+ result = 1U;
+ break;
+ case LPDDR4:
+ result = 1U;
+ break;
+ }
+ return(result);
+}
+
+/**
+ * config_ddr_io_pull_up_downs_rpc_bits()
+ *
+ * This function overrides the RPC bits related to weak pull up and
+ * weak pull downs. It also sets the override bit if the I/O is disabled.
+ * The settings come fro m Libero
+ *
+ * Note: If LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9 is not present, indicates older
+ * Libero core (pre 2.0.109)
+ * Post 2.0.109 version of Libero MSS core, weak pull up and pull down
+ * settings come from Libero, along with setting unused MSS DDR I/O to
+ * override.
+ *
+ */
+static void config_ddr_io_pull_up_downs_rpc_bits(DDR_TYPE ddr_type)
+{
+ if(ddr_type == LPDDR4) /* we will add other variants here once verified */
+ {
+#ifdef LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9
+ /* set over-rides (associated bit set to 1 if I/O not being used */
+ CFG_DDR_SGMII_PHY->ovrt9.ovrt9 = LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9;
+ CFG_DDR_SGMII_PHY->ovrt10.ovrt10 = LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10;
+ CFG_DDR_SGMII_PHY->ovrt11.ovrt11 = LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11;
+ CFG_DDR_SGMII_PHY->ovrt12.ovrt12 = LIBERO_SETTING_RPC_EN_DATA0_OVRT12;
+ CFG_DDR_SGMII_PHY->ovrt13.ovrt13 = LIBERO_SETTING_RPC_EN_DATA1_OVRT13;
+ CFG_DDR_SGMII_PHY->ovrt14.ovrt14 = LIBERO_SETTING_RPC_EN_DATA2_OVRT14;
+ CFG_DDR_SGMII_PHY->ovrt15.ovrt15 = LIBERO_SETTING_RPC_EN_DATA3_OVRT15;
+ CFG_DDR_SGMII_PHY->ovrt16.ovrt16 = LIBERO_SETTING_RPC_EN_ECC_OVRT16;
+ /* set the required wpu state- note: associated I/O bit 1=> off, 0=> on */
+ CFG_DDR_SGMII_PHY->rpc235.rpc235 = LIBERO_SETTING_RPC235_WPD_ADD_CMD0;
+ CFG_DDR_SGMII_PHY->rpc236.rpc236 = LIBERO_SETTING_RPC236_WPD_ADD_CMD1;
+ CFG_DDR_SGMII_PHY->rpc237.rpc237 = LIBERO_SETTING_RPC237_WPD_ADD_CMD2;
+ CFG_DDR_SGMII_PHY->rpc238.rpc238 = LIBERO_SETTING_RPC238_WPD_DATA0;
+ CFG_DDR_SGMII_PHY->rpc239.rpc239 = LIBERO_SETTING_RPC239_WPD_DATA1;
+ CFG_DDR_SGMII_PHY->rpc240.rpc240 = LIBERO_SETTING_RPC240_WPD_DATA2;
+ CFG_DDR_SGMII_PHY->rpc241.rpc241 = LIBERO_SETTING_RPC241_WPD_DATA3;
+ CFG_DDR_SGMII_PHY->rpc242.rpc242 = LIBERO_SETTING_RPC242_WPD_ECC;
+ /* set the required wpd state- note: associated I/O bit 1=> off, 0=> on */
+ CFG_DDR_SGMII_PHY->rpc243.rpc243 = LIBERO_SETTING_RPC243_WPU_ADD_CMD0;
+ CFG_DDR_SGMII_PHY->rpc244.rpc244 = LIBERO_SETTING_RPC244_WPU_ADD_CMD1;
+ CFG_DDR_SGMII_PHY->rpc245.rpc245 = LIBERO_SETTING_RPC245_WPU_ADD_CMD2;
+ CFG_DDR_SGMII_PHY->rpc246.rpc246 = LIBERO_SETTING_RPC246_WPU_DATA0;
+ CFG_DDR_SGMII_PHY->rpc247.rpc247 = LIBERO_SETTING_RPC247_WPU_DATA1;
+ CFG_DDR_SGMII_PHY->rpc248.rpc248 = LIBERO_SETTING_RPC248_WPU_DATA2;
+ CFG_DDR_SGMII_PHY->rpc249.rpc249 = LIBERO_SETTING_RPC249_WPU_DATA3;
+ CFG_DDR_SGMII_PHY->rpc250.rpc250 = LIBERO_SETTING_RPC250_WPU_ECC;
+#endif
+ }
+}
+
+
+/**
+ * get the best sweep value
+ * @param good_index
+ * @return
+ */
+#ifdef SWEEP_ENABLED
+static uint8_t get_best_sweep(sweep_index *good_index)
+{
+#ifdef EXTRACT_SWEEP_RESULT
+ uint8_t cmd_index;
+ uint8_t bclk_sclk_index;
+ uint8_t dpc_vgen_index;
+ uint8_t dpc_vgen_h_index;
+ uint8_t dpc_vgen_vs_index;
+ uint8_t good_in_row;
+
+ for (dpc_vgen_vs_index=0U; dpc_vgen_vs_index < MAX_NUMBER_DPC_VS_GEN_SWEEPS; dpc_vgen_vs_index++)
+ {
+ for (dpc_vgen_h_index=0U; dpc_vgen_h_index < MAX_NUMBER_DPC_H_GEN_SWEEPS; dpc_vgen_h_index++)
+ {
+ for (dpc_vgen_index=0U; dpc_vgen_index < MAX_NUMBER_DPC_V_GEN_SWEEPS; dpc_vgen_index++)
+ {
+ for (bclk_sclk_index=0U; bclk_sclk_index < MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS; bclk_sclk_index++)
+ {
+ good_in_row = 0U;
+ for (cmd_index=0U; cmd_index < MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS; cmd_index++)
+ {
+ if (sweep_results[dpc_vgen_vs_index][dpc_vgen_h_index][dpc_vgen_index][bclk_sclk_index][cmd_index]\
+ == CALIBRATION_PASSED)
+ {
+ good_in_row++;
+ /*
+ * look for 3 in a row,in x and y direction and pick the
+ * middle one
+ * */
+ if((good_in_row > 2U)&&(bclk_sclk_index>1)&&(bclk_sclk_indexdpc_vgen_vs_index = dpc_vgen_vs_index;
+ good_index->dpc_vgen_h_index = dpc_vgen_h_index;
+ good_index->bclk_sclk_index = bclk_sclk_index;
+ good_index->dpc_vgen_index = dpc_vgen_index;
+ good_index->cmd_index = cmd_index - 1U;
+ return(0U);
+ }
+ }
+ }
+ else
+ {
+ good_in_row = 0U;
+ }
+ }
+ }
+ }
+ }
+ }
+ return(1U);
+#else /* EXTRACT_SWEEP_RESULT */
+ good_index->dpc_vgen_vs_index = 0U;
+ good_index->dpc_vgen_h_index = 0U;
+ good_index->bclk_sclk_index = 0U;
+ good_index->dpc_vgen_index = 0U;
+ good_index->cmd_index = 0U;
+ return(0U);
+#endif
+}
+#endif /* SWEEP_ENABLED */
+
+
+#ifdef DDR_DIAGNOSTICS /* todo: add support for diagnostics below during board bring-up */
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_DDR_status() function is used to return status information to the
+ user.
+
+ TODO: Define number of request inputs
+
+ @param option
+ This option chooses status data we wish returned
+
+ @param return_data
+ Returned data here. This must be within a defined range.
+ todo:Detail on the sharing of data will be system dependent.
+ AMP/SMU detail to be finalized at time of writing
+
+ @return
+ Returns 0 on success.
+ TODO: Define error codes.
+
+ Example:
+ The call to MSS_DDR_status(DDR_TYPE, return_data) will return 0 if
+ successful and the DDR type in the first four bytes of the ret_mem area.
+ @code
+ MSS_DDR_status( DDR_TYPE, ret_mem );
+ @endcode
+ */
+uint8_t
+MSS_DDR_status
+(
+ uint8_t option, uint32_t *return_data
+)
+{
+ uint8_t error = 0U;
+
+ switch (option)
+ {
+ case USR_OPTION_tip_register_dump:
+ /* todo: WIP
+ * add commands here */
+ break;
+
+ default:
+
+ break;
+ }
+
+ return error;
+}
+
+
+/*-------------------------------------------------------------------------*//**
+ * MSS_DDR_user_commands commands from the user
+ *
+ * @param command
+ * User command
+ * @param extra_command_data
+ * extra data from user for particular command
+ * @param return_data
+ * data returned via supplied pointer
+ * @return
+ * status 0 => success
+ *
+ * Example:
+ The call to
+ MSS_DDR_user_commands(USR_CMD_INC_DELAY_LINE, 0x01 , return_data)
+ will return 0 id successful and the
+ DDR type in the first four bytes of the ret_mem area.
+ @code
+ MSS_DDR_user_commands(USR_CMD_INC_DELAY_LINE, 0x01 , return_data);
+ @endcode
+ */
+uint8_t
+MSS_DDR_user_commands
+(
+ uint8_t command, uint32_t *extra_command_data, uint32_t *return_data, \
+ uint32_t return_size
+)
+{
+ uint8_t error = 0U;
+ uint32_t *reg_address;
+
+ switch (command)
+ {
+ case USR_CMD_GET_DDR_STATUS:
+ break;
+ case USR_CMD_GET_MODE_SETTING:
+ break;
+ case USR_CMD_GET_W_CALIBRATION:
+ config_copy(return_data, &calib_data, sizeof(calib_data));
+ break;
+ case USR_CMD_GET_GREEN_ZONE:
+ /* READ DQ WINDOW MEASUREMENT */
+ /* READ DQS WINDOW MEASUREMENT */
+ /* READ VREF WINDOW MAX MEASUREMENT */
+
+ break;
+
+ case USR_CMD_GET_REG:
+ /*
+ * First check if address valid
+ */
+ config_copy(reg_address, extra_command_data, 4U);
+ reg_address = (uint32_t *)((uint32_t)reg_address &\
+ (uint32_t)(0xFFFFFFFCUL));
+ if ((reg_address >=\
+ &CFG_DDR_SGMII_PHY->SOFT_RESET_DDR_PHY.SOFT_RESET_DDR_PHY)\
+ && (reg_address < &CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT))
+ {
+ config_copy(return_data, reg_address, sizeof(uint32_t));
+ }
+ else
+ {
+ error = 1U;
+ }
+ break;
+
+ /*
+ * And set commands
+ */
+ case USR_CMD_SET_GREEN_ZONE_DQ:
+ /* READ DQ WINDOW MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & DQ delayline controls, to
+ * measure the maximum DQ offset before failure.
+ */
+ break;
+ case USR_CMD_SET_GREEN_ZONE_DQS:
+ /* READ DQS WINDOW MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & DQS delayline controls, to
+ * measure the maximum DQS offset before failure.
+ */
+ break;
+ case USR_CMD_SET_GREEN_ZONE_VREF_MAX:
+ /* READ VREF WINDOW MAX MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & VREF controller delayline
+ * controls, to measure the max VREF level.
+ */
+ break;
+ case USR_CMD_SET_GREEN_ZONE_VREF_MIN:
+ /* READ VREF WINDOW MIN MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & VREF controller delayline
+ * controls, to measure the minimum VREF level.
+ */
+ break;
+ case USR_CMD_SET_RETRAIN:
+ /* Incremental, In-System Retraining Procedures */
+ /*
+ * This procedure adjusts the read window to re-center clock and
+ * data.
+ * It should be triggered when the DLL code value passes a certain
+ * threshold, during a refresh cycle.
+ * Added here to allow the user to trigger.
+ */
+ break;
+ case USR_CMD_SET_REG:
+ break;
+
+ default:
+ error = 1U;
+ break;
+ }
+ return error;
+}
+#endif
+
+#ifdef DEBUG_DDR_INIT
+#ifdef DEBUG_DDR_DDRCFG
+void debug_read_ddrcfg(void)
+{
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->ADDR_MAP,\
+ (sizeof(DDRCFG->ADDR_MAP)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MC_BASE3,\
+ (sizeof(DDRCFG->MC_BASE3)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MC_BASE1,\
+ (sizeof(DDRCFG->MC_BASE1)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MC_BASE2,\
+ (sizeof(DDRCFG->MC_BASE2)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MPFE,\
+ (sizeof(DDRCFG->MPFE)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->REORDER,\
+ (sizeof(DDRCFG->REORDER)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->RMW,\
+ (sizeof(DDRCFG->RMW)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->ECC,\
+ (sizeof(DDRCFG->ECC)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->READ_CAPT,\
+ (sizeof(DDRCFG->READ_CAPT)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MTA,\
+ (sizeof(DDRCFG->MTA)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->DYN_WIDTH_ADJ,\
+ (sizeof(DDRCFG->DYN_WIDTH_ADJ)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->CA_PAR_ERR,\
+ (sizeof(DDRCFG->CA_PAR_ERR)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->DFI,\
+ (sizeof(DDRCFG->DFI)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->AXI_IF,\
+ (sizeof(DDRCFG->AXI_IF)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->csr_custom,\
+ (sizeof(DDRCFG->csr_custom)/4U));
+ return;
+}
+#endif
+#endif
+
+
+const uint8_t REFCLK_OFFSETS[][5U] = {
+ {LIBERO_SETTING_REFCLK_DDR3_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR3L_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR4_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_3},
+
+ {LIBERO_SETTING_REFCLK_DDR3_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR3L_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR4_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_3},
+};
+
+/**
+ * ddr_manual_addcmd_refclk_offset This function determines current
+ * sweep offset based on DDR type
+ * @param ddr_type
+ * @param refclk_sweep_index
+ * @return
+ */
+#ifdef MANUAL_ADDCMD_TRAINIG
+static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index)
+{
+ uint8_t refclk_offset;
+ uint8_t type_array_index;
+
+ type_array_index = (uint8_t)ddr_type;
+ if(LIBERO_SETTING_DDR_CLK == DDR_1333_MHZ)
+ {
+ type_array_index = type_array_index + (uint8_t)LPDDR4;
+ }
+
+ if (*refclk_sweep_index >= REFCLK_OFFSETS[type_array_index][0U])
+ {
+ *refclk_sweep_index = 0U;
+ }
+
+ refclk_offset = REFCLK_OFFSETS[type_array_index][*refclk_sweep_index + 1U];
+
+ *refclk_sweep_index = (*refclk_sweep_index + 1U);
+
+ return refclk_offset;
+}
+#endif
+
+
+#endif /* DDR_SUPPORT */
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr.h
new file mode 100644
index 00000000..da8cc8d9
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr.h
@@ -0,0 +1,1133 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief DDR related defines
+ *
+ */
+
+/*=========================================================================*//**
+ @page DDR setup and monitoring
+ ==============================================================================
+ @section intro_sec Introduction
+ ==============================================================================
+ The MPFS microcontroller subsystem (MSS) includes a number of hard core
+ components physically located in the north west corner of the MSS on the die.
+ This includes the DDR Phy.
+
+ ==============================================================================
+ @section Items located in the north west corner
+ ==============================================================================
+ - MSS PLL
+ - SGMII
+ - DDR phy
+ - MSSIO
+
+ ==============================================================================
+ @section Overview of DDR related hardware
+ ==============================================================================
+
+ Simplified IP diagram
+
+
+ +--+
+ +--++ +-----+ +---v--+ |o |
+ |H0 | |H1-H4+--------> AXI | |t |
+ ++--+ +-+---+ |switch<---+h |
+ | | | | |e |
+ | | +--+---+ |r |
+ +v------v-------+ | | |
+ |L2 cache | non-cache |m |
+ +------------+--+ | |a |
+ +---v----+ +---v---+ |s |
+ |seg 0 | | seg 1 | |t |
+ +----^---+ +---^---+ |e |
+ | | |r |
+ +-----------+------+----v---------v---+ |s |
+ |Training IP|MTC |DDR controller | +--+
+ +-----------+------+--------+---------+
+ |DFI
+ |
+ +---------v--------+
+ | DDR Phy |
+ +------------------+
+ | Bank 6 I/O |
+ +-------+----------+
+ |
+ +----------v---------------+
+ | +--+ +--+ +--+ +--+ +--+ |
+ | |D | |D | |R | | | | | |
+ | +--+ +--+ +--+ +--+ +--+ |
+ +--------------------------+
+
+
+ -----------
+ Hart0 E51
+ -----------
+ In most systems, the E51 will will setup and monitor the DDR
+
+ -----------
+ L2 Cache
+ -----------
+ Specific address range is used to access DDR via cache
+
+ -----------
+ AXI switch
+ -----------
+ DDR access via AXI switch for non-cached read/write
+
+ -----------
+ SEG regs
+ -----------
+ Used to map internal DDR address range to external fixed mapping.
+ Note: DDR address ranges are at 32 bit and 64 bits
+
+ -----------
+ DDR controller
+ -----------
+ Manages DDR, refresh rates etc
+
+ -----------
+ DDR Training IP
+ -----------
+ Used to carry out training using IP state machines
+ - BCLKSCLK_TIP_TRAINING .
+ - addcmd_TIP_TRAINING
+ - wrlvl_TIP_TRAINING
+ - rdgate_TIP_TRAINING
+ - dq_dqs_opt_TIP_TRAINING
+
+ -----------
+ DDR MTC - Memory test controller
+ -----------
+ Sends/receives test patterns to DDR. More efficient than using software.
+ Used during write calibration and in DDR test routines.
+
+ -----------
+ DFI
+ -----------
+ Industry standard interface between phy, DDRC
+
+ -----------
+ DDR phy
+ -----------
+ PolarFire-SoC DDR phy manges data paath between pins and DFI
+
+ ==============================================================================
+ @section Overview of DDR embedded software
+ ==============================================================================
+
+ -----------
+ Setup
+ -----------
+ - phy and IO
+ - DDRC
+
+ -----------
+ Use Training IP
+ -----------
+ - kick-off RTL training IP state machine
+ - Verify all training complete
+ - BCLKSCLK_TIP_TRAINING .
+ - addcmd_TIP_TRAINING
+ This is a coarse training that moves the DDRCLK with PLL phase
+ rotations in relation to the Address/Command bits to achieve the
+ desired offset on the FPGA side.
+ - wrlvl_TIP_TRAINING
+ - rdgate_TIP_TRAINING
+ - dq_dqs_opt_TIP_TRAINING
+
+ Test this reg to determine training status:
+ DDRCFG->DFI.STAT_DFI_TRAINING_COMPLETE.STAT_DFI_TRAINING_COMPLETE;
+
+ -----------
+ Write Calibration
+ -----------
+ The Memory Test Core plugged in to the front end of the DDR controller is used
+ to perform lane-based writes and read backs and increment write calibration
+ offset for each lane until data match occurs. The settings are recorded by the
+ driver and available to be read using by an API function call.
+
+ -----------
+ VREF Calibration (optional)
+ -----------
+ VREF (DDR4 + LPDDR4 only) Set Remote VREF via mode register writes (MRW).
+ In DDR4 and LPDDR4, VREF training may be done by writing to Mode Register 6 as
+ defined by the JEDEC spec and, for example, Micron's datasheet for its 4Gb
+ DDR4 RAM's:
+
+ MR6 register definition from DDR4 datasheet
+
+ | Mode Reg | Description |
+ | ------------- |:---------------------------------------------------:|
+ | 13,9,8 | DQ RX EQ must be 000 |
+ | 7 | Vref calib enable = => disables, 1 ==> enabled |
+ | 6 | Vref Calibration range 0 = Range 0, 1 - Range 2 |
+ | 5:0 | Vref Calibration value |
+
+ This step is not implemented in the current driver. It can be implemented in
+ the same way as write Calibration and will be added during board verification.
+
+ -----------
+ FPGA VREF (Local VREF training) (optional)
+ -----------
+ In addition to memory VREFDQ training, or remote training, it is possible to
+ train the VREFDQ on the FPGA device. WE refer to this training as local VREF
+ training.
+ Train FPGA VREF using the vrgen_h and vrgen_v registers
+ To manipulate the FPGA VREF value, firmware must write to the DPC_BITS
+ register, located at physical address 0x2000 7184.
+ CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_h;
+ CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_v;
+ Like memory VREFDQ training, FPGA VREFDQ training seeks to find an average/
+ optimal VREF value by sweeping across the full range and finding a left edge
+ and a right edge.
+ This step is not implemented in the current driver. It can be implemented in
+ the same way as write Calibration and will be added during board verification.
+
+ -----------
+ DQ Write Offset
+ -----------
+ (LPDDR4 only) ), there must be an offset at the input to the LPDDR4 memory
+ device between DQ and DQS. Unlike other flavors of DDR, which match DQ and DQS
+ at the SDRAM, for LPDDR4 this relationship must be trained, because it will
+ vary between 200ps and 600ps, which, depending on the data rate, could be as
+ much as one whole bit period.
+ This training is integrated with write calibration, because it, too, is done
+ on a per-lane basis. That is, each lane is trained separately by sweeping the
+ DQ output delay to find a valid range and of DQ output delays and center it.
+ DQ output delays are swept using the expert_dlycnt_move_reg0 register located
+ in the MSS DDR TIP.
+
+
+ -----------
+ Overview Flow diagram of Embedded software setup
+ -----------
+
+ +--------------------------------------------+
+ | Some Preconditions |
+ | DCE, CORE_UP, FLASH VALID, MSS_IO_EN |
+ | MSS PLL setup, Clks to MSS setup |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Check if in off mode, ret if so |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | set ddr mode and VS bits |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | soft reset I/O decoders |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Set RPC registers that need manual setup |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Soft reset IP- to load RPC ->SCB regs |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Calibrate I/O - as they are now setup |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Configure the DDR PLL - Using SCB writes |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Setup the SEG regs - NB May move this down|
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Set-up the DDRC - Using Libero values |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Reset training IP |
+ +--------------------+-----------------------+
+ |
+ +----------------- --v-----------------------+
+ | Rotate BCLK by programmed amount (degrees)|
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Set training parameters |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Assert traing reset |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Wait until traing complete |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Write calibrate |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | If LPDDR4, calibrate DQ |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Sanity check training |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Return 0 if all went OK |
+ +--------------------------------------------+
+
+ *//*=========================================================================*/
+
+
+#ifndef __MSS_DDRC_H_
+#define __MSS_DDRC_H_ 1
+
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_TYPE_
+{
+
+ DDR3 = 0x00, /*!< 0 DDR3 */
+ DDR3L = 0x01, /*!< 1 DDR3L */
+ DDR4 = 0x02, /*!< 2 DDR4 */
+ LPDDR3 = 0x03, /*!< 3 LPDDR3 */
+ LPDDR4 = 0x04, /*!< 4 LPDDR4 */
+ DDR_OFF_MODE = 0x07 /*!< 4 LPDDR4 */
+} DDR_TYPE;
+
+typedef enum DDR_MEMORY_ACCESS_
+{
+ DDR_NC_256MB,
+ DDR_NC_WCB_256MB,
+ DDR_NC_2GB,
+ DDR_NC_WCB_2GB,
+} DDR_MEMORY_ACCESS;
+
+/* this is a fixed value, currently only 5 supported in the TIP */
+#define MAX_POSSIBLE_TIP_TRAININGS 0x05U
+
+/* LIBERO_SETTING_TIP_CFG_PARAMS
+ * ADDCMD_OFFSET [0:3] RW value */
+#define ADDRESS_CMD_OFFSETT_MASK (0x7U<<0U)
+
+#define BCLK_SCLK_OFFSET_SHIFT (3U)
+#define BCLK_SCLK_OFFSET_MASK (0x7U<<3U)
+
+#define BCLK_DPC_VRGEN_V_SHIFT (12U)
+#define BCLK_DPC_VRGEN_V_MASK (0x3FU<<12U)
+
+#define BCLK_DPC_VRGEN_H_SHIFT (4U)
+#define BCLK_DPC_VRGEN_H_MASK (0xFU<<4U)
+
+#define BCLK_DPC_VRGEN_VS_SHIFT (0U)
+#define BCLK_DPC_VRGEN_VS_MASK (0xFU<<0U)
+
+
+/* masks and associated values used with DDRPHY_MODE register */
+#define DDRPHY_MODE_MASK 0x7U
+/* ECC */
+#define DDRPHY_MODE_ECC_MASK (0x1U<<3U)
+#define DDRPHY_MODE_ECC_ON (0x1U<<3U)
+/* Bus width */
+#define DDRPHY_MODE_BUS_WIDTH_4_LANE (0x1U<<5U)
+#define DDRPHY_MODE_BUS_WIDTH_MASK (0x7U<<5U)
+/* Number of ranks, 1 or 2 supported */
+#define DDRPHY_MODE_RANK_MASK (0x1U<<26U)
+#define DDRPHY_MODE_ONE_RANK (0x0U<<26U)
+#define DDRPHY_MODE_TWO_RANKS (0x1U<<26U)
+
+#define DMI_DBI_MASK (~(0x1U<<8U))
+
+/* Write latency min/max settings If write calibration fails
+ * For Libero setting, we iterate through these values looking for a
+ * Calibration pass */
+#define MIN_LATENCY 0UL
+#define MAX_LATENCY 3UL //ML fixme- agree this value with Alister
+
+#define MTC_TIMEOUT_ERROR 0x02U
+
+#define DDR_MODE_REG_VREF 0xCU
+
+#define CALIBRATION_PASSED 0xFF
+#define CALIBRATION_FAILED 0xFE
+#define CALIBRATION_SUCCESS 0xFC
+
+/*
+ * Some settings that are only used during testing in new DDR setup
+ */
+/* #define LANE_ALIGNMENT_RESET_REQUIRED leave commented, not required */
+#define ABNORMAL_RETRAIN_CA_DECREASE_COUNT 2U
+#define ABNORMAL_RETRAIN_CA_DLY_DECREASE_COUNT 2U
+#define DQ_DQS_NUM_TAPS 5U
+
+#if !defined (LIBERO_SETTING_MAX_MANUAL_REF_CLK_PHASE_OFFSET)
+#define LIBERO_SETTING_MAX_MANUAL_REF_CLK_PHASE_OFFSET 4U
+#endif
+#if !defined (LIBERO_SETTING_MIN_MANUAL_REF_CLK_PHASE_OFFSET)
+#define LIBERO_SETTING_MIN_MANUAL_REF_CLK_PHASE_OFFSET 2U
+#endif
+#if !defined (LIBERO_SETTING_MANUAL_REF_CLK_PHASE_OFFSET)
+/* If skipping add/cmd training, this value is used */
+/* The value used may be trained. The value here should be determined */
+/* for the board design by performing a manual sweep. */
+#define LIBERO_SETTING_MANUAL_REF_CLK_PHASE_OFFSET 0x00000006UL
+ /* CA_BUS_RX_OFF_POST_TRAINING [0:1] RW value= 0x1 */
+#endif
+
+/*
+ * We currently need at least one retrain, otherwise driver can get stuck in
+ * sanity check state
+ */
+#if !defined (EN_RETRY_ON_FIRST_TRAIN_PASS)
+#define EN_RETRY_ON_FIRST_TRAIN_PASS 0
+#endif
+
+#if !defined (DDR_FULL_32BIT_NC_CHECK_EN)
+#define DDR_FULL_32BIT_NC_CHECK_EN 1
+#endif
+
+#if !defined (DDR_FULL_32BIT_CACHED_CHECK_EN)
+#define DDR_FULL_32BIT_CACHED_CHECK_EN 0
+#endif
+
+#if !defined (NO_PATTERN_IN_CACHE_READS)
+#define NO_PATTERN_IN_CACHE_READS 1
+#endif
+
+#if !defined (SIZE_OF_PATTERN_TEST)
+#define SIZE_OF_PATTERN_TEST 0x02000000UL
+#endif
+
+#if !defined (SIZE_OF_PATTERN_OFFSET)
+#define SIZE_OF_PATTERN_OFFSET 12U
+#endif
+
+#if !defined (DEFAULT_RPC_166_VALUE)
+#define DEFAULT_RPC_166_VALUE 2UL
+#endif
+
+/* set to 0 if you want to turn off tuning */
+#if !defined (TUNE_RPC_166_VALUE)
+#define TUNE_RPC_166_VALUE 1
+#endif
+
+#if !defined (MIN_RPC_166_VALUE)
+#define MIN_RPC_166_VALUE 2UL
+#endif
+
+#if !defined (MAX_RPC_166_VALUE)
+#define MAX_RPC_166_VALUE 4UL
+#endif
+
+#define NUM_RPC_166_VALUES (MAX_RPC_166_VALUE - MIN_RPC_166_VALUE)
+
+/* This is a fixed setting, will move into driver in next commit */
+#if !defined (SW_TRAING_BCLK_SCLK_OFFSET)
+#define SW_TRAING_BCLK_SCLK_OFFSET 0x00000000UL
+#endif
+/*
+ * 0x6DU => setting vref_ca to 40%
+ * This (0x6DU) is the default setting.
+ * Currently not being used, here for possible future use.
+ * */
+#if !defined (DDR_MODE_REG_VREF_VALUE)
+#define DDR_MODE_REG_VREF_VALUE 0x6DU
+#endif
+
+/* number of test writes to perform */
+#if !defined (SW_CFG_NUM_READS_WRITES)
+#define SW_CFG_NUM_READS_WRITES 0x20000U
+#endif
+/*
+ * what test patterns to write/read on start-up
+ * */
+#if !defined (SW_CONFIG_PATTERN)
+#define SW_CONFIG_PATTERN (PATTERN_INCREMENTAL|\
+ PATTERN_WALKING_ONE|\
+ PATTERN_WALKING_ZERO|\
+ PATTERN_RANDOM|\
+ PATTERN_0xCCCCCCCC|\
+ PATTERN_0x55555555)
+#endif
+
+/*
+ * Sweep offsets
+ * They currently are not coming from MSS Configurator (v12.7 and earlier)
+ * They may at some point
+ *
+ * Determined ( 5th Feb 2021 )
+ * DDR3@1066 = 3,2,1
+ * DDR4@1600 = 7,0,1
+ * LPDDR3@1066 = 7,0,1
+ * LPDDR4@1600 = 5,4,6,3
+ *
+ * DDR3@1333 = 1,7,0,2
+ * DDR4@1333 = 0,7,1
+ * LPDDR3@1333 = 7,0,6
+ * LPDDR4@1333 = 1,2,3
+ *
+ */
+#if !defined (VREF_TRAINING_MIN)
+#define VREF_TRAINING_MIN 5U
+#endif
+#if !defined (VREF_TRAINING_MAX)
+#define VREF_TRAINING_MAX 30U
+#endif
+#if !defined (CA_SWEEP_START)
+#define CA_SWEEP_START 0U
+#endif
+#if !defined (CA_SWEEP_END)
+#define CA_SWEEP_END 30U
+#endif
+#if !defined (CA_SWEEP_INCREMENT)
+#define CA_SWEEP_INCREMENT 5U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_NUM_OFFSETS 4U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_NUM_OFFSETS 4U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_NUM_OFFSETS 3U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_0 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_1 2U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_0 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_1 2U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_0 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_1 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_0 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_1 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_3 0U
+#endif
+//LPDDR4@1600 = 5,4,6,3 changed to 5,4,6,2 16th Feb Alister
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_0 5U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_1 4U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_2 6U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_3 3U
+#endif
+
+/*
+ * 1333 offset
+ */
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_0 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_1 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_2 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3 2U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_0 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_1 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_2 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_3 2U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_0 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_1 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_0 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_1 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_2 6U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_0 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_1 2U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_2 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_3 0U
+#endif
+
+/* Bit1 == 0 => 1600Mhz Bit1 == 1 => 1333Mhz */
+#if !defined (LIBERO_SETTING_DDR_CLK)
+#define LIBERO_SETTING_DDR_CLK 1600000000
+#endif
+
+#define DDR_1333_MHZ 1333333333
+#define DDR_1600_MHZ 1600000000
+
+#ifndef NOT_A_FULL_RETRAIN
+#define NOT_A_FULL_RETRAIN
+#endif
+
+#if !defined (RPC_OVERRIDE_166_LANE_FIFO)
+#define RPC_OVERRIDE_166_LANE_FIFO 0
+#endif
+
+#define ONE_GB_MTC 30U
+#define HALF_GB_MTC 29U
+#define ONE_MB_MTC 20U
+
+
+/*Cached access at 0x00_8000_0000 (-0x80+0x00) */
+#define INIT_SETTING_SEG0_0 0x00007F80UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7F80 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Cached access at 0x10_0000_000 */
+#define INIT_SETTING_SEG0_1 0x00007000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7000 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_2 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_3 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_4 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_5 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:6] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_6 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_7 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG1_0 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG1_1 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached access at 0x00_c000_0000 */
+#define INIT_SETTING_SEG1_2 0x00007F40UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7F40 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached access at 0x14_0000_0000 */
+#define INIT_SETTING_SEG1_3 0x00006C00UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x6C00 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached WCB access at 0x00_d000_0000 */
+#define INIT_SETTING_SEG1_4 0x00007F30UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7F30 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached WCB 0x18_0000_0000 */
+#define INIT_SETTING_SEG1_5 0x00006800UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x6800 */
+ /* RESERVED [15:6] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Trace - Trace not in use here so can be left as 0 */
+#define INIT_SETTING_SEG1_6 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG1_7 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+
+/***************************************************************************//**
+
+ */
+typedef enum MTC_PATTERN_
+{
+ MTC_COUNTING_PATTERN = 0x00, /*!< */
+ MTC_WALKING_ONE = 0x01, /*!< */
+ MTC_PSEUDO_RANDOM = 0x02, /*!< */
+ MTC_NO_REPEATING_PSEUDO_RANDOM = 0x03, /*!< */
+ MTC_ALT_ONES_ZEROS = 0x04, /*!< */
+ MTC_ALT_5_A = 0x05, /*!< */
+ MTC_USER = 0x06, /*!< */
+ MTC_PSEUDO_RANDOM_16BIT = 0x07, /*!< */
+ MTC_PSEUDO_RANDOM_8BIT = 0x08, /*!< */
+} MTC_PATTERN;
+
+
+
+typedef enum MTC_ADD_PATTERN_
+{
+ MTC_ADD_SEQUENTIAL = 0x00, /*!< */
+ MTC_ADD_RANDOM = 0x01, /*!< */
+} MTC_ADD_PATTERN;
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_SM_STATES_
+{
+
+ DDR_STATE_INIT = 0x00, /*!< 0 DDR_STATE_INIT*/
+ DDR_STATE_MONITOR = 0x01, /*!< 1 DDR_STATE_MONITOR */
+ DDR_STATE_TRAINING = 0x02, /*!< 2 DDR_STATE_TRAINING */
+ DDR_STATE_VERIFY = 0x03, /*!< 3 DDR_STATE_VERIFY */
+} DDR_SM_STATES;
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_SS_COMMAND_
+{
+
+ DDR_SS__INIT = 0x00, /*!< 0 DDR_SS__INIT */
+ DDR_SS_MONITOR = 0x01, /*!< 1 DDR_SS_MONITOR */
+} DDR_SS_COMMAND;
+
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_SS_STATUS_
+{
+
+ DDR_SETUP_DONE = 0x01, /*!< 0 DDR_SETUP_DONE */
+ DDR_SETUP_FAIL = 0x02, /*!< 1 DDR_SETUP_FAIL */
+ DDR_SETUP_SUCCESS = 0x04, /*!< 2 DDR_SETUP_SUCCESS */
+ DDR_SETUP_OFF_MODE = 0x08, /*!< 4 DDR_SETUP_OFF_MODE */
+} DDR_SS_STATUS;
+
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_TRAINING_SM_
+{
+
+ DDR_TRAINING_INIT, /*!< DDR_TRAINING_INIT */
+ DDR_TRAINING_FAIL,
+ DDR_CHECK_TRAINING_SWEEP,
+ DDR_TRAINING_SWEEP,
+ DDR_TRAINING_CHECK_FOR_OFFMODE, /*!< DDR_TRAINING_OFFMODE */
+ DDR_TRAINING_SET_MODE_VS_BITS,
+ DDR_TRAINING_FLASH_REGS,
+ DDR_TRAINING_CORRECT_RPC,
+ DDR_TRAINING_SOFT_RESET,
+ DDR_TRAINING_CALIBRATE_IO,
+ DDR_TRAINING_CONFIG_PLL,
+ DDR_TRAINING_SETUP_SEGS,
+ DDR_TRAINING_VERIFY_PLL_LOCK,
+ DDR_TRAINING_SETUP_DDRC,
+ DDR_TRAINING_RESET,
+ DDR_TRAINING_ROTATE_CLK,
+ DDR_TRAINING_SET_TRAINING_PARAMETERS,
+ DDR_TRAINING_IP_SM_BCLKSCLK_SW,
+ DDR_MANUAL_ADDCMD_TRAINING_SW,
+ DDR_TRAINING_IP_SM_START,
+ DDR_TRAINING_IP_SM_START_CHECK,
+ DDR_TRAINING_IP_SM_BCLKSCLK,
+ DDR_TRAINING_IP_SM_ADDCMD,
+ DDR_TRAINING_IP_SM_WRLVL,
+ DDR_TRAINING_IP_SM_RDGATE,
+ DDR_TRAINING_IP_SM_DQ_DQS,
+ DDR_TRAINING_IP_SM_VERIFY,
+ DDR_TRAINING_SET_FINAL_MODE,
+ DDR_TRAINING_WRITE_CALIBRATION,
+ DDR_TRAINING_WRITE_CALIBRATION_RETRY, /*!< Retry on calibration fail */
+ DDR_SWEEP_CHECK,
+ DDR_SANITY_CHECKS,
+ DDR_FULL_MTC_CHECK,
+ DDR_FULL_32BIT_NC_CHECK,
+ DDR_FULL_32BIT_CACHE_CHECK,
+ DDR_LOAD_PATTERN_TO_CACHE,
+ DDR_VERIFY_PATTERN_IN_CACHE,
+ DDR_FULL_32BIT_WRC_CHECK,
+ DDR_FULL_64BIT_NC_CHECK,
+ DDR_FULL_64BIT_CACHE_CHECK,
+ DDR_FULL_64BIT_WRC_CHECK,
+ DDR_TRAINING_VREFDQ_CALIB,
+ DDR_TRAINING_FPGA_VREFDQ_CALIB,
+ DDR_TRAINING_FINISH_CHECK,
+ DDR_TRAINING_FINISHED,
+ DDR_TRAINING_FAIL_SM2_VERIFY,
+ DDR_TRAINING_FAIL_SM_VERIFY,
+ DDR_TRAINING_FAIL_SM_DQ_DQS,
+ DDR_TRAINING_FAIL_SM_RDGATE,
+ DDR_TRAINING_FAIL_SM_WRLVL,
+ DDR_TRAINING_FAIL_SM_ADDCMD,
+ DDR_TRAINING_FAIL_SM_BCLKSCLK,
+ DDR_TRAINING_FAIL_BCLKSCLK_SW,
+ DDR_TRAINING_FAIL_FULL_32BIT_NC_CHECK,
+ DDR_TRAINING_FAIL_32BIT_CACHE_CHECK,
+ DDR_TRAINING_FAIL_MIN_LATENCY,
+ DDR_TRAINING_FAIL_START_CHECK,
+ DDR_TRAINING_FAIL_PLL_LOCK,
+ DDR_TRAINING_FAIL_DDR_SANITY_CHECKS,
+ DDR_SWEEP_AGAIN
+} DDR_TRAINING_SM;
+
+
+/***************************************************************************//**
+
+ */
+typedef enum {
+
+ USR_CMD_GET_DDR_STATUS = 0x00, //!< USR_CMD_GET_DDR_STATUS
+ USR_CMD_GET_MODE_SETTING = 0x01, //!< USR_CMD_GET_MODE_SETTING
+ USR_CMD_GET_W_CALIBRATION = 0x02, //!< USR_CMD_GET_W_CALIBRATION
+ USR_CMD_GET_GREEN_ZONE = 0x03, //!< USR_CMD_GET_GREEN_ZONE
+ USR_CMD_GET_REG = 0x04 //!< USR_CMD_GET_REG
+} DDR_USER_GET_COMMANDS_t;
+
+/***************************************************************************//**
+
+ */
+typedef enum {
+ USR_CMD_SET_GREEN_ZONE_DQ = 0x80, //!< USR_CMD_SET_GREEN_ZONE_DQ
+ USR_CMD_SET_GREEN_ZONE_DQS = 0x81, //!< USR_CMD_SET_GREEN_ZONE_DQS
+ USR_CMD_SET_GREEN_ZONE_VREF_MAX = 0x82, //!< USR_CMD_SET_GREEN_ZONE_VREF
+ USR_CMD_SET_GREEN_ZONE_VREF_MIN = 0x83, //!< USR_CMD_SET_GREEN_ZONE_VREF
+ USR_CMD_SET_RETRAIN = 0x84, //!< USR_CMD_SET_RETRAIN
+ USR_CMD_SET_REG = 0x85 //!< USR_CMD_SET_REG
+} DDR_USER_SET_COMMANDS_t;
+
+/***************************************************************************//**
+
+ */
+typedef enum SWEEP_STATES_{
+ INIT_SWEEP, //!< start the sweep
+ ADDR_CMD_OFFSET_SWEEP, //!< sweep address command
+ BCLK_SCLK_OFFSET_SWEEP, //!< sweep bclk sclk
+ DPC_VRGEN_V_SWEEP, //!< sweep vgen_v
+ DPC_VRGEN_H_SWEEP, //!< sweep vgen_h
+ DPC_VRGEN_VS_SWEEP, //!< VS sweep
+ FINISHED_SWEEP, //!< finished sweep
+} SWEEP_STATES;
+
+/***************************************************************************//**
+
+ */
+typedef enum {
+ USR_OPTION_tip_register_dump = 0x00 //!< USR_OPTION_tip_register_dump
+} USR_STATUS_OPTION_t;
+
+
+#define MAX_LANES 5
+
+/***************************************************************************//**
+
+ */
+typedef enum SEG_SETUP_{
+ DEFAULT_SEG_SETUP = 0x00,
+ LIBERO_SEG_SETUP
+} SEG_SETUP;
+
+
+
+/***************************************************************************//**
+
+ */
+typedef struct mss_ddr_fpga_vref_{
+ uint32_t status_lower;
+ uint32_t status_upper;
+ uint32_t lower;
+ uint32_t upper;
+ uint32_t vref_result;
+} mss_ddr_vref;
+
+/**
+ * \brief dll sgmii SCB regs
+ */
+typedef struct IOSCB_BANKCONT_DDR_ {
+ /* bit0 - This when asserted resets all the non-volatile register bits e.g. RW-P bits, the bit self clears i.e. is similar to a W1P bit */
+ /* bit1 - This when asserted resets all the register bits apart from the non-volatile registers, the bit self clears. i.e. is similar to a W1P bit */
+ __IO uint32_t soft_reset; /* bit8 - This asserts the functional reset of the block. It is asserted at power up. When written is stays asserted until written to 0. */
+
+ __IO uint32_t dpc_bits; /* bit 3:0: dpc_vs bank voltage select for pvt calibration */
+ /* : dpc_vrgen_h */
+ /* : dpc_vrgen_en_h */
+ /* : dpc_move_en_h */
+ /* : dpc_vrgen_v */
+ /* : dpc_vrgen_en_v */
+ /* : dpc_move_en_v */
+ __IO uint32_t bank_status; /* bit 0: Bank power on complete (active low for polling) */
+ /* bit 1: Bank calibration complete (active low for polling) */
+} IOSCB_BANKCONT_DDR_STRUCT;
+
+
+#define IOSCB_BANKCONT_DDR_BASE 0x3E020000UL
+#define IOSCB_BANKCONT_DDR ((volatile IOSCB_BANKCONT_DDR_STRUCT *) IOSCB_BANKCONT_DDR_BASE)
+
+/***************************************************************************//**
+
+ */
+typedef struct mss_ddr_write_calibration_{
+ uint32_t status_lower;
+ uint32_t lower[MAX_LANES];
+ uint32_t lane_calib_result;
+} mss_ddr_write_calibration;
+
+/***************************************************************************//**
+
+ */
+typedef struct mss_lpddr4_dq_calibration_{
+ uint32_t lower[MAX_LANES];
+ uint32_t upper[MAX_LANES];
+ uint32_t calibration_found[MAX_LANES];
+} mss_lpddr4_dq_calibration;
+
+
+/***************************************************************************//**
+ Calibration settings derived during write training
+ */
+typedef struct mss_ddr_calibration_{
+ /* CMSIS related defines identifying the UART hardware. */
+ mss_ddr_write_calibration write_cal;
+ mss_lpddr4_dq_calibration dq_cal;
+ mss_ddr_vref fpga_vref;
+ mss_ddr_vref mem_vref;
+} mss_ddr_calibration;
+
+/***************************************************************************//**
+ sweep index's
+ */
+typedef struct sweep_index_{
+ uint8_t cmd_index;
+ uint8_t bclk_sclk_index;
+ uint8_t dpc_vgen_index;
+ uint8_t dpc_vgen_h_index;
+ uint8_t dpc_vgen_vs_index;
+} sweep_index;
+
+/***************************************************************************//**
+
+ */
+uint8_t
+MSS_DDR_init_simulation
+(
+ void
+);
+
+/***************************************************************************//**
+
+ */
+uint8_t
+MSS_DDR_training
+(
+ uint8_t ddr_type
+);
+
+
+/***************************************************************************//**
+ The ddr_state_machine() function runs a state machine which initializes and
+ monitors the DDR
+
+ @return
+ This function returns status, see DDR_SS_STATUS enum
+
+ Example:
+ @code
+
+ uint32_t ddr_status;
+ ddr_status = ddr_state_machine(DDR_SS__INIT);
+
+ while((ddr_status & DDR_SETUP_DONE) != DDR_SETUP_DONE)
+ {
+ ddr_status = ddr_state_machine(DDR_SS_MONITOR);
+ }
+ if ((ddr_status & DDR_SETUP_FAIL) != DDR_SETUP_FAIL)
+ {
+ error |= (0x1U << 2U);
+ }
+
+ @endcode
+
+ */
+uint32_t
+ddr_state_machine
+(
+ DDR_SS_COMMAND command
+);
+
+/***************************************************************************//**
+ The debug_read_ddrcfg() prints out the ddrcfg register values
+
+ @return
+ This function returns status, see DDR_SS_STATUS enum
+
+ Example:
+ @code
+
+ debug_read_ddrcfg();
+
+ @endcode
+
+ */
+void
+debug_read_ddrcfg
+(
+ void
+);
+
+/***************************************************************************//**
+ The setup_ddr_segments() sets up seg regs
+
+ @return
+ none
+
+ Example:
+ @code
+
+ setup_ddr_segments(DEFAULT_SEG_SETUP);
+
+ @endcode
+
+ */
+void
+setup_ddr_segments
+(
+ SEG_SETUP option
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_DDRC_H_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c
new file mode 100644
index 00000000..0c8951a1
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c
@@ -0,0 +1,923 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_debug.h
+ * @author Microchip FPGA Embedded Systems Solutions
+ * @brief DDR write and read test functions
+ *
+ */
+
+#include
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+/*******************************************************************************
+ * Local Defines
+ */
+#define DDR_BASE 0x80000000u
+#define DDR_SIZE 0x40000000u
+
+#define PDMA_CHANNEL0_BASE_ADDRESS 0x3000000ULL
+#define PDMA_CHANNEL1_BASE_ADDRESS 0x3001000ULL
+#define PDMA_CHANNEL2_BASE_ADDRESS 0x3002000ULL
+#define PDMA_CHANNEL3_BASE_ADDRESS 0x3003000ULL
+
+const char *progress[3] = {"|\r", "/\r", "-\r"};
+typedef void(*pattern_fct_t)(void);
+static uint32_t g_test_buffer_cached[765];
+static uint32_t g_test_buffer_not_cached[765];
+
+/*******************************************************************************
+ * External Defines
+ */
+#ifdef DEBUG_DDR_INIT
+#ifdef SWEEP_ENABLED
+extern uint8_t sweep_results[MAX_NUMBER_DPC_VS_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_H_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_V_GEN_SWEEPS]\
+ [MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS]\
+ [MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS];
+#endif
+#endif
+extern const uint32_t ddr_test_pattern[768];
+
+/*******************************************************************************
+ * External function declarations
+ */
+extern void delay(uint32_t n);
+extern void pdma_transfer(uint64_t destination, uint64_t source, uint64_t size_in_bytes, uint64_t base_address);
+extern void pdma_transfer_complete( uint64_t base_address);
+
+/*******************************************************************************
+ * Local data declarations
+ */
+#ifdef DEBUG_DDR_INIT
+mss_uart_instance_t *g_debug_uart;
+#endif
+
+uint64_t ddr_test;
+
+/*******************************************************************************
+ * Local function declarations
+ */
+static uint32_t ddr_write ( volatile uint64_t *DDR_word_ptr,\
+ uint32_t no_of_access, uint8_t data_ptrn, DDR_ACCESS_SIZE data_size );
+static uint32_t ddr_read ( volatile uint64_t *DDR_word_ptr,\
+ uint32_t no_of_access, uint8_t data_ptrn, DDR_ACCESS_SIZE data_size );
+
+#ifdef DEBUG_DDR_INIT
+/***************************************************************************//**
+ * Setup serial port if DDR debug required during start-up
+ * @param uart Ref to uart you want to use
+ * @return
+ */
+
+__attribute__((weak))\
+ uint32_t setup_ddr_debug_port(mss_uart_instance_t * uart)
+{
+#ifdef DEBUG_DDR_INIT
+ /* Turn on UART0 clock */
+ SYSREG->SUBBLK_CLOCK_CR |= (SUBBLK_CLOCK_CR_MMUART0_MASK);
+ /* Remove soft reset */
+ SYSREG->SOFT_RESET_CR &= (uint32_t)(~SUBBLK_CLOCK_CR_MMUART0_MASK);
+ MSS_UART_init( uart,
+ MSS_UART_115200_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+ return(0U);
+#endif
+}
+
+
+/***************************************************************************//**
+ * Print in number hex format
+ * @param uart
+ * @param b
+ */
+
+static void dumpbyte(mss_uart_instance_t * uart, uint8_t b)
+{
+#ifdef DEBUG_DDR_INIT
+ const uint8_t hexchrs[] = { '0','1','2','3','4','5','6','7','8','9','A','B',\
+ 'C','D','E','F' };
+ MSS_UART_polled_tx(uart, &hexchrs[b >> 4u] , 1);
+ MSS_UART_polled_tx(uart, &hexchrs[b & 0x0fu] , 1);
+#endif
+}
+
+/***************************************************************************//**
+ *
+ * @param uart
+ * @param msg
+ * @param d
+ */
+__attribute__((weak))\
+ void uprint32(mss_uart_instance_t * uart, const char* msg, uint32_t d)
+{
+ MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
+ for (unsigned i=0; i < 4; i++)
+ {
+ dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
+ }
+}
+
+/***************************************************************************//**
+ *
+ * @param uart
+ * @param msg
+ * @param d
+ */
+__attribute__((weak))\
+ void uprint64(mss_uart_instance_t * uart, const char* msg, uint64_t d)
+{
+ MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
+ for (unsigned i=4; i < 8; i++)
+ {
+ dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
+ }
+ for (unsigned i=0; i < 4; i++)
+ {
+ dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
+ }
+}
+
+/***************************************************************************//**
+ *
+ * @param uart
+ * @param msg
+ */
+__attribute__((weak))\
+ void uprint(mss_uart_instance_t * uart, const char* msg)
+{
+ MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
+}
+
+/***************************************************************************//**
+ * dump a number of 32bit contiguous registers
+ * @param uart
+ * @param reg_pointer
+ * @param no_of_regs
+ */
+void print_reg_array(mss_uart_instance_t * uart, uint32_t *reg_pointer,\
+ uint32_t no_of_regs)
+{
+#ifdef DEBUG_DDR_INIT
+ while(no_of_regs > 0U)
+ {
+ uprint64(uart, "\n\rRegister, 0x", (uint64_t)reg_pointer);
+ uprint32(uart, " ,Value, 0x", *reg_pointer);
+ reg_pointer++;
+ no_of_regs--;
+ }
+#endif
+}
+
+#endif
+
+/***************************************************************************//**
+ * Write data to DDR
+ * @param DDR_word_ptr
+ * @param no_of_access
+ * @param data_ptrn
+ * @return
+ */
+static uint32_t ddr_write
+(
+ volatile uint64_t *DDR_word_ptr,
+ uint32_t no_of_access,
+ uint8_t data_ptrn,
+ DDR_ACCESS_SIZE data_size
+)
+{
+ uint32_t i;
+ uint64_t DATA;
+ uint32_t error_count = 0U;
+
+ uint32_t *DDR_32_ptr = (uint32_t *)DDR_word_ptr;
+ uint16_t *DDR_16_ptr = (uint16_t *)DDR_word_ptr;
+ uint8_t *DDR_8_ptr = (uint8_t *)DDR_word_ptr;
+
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = 0x00000000; break;
+ case PATTERN_WALKING_ONE : DATA = 0x00000001; break;
+ case PATTERN_WALKING_ZERO : DATA = 0x01;
+ DATA = ~ DATA; break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ DATA = 0x00000000;
+ break;
+ }
+
+ for( i = 0; i< (no_of_access); i++)
+ {
+ switch(data_size)
+ {
+ case DDR_8_BIT:
+ DATA &= 0xFFUL;
+ *DDR_8_ptr = (uint8_t)DATA;
+ DDR_8_ptr = DDR_8_ptr + 1;
+ break;
+ case DDR_16_BIT:
+ DATA &= 0xFFFFUL;
+ *DDR_16_ptr = (uint16_t)DATA;
+ DDR_16_ptr = DDR_16_ptr + 1;
+ break;
+ case DDR_32_BIT:
+ DATA &= 0xFFFFFFFFUL;
+ *DDR_32_ptr = (uint32_t)DATA;
+ DDR_32_ptr = DDR_32_ptr + 1;
+ break;
+ default:
+ case DDR_64_BIT:
+ *DDR_word_ptr = DATA;
+ DDR_word_ptr = DDR_word_ptr + 1;
+ break;
+ }
+
+#ifdef DEBUG_DDR_INIT
+ if((i%0x1000000UL) ==0UL)
+ {
+ MSS_UART_polled_tx(g_debug_uart, (const uint8_t*)"w", (uint32_t)1UL);
+ }
+#endif
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = DATA + 0x00000001; break;
+ case PATTERN_WALKING_ONE :
+ if (DATA == 0x80000000)
+ DATA = 0x00000001;
+ else
+ DATA = (DATA << 1);
+ break;
+ case PATTERN_WALKING_ZERO :
+ DATA = ~DATA;
+ if (DATA == 0x80000000)
+ DATA = 0x00000001;
+ else
+ {
+ DATA = (DATA << 1);
+ }
+ DATA = ~DATA;
+ break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ break;
+ }
+ }
+ return error_count;
+}
+
+/***************************************************************************//**
+ * Reads and compares with what was written
+ * @param DDR_word_ptr
+ * @param no_of_access
+ * @param data_ptrn
+ * @return 0 => read backs all expected value, otherwise error count
+ */
+uint32_t ddr_read
+(
+ volatile uint64_t *DDR_word_ptr,
+ uint32_t no_of_access,
+ uint8_t data_ptrn,
+ DDR_ACCESS_SIZE data_size
+)
+{
+ uint32_t i;
+ uint64_t DATA;
+ uint32_t err_cnt;
+ volatile uint64_t ddr_data;
+ volatile uint64_t *DDR_word_pt_t, *first_DDR_word_pt_t;
+ uint32_t rand_addr_offset;
+ uint8_t *DDR_8_pt_t;
+ uint16_t *DDR_16_pt_t;
+ uint32_t *DDR_32_pt_t;
+
+ err_cnt = 0U;
+ first_DDR_word_pt_t = DDR_word_ptr;
+ DDR_8_pt_t = (uint8_t *)DDR_word_ptr;
+ DDR_16_pt_t = (uint16_t *)DDR_word_ptr;
+ DDR_32_pt_t = (uint32_t *)DDR_word_ptr;
+
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = 0x00000000; break;
+ case PATTERN_WALKING_ONE : DATA = 0x00000001; break;
+ case PATTERN_WALKING_ZERO : DATA = 0x01;
+ DATA = ~ DATA; break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ *DDR_word_ptr = DATA;
+ *DDR_8_pt_t = (uint8_t)DATA;
+ *DDR_16_pt_t = (uint16_t)DATA;
+ *DDR_32_pt_t = (uint32_t)DATA;
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ DATA = 0x00000000;
+ break;
+ }
+ if (data_ptrn == '4')
+ {
+ delay(10);
+ }
+ for( i = 0; i< (no_of_access); i++)
+ {
+ switch(data_size)
+ {
+ case DDR_8_BIT:
+ DATA &= 0xFFUL;
+ ddr_data = *DDR_8_pt_t;
+ break;
+ case DDR_16_BIT:
+ DATA &= 0xFFFFUL;
+ ddr_data = *DDR_16_pt_t;
+ break;
+ case DDR_32_BIT:
+ DATA &= 0xFFFFFFFFUL;
+ ddr_data = *DDR_32_pt_t;
+ break;
+ default:
+ case DDR_64_BIT:
+ DDR_word_pt_t = DDR_word_ptr;
+ ddr_data = *DDR_word_pt_t;
+ break;
+ }
+
+#ifdef DEBUG_DDR_INIT
+ if((i%0x1000000UL) ==0UL)
+ {
+ MSS_UART_polled_tx(g_debug_uart, (const uint8_t*)"r", (uint32_t)1UL);
+ }
+#endif
+
+ if (ddr_data != DATA)
+ {
+#ifdef DEBUG_DDR_INIT
+#ifdef DEBUG_DDR_RD_RW_FAIL
+ if (err_cnt <=0xF)
+ {
+ uprint64(g_debug_uart,\
+ "\n\r READ/ WRITE ACCESS FAILED AT ADDR: 0x ",\
+ (uintptr_t)DDR_word_ptr);
+ uprint64(g_debug_uart,"\t Expected Data 0x ", DATA);
+ uprint64(g_debug_uart,"\t READ DATA: 0x ", ddr_data);
+ uprint64(g_debug_uart,"\t READ DATA: 0x ", *DDR_word_ptr);
+ uprint64(g_debug_uart,"\t READ DATA: 0x ", *DDR_word_ptr);
+ }
+#endif
+#endif
+ err_cnt++;
+ }
+ else
+ {
+#ifdef DEBUG_DDR_RD_RW_PASS
+ //printf("\n\r READ/ WRITE ACCESS passED AT ADDR: 0x%x expected data = 0x%x, Data read 0x%x",DDR_word_ptr, DATA, *DDR_word_ptr);
+ uprint64(g_debug_uart, "\n\r READ/ WRITE ACCESS PASSED AT ADDR: 0x"\
+ , (uintptr_t)DDR_word_ptr);
+ uprint64(g_debug_uart,"\t READ DATA: 0x", *DDR_word_ptr);
+#endif
+ }
+ DDR_word_ptr = DDR_word_ptr + 1U;
+ DDR_8_pt_t = DDR_8_pt_t +1U;
+ DDR_16_pt_t = DDR_16_pt_t +1U;
+ DDR_32_pt_t = DDR_32_pt_t +1U;
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = DATA + 0x01; break;
+ case PATTERN_WALKING_ONE :
+ if (DATA == 0x80000000)
+ DATA = 0x00000001;
+ else
+ DATA = (DATA << 1);
+ break;
+ case PATTERN_WALKING_ZERO :
+ DATA = ~DATA;
+ if (DATA == 0x80000000)
+ {
+ DATA = 0x00000001;
+ }
+ else
+ {
+ DATA = (DATA << 1);
+ }
+ DATA = ~DATA;
+ break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ rand_addr_offset = (uint32_t)(rand() & 0xFFFFCUL);
+ DDR_word_ptr = first_DDR_word_pt_t + rand_addr_offset;
+ DDR_8_pt_t = (uint8_t *)(first_DDR_word_pt_t + rand_addr_offset);
+ DDR_16_pt_t = (uint16_t *)(first_DDR_word_pt_t + rand_addr_offset);
+ DDR_32_pt_t = (uint32_t *)(first_DDR_word_pt_t + rand_addr_offset);
+ *DDR_word_ptr = DATA;
+ *DDR_8_pt_t = (uint8_t)DATA;
+ *DDR_16_pt_t = (uint16_t)DATA;
+ *DDR_32_pt_t = (uint32_t)DATA;
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ break;
+ }
+ }
+ return (err_cnt);
+}
+
+/***************************************************************************//**
+ *
+ * @param DDR_word_ptr Address
+ * @param no_access Number of addresses
+ * @param pattern bit mask with patterns you want to test against
+ * @return
+ */
+uint32_t ddr_read_write_fn (uint64_t* DDR_word_ptr, uint32_t no_access,\
+ uint32_t pattern)
+{
+ uint32_t error_cnt = 0U;
+ uint8_t pattern_mask;
+ for (unsigned i=0; i < 1; i++)
+ {
+ for (uint32_t pattern_shift=0U; pattern_shift < MAX_NO_PATTERNS;\
+ pattern_shift++)
+ {
+ pattern_mask = (uint8_t)(0x01U << pattern_shift);
+ if(pattern & pattern_mask)
+ {
+#ifdef DEBUG_DDR_INIT
+ uprint32(g_debug_uart,"\n\r\t Pattern: 0x", pattern_shift);
+#endif
+
+#if TEST_64BIT_ACCESS == 1
+ /* write the pattern */
+ error_cnt += ddr_write ((uint64_t *)DDR_word_ptr,\
+ no_access, pattern_mask, DDR_64_BIT);
+ /* read back and verifies */
+ error_cnt += ddr_read ((uint64_t *)DDR_word_ptr, \
+ no_access, pattern_mask, DDR_64_BIT);
+#endif
+
+#if TEST_32BIT_ACCESS == 1
+ /* write the pattern */
+ error_cnt += ddr_write ((uint64_t *)DDR_word_ptr,\
+ no_access, pattern_mask, DDR_32_BIT);
+ /* read back and verifies */
+ error_cnt += ddr_read ((uint64_t *)DDR_word_ptr, \
+ no_access, pattern_mask, DDR_32_BIT);
+#endif
+ }
+ }
+ DDR_word_ptr++; /* increment the address */
+ }
+ return error_cnt;
+}
+
+
+/***************************************************************************//**
+ *
+ * @param error
+ * @return
+ */
+#ifdef DEBUG_DDR_INIT
+uint32_t error_status(mss_uart_instance_t *g_mss_uart_debug_pt, uint32_t error)
+{
+ uprint32(g_mss_uart_debug_pt, "\n\r ERROR_RESULT: ", error);
+ return (0U);
+}
+#endif
+
+/***************************************************************************//**
+ * Calibration status
+ * @return
+ */
+#ifdef DEBUG_DDR_INIT
+uint32_t wrcalib_status(mss_uart_instance_t *g_mss_uart_debug_pt)
+{
+ uprint32(g_mss_uart_debug_pt, "\n\r WRCALIB_RESULT: ",\
+ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib);
+ return (0U);
+}
+#endif
+
+#ifdef DEBUG_DDR_INIT
+/***************************************************************************//**
+ * Prints out DDR status
+ * @return
+ */
+uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt)
+{
+
+ uint32_t t_status = 0U;
+ uint32_t MSS_DDR_APB_ADDR;
+ uint32_t ddr_lane_sel;
+ uint32_t dq0_dly = 0U;
+ uint32_t dq1_dly = 0U;
+ uint32_t dq2_dly = 0U;
+ uint32_t dq3_dly = 0U;
+ uint32_t dq4_dly = 0U;
+ uint32_t dq5_dly = 0U;
+
+ /* MSS_UART_polled_tx_string(g_mss_uart_debug_pt, "\n\n\r TIP register status \n");
+ delay(1000);*/
+ uprint32(g_mss_uart_debug_pt, "\n\r\n\r training status = ",\
+ CFG_DDR_SGMII_PHY->training_status.training_status);
+ uprint32(g_mss_uart_debug_pt, "\n\r PCODE = ",\
+ (CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2 & 0x7F));
+ uprint32(g_mss_uart_debug_pt, "\n\r NCODE = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2) >> 7) & 0x7F));
+ uprint32(g_mss_uart_debug_pt, "\n\r WRCALIB_RESULT: "\
+ , CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib);
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_ref_slewr = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 0) & 0x3F));
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_ref_slewf = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 6) & 0xFFF));
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_slewr = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 18) & 0x3F));
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_slewf = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 24) & 0x3F));
+
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt, \
+ (const uint8_t*)"\n\n\r lane_select \t gt_err_comb \t gt_txdly \t gt_steps_180 \t gt_state \t wl_delay_0 \t dqdqs_err_done \t dqdqs_state \t delta0 \t delta1");
+
+ for (ddr_lane_sel=0U; ddr_lane_sel < LIBERO_SETTING_DATA_LANES_USED; ddr_lane_sel++)
+ {
+ CFG_DDR_SGMII_PHY->lane_select.lane_select = ddr_lane_sel;
+ uprint32(g_mss_uart_debug_pt, "\n\r ",\
+ CFG_DDR_SGMII_PHY->lane_select.lane_select);
+ delay(1000);
+ MSS_DDR_APB_ADDR = CFG_DDR_SGMII_PHY->gt_err_comb.gt_err_comb;
+ uprint32(g_mss_uart_debug_pt, "\t ", MSS_DDR_APB_ADDR);
+ t_status = t_status | MSS_DDR_APB_ADDR;
+
+ MSS_DDR_APB_ADDR = CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly;
+ uprint32(g_mss_uart_debug_pt, "\t ", MSS_DDR_APB_ADDR);
+
+ if((MSS_DDR_APB_ADDR & 0xFF) == 0) t_status = 1;
+ if((MSS_DDR_APB_ADDR & 0xFF00) == 0) t_status = 1;
+ if((MSS_DDR_APB_ADDR & 0xFF0000) == 0) t_status = 1;
+ if((MSS_DDR_APB_ADDR & 0xFF000000) == 0) t_status = 1;
+
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->gt_steps_180.gt_steps_180);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->gt_state.gt_state);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->wl_delay_0.wl_delay_0);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->dq_dqs_err_done.dq_dqs_err_done);
+ t_status = t_status | (MSS_DDR_APB_ADDR != 8);
+
+ uprint32(g_mss_uart_debug_pt, "\t\t ",\
+ CFG_DDR_SGMII_PHY->dqdqs_state.dqdqs_state);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->delta0.delta0);
+ dq0_dly = (MSS_DDR_APB_ADDR & 0xFF);
+ dq1_dly = (MSS_DDR_APB_ADDR & 0xFF00) >> 8;
+ dq2_dly = (MSS_DDR_APB_ADDR & 0xFF0000) >> 16;
+ dq3_dly = (MSS_DDR_APB_ADDR & 0xFF000000) >> 24;
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->delta1.delta1);
+ dq4_dly = (MSS_DDR_APB_ADDR & 0xFF);
+ dq5_dly = (MSS_DDR_APB_ADDR & 0xFF00) >> 8;
+ dq2_dly = (MSS_DDR_APB_ADDR & 0xFF0000) >> 16;
+ dq3_dly = (MSS_DDR_APB_ADDR & 0xFF000000) >> 24;
+ }
+
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt, (const uint8_t*)"\n\r\n\r lane_select\t rdqdqs_status2\t addcmd_status0\t addcmd_status1\t addcmd_answer1\t dqdqs_status1\n\r");
+ for (ddr_lane_sel=0U; ddr_lane_sel < LIBERO_SETTING_DATA_LANES_USED;\
+ ddr_lane_sel++)
+ {
+ CFG_DDR_SGMII_PHY->lane_select.lane_select = ddr_lane_sel;
+ uprint32(g_mss_uart_debug_pt, "\n\r ",\
+ CFG_DDR_SGMII_PHY->lane_select.lane_select);
+ delay(1000);
+
+ if(dq0_dly > 20) t_status = 1;
+ if(dq1_dly > 20) t_status = 1;
+ if(dq2_dly > 20) t_status = 1;
+ if(dq3_dly > 20) t_status = 1;
+ if(dq4_dly > 20) t_status = 1;
+ if(dq5_dly > 20) t_status = 1;
+
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->dqdqs_status2.dqdqs_status2);
+
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->addcmd_answer.addcmd_answer);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->dqdqs_status1.dqdqs_status1);
+
+ }
+ return(t_status);
+}
+#endif
+
+/***************************************************************************//**
+ * display sweep results
+ *
+ * @param g_mss_uart_debug_pt
+ */
+#ifdef DEBUG_DDR_INIT
+#ifdef SWEEP_ENABLED
+void sweep_status (mss_uart_instance_t *g_mss_uart_debug_pt)
+{
+
+ uint32_t t_status;
+ uint8_t cmd_index;
+ uint8_t bclk_sclk_index;
+ uint8_t dpc_vgen_index;
+ uint8_t dpc_vgen_h_index;
+ uint8_t dpc_vgen_vs_index;
+
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
+ "\n\n\r dpc_vgen_vs dpc_vgen_h \t dpc_vgen_v \t bclk_sclk");
+ for (cmd_index=0U; cmd_index < MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS; \
+ cmd_index++)
+ {
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ cmd_index + LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET);
+ }
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
+ "\n\r--------------------------------------------------------------------");
+
+ for (dpc_vgen_vs_index=0U; dpc_vgen_vs_index 1000)
+ {
+ alive = 0;
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)".");
+#endif
+ }
+ }
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r\nFinished loading test pattern\r\n");
+#endif
+
+ pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL2_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL3_BASE_ADDRESS);
+
+}
+
+/**
+ * Run from address
+ * @param start_addr address to run from.
+ */
+void execute_ddr_pattern(uint64_t start_addr)
+{
+ pattern_fct_t p_pattern_fct = (pattern_fct_t)start_addr;
+
+ (*p_pattern_fct)();
+}
+
+/**
+ * Loads DDR with a pattern that triggers read issues if not enough margin.
+ * Used to verify training is successful.
+ * @param p_cached_ddr
+ * @param p_not_cached_ddr
+ * @param length
+ */
+void load_test_buffers(uint32_t * p_cached_ddr, uint32_t * p_not_cached_ddr, uint64_t length)
+{
+ (void)length;
+
+ pdma_transfer((uint64_t)g_test_buffer_cached, (uint64_t)p_cached_ddr, length, PDMA_CHANNEL0_BASE_ADDRESS);
+ pdma_transfer((uint64_t)g_test_buffer_not_cached, (uint64_t)p_not_cached_ddr, length, PDMA_CHANNEL1_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS);
+}
+
+/**
+ * test_ddr reads from cached and non cached DDR and compares
+ * @param no_of_iterations
+ * @param size
+ * @return returns 1 if compare fails
+ */
+uint32_t test_ddr(uint32_t no_of_iterations, uint32_t size)
+{
+ uint32_t pattern_length = sizeof(ddr_test_pattern) - (3 * sizeof(uint32_t));
+ uint32_t * p_ddr_cached = (uint32_t *)0x80000000;
+ uint32_t * p_ddr_noncached = (uint32_t *)0x1400000000;
+ uint32_t word_offset;
+ uint32_t alive = 0;
+ uint32_t alive_idx = 0U;
+ uint32_t iteration = 0U;
+ uint32_t error = 0U;
+
+
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r\nStarting ddr test\r\n");
+#endif
+ while(iteration < no_of_iterations)
+ {
+ int different = 0;
+
+ load_test_buffers(p_ddr_cached, p_ddr_noncached, pattern_length);
+
+ different = memcmp(g_test_buffer_cached, g_test_buffer_not_cached, pattern_length);
+
+ if(different != 0)
+ {
+ for(word_offset = 0; word_offset < (pattern_length / sizeof(uint32_t)); word_offset++)
+ {
+ if(g_test_buffer_cached[word_offset] != g_test_buffer_not_cached[word_offset])
+ {
+#ifdef DEBUG_DDR_INIT
+ uprint64(g_debug_uart, " Mismatch, 0x", (uint64_t)p_ddr_cached);
+ uprint32(g_debug_uart, " offset:, 0x", (uint64_t)word_offset);
+ uprint32(g_debug_uart, " address: 0x", (uint64_t)(p_ddr_cached + word_offset));
+ uprint32(g_debug_uart, " expected (non-cached): 0x", g_test_buffer_not_cached[word_offset]);
+ uprint32(g_debug_uart, " found (cached): 0x", (uint64_t)g_test_buffer_cached[word_offset]);
+ uprint32(g_debug_uart, " direct cached read: 0x", (uint32_t)*(p_ddr_cached + word_offset));
+ uprint32(g_debug_uart, " direct non-cached read: 0x", (uint32_t)*(p_ddr_noncached + word_offset));
+#endif
+ break;
+ }
+ }
+ error = 1U;
+ return error;
+ }
+
+ if (((uint64_t)p_ddr_cached + ( 2 * pattern_length)) < (LIBERO_SETTING_DDR_32_CACHE + size))
+ {
+ p_ddr_cached += (pattern_length / sizeof(uint32_t));
+ p_ddr_noncached += (pattern_length / sizeof(uint32_t));
+ }
+ else
+ {
+ p_ddr_cached = (uint32_t *)0x80000000;
+ p_ddr_noncached = (uint32_t *)0x1400000000;
+ iteration++;
+#ifdef DEBUG_DDR_INIT
+ uprint32(g_debug_uart, " Iteration ", (uint64_t)(unsigned int)iteration);
+#endif
+ }
+
+ alive++;
+ if(alive > 10000U)
+ {
+ alive = 0;
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r");
+ uprint(g_debug_uart, (const char*)progress[alive_idx]);
+#endif
+ alive_idx++;
+ if(alive_idx >= 3U)
+ {
+ alive_idx = 0;
+ }
+ if(ddr_test == 2U)
+ {
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r\nEnding ddr test. Press 0 to display the menu\r\n");
+#endif
+ return error;
+ }
+ }
+ }
+ return error;
+}
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h
new file mode 100644
index 00000000..20c3c111
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_debug.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief mss_ddr_debug related defines
+ *
+ */
+
+/*=========================================================================*//**
+ @page DDR setup and monitoring
+ ==============================================================================
+ @section intro_sec Introduction
+ ==============================================================================
+ DDR debug helper functions
+
+ ==============================================================================
+ @section Items located in the north west corner
+ ==============================================================================
+ -
+
+ ==============================================================================
+ @section Overview of DDR related hardware
+ ==============================================================================
+
+ *//*=========================================================================*/
+
+#include
+#include
+
+
+#ifndef __MSS_DDr_DEBUG_H_
+#define __MSS_DDr_DEBUG_H_ 1
+
+#ifdef DEBUG_DDR_INIT
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TEST_64BIT_ACCESS
+#define TEST_64BIT_ACCESS 1
+#endif
+
+#ifndef TEST_32BIT_ACCESS
+#define TEST_32BIT_ACCESS 1
+#endif
+
+typedef enum DDR_ACCESS_SIZE_
+{
+ DDR_8_BIT,
+ DDR_16_BIT,
+ DDR_32_BIT,
+ DDR_64_BIT
+} DDR_ACCESS_SIZE;
+
+
+/***************************************************************************//**
+ The ddr_read_write_fn function is used to write/read test patterns to the DDR
+
+ @return
+ This function returns 0 if successful, number of errors if not.
+
+ Example:
+ @code
+
+ if (ddr_read_write_fn() != 0U)
+ {
+ .. warn the user, increment error count , wait for watchdog reset
+ }
+
+ @endcode
+ */
+uint32_t
+ddr_read_write_fn
+(
+uint64_t* DDR_word_ptr,
+uint32_t no_access,
+uint32_t pattern
+);
+
+#ifdef DEBUG_DDR_INIT
+/***************************************************************************//**
+ The uprint32() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)uprint32(g_debug_uart, "\n\r DDR_TRAINING_FAIL: ", error);
+
+ @endcode
+ */
+void
+uprint32
+(
+mss_uart_instance_t * uart,
+const char* msg,
+uint32_t d
+);
+
+/***************************************************************************//**
+ The uprint64() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)uprint64(g_debug_uart, "\n\r DDR_TRAINING_FAIL: ", error);
+
+ @endcode
+ */
+void
+uprint64
+(
+mss_uart_instance_t * uart,
+const char* msg,
+uint64_t d
+);
+
+/***************************************************************************//**
+ The error_status() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)error_status(g_debug_uart, "\n\r DDR_TRAINING_FAIL: ", error);
+
+ @endcode
+ */
+uint32_t error_status(mss_uart_instance_t *g_mss_uart_debug_pt, uint32_t error);
+
+/***************************************************************************//**
+ The wrcalib_status() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)wrcalib_status(mss_uart_instance_t *g_mss_uart_debug_pt);
+
+ @endcode
+ */
+uint32_t wrcalib_status(mss_uart_instance_t *g_mss_uart_debug_pt);
+
+/***************************************************************************//**
+ The tip_register_status() function is used to print ddr TIP status to the
+ designated debug port
+
+ Example:
+ @code
+
+ (void)tip_register_status(mss_uart_instance_t *g_mss_uart_debug_pt);
+
+ @endcode
+ */
+uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt);
+
+/***************************************************************************//**
+ The setup_ddr_debug_port() function is used to setup a serial port dedicated
+ to printing information on the DDR start-up.
+
+ @return
+ This function returns 0 if successful
+
+ Example:
+ @code
+
+ if (ddr_setup() != 0U)
+ {
+ .. warn the user, increment error count , wait for watchdog reset
+ }
+
+ @endcode
+ */
+uint32_t
+setup_ddr_debug_port
+(
+mss_uart_instance_t * uart
+);
+
+/***************************************************************************//**
+ *
+ */
+void
+sweep_status
+(
+mss_uart_instance_t *g_mss_uart_debug_pt
+);
+
+/***************************************************************************//**
+ *
+ */
+void
+print_reg_array
+(
+mss_uart_instance_t * uart,
+uint32_t *reg_pointer,
+uint32_t no_of_regs
+);
+#endif
+
+/***************************************************************************//**
+ *
+ */
+void
+load_ddr_pattern
+(
+uint64_t base,
+uint32_t size,
+uint8_t pattern_offset
+);
+
+/***************************************************************************//**
+ *
+ */
+uint32_t
+test_ddr
+(
+uint32_t no_of_iterations,
+uint32_t size
+);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_DDRC_H_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h
new file mode 100644
index 00000000..355eb551
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_defs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief mss_ddr_debug related defines
+ *
+ */
+
+#ifndef SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_
+#define SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_
+
+#define PATTERN_INCREMENTAL (0x01U << 0U)
+#define PATTERN_WALKING_ONE (0x01U << 1U)
+#define PATTERN_WALKING_ZERO (0x01U << 2U)
+#define PATTERN_RANDOM (0x01U << 3U)
+#define PATTERN_0xCCCCCCCC (0x01U << 4U)
+#define PATTERN_0x55555555 (0x01U << 5U)
+#define PATTERN_ZEROS (0x01U << 6U)
+#define MAX_NO_PATTERNS 7U
+
+/* Training types status offsets */
+#define BCLK_SCLK_BIT (0x1U<<0U)
+#define ADDCMD_BIT (0x1U<<1U)
+#define WRLVL_BIT (0x1U<<2U)
+#define RDGATE_BIT (0x1U<<3U)
+#define DQ_DQS_BIT (0x1U<<4U)
+
+/* The first five bits represent the currently supported training in the TIP */
+/* This value will not change unless more training possibilities are added to
+ * the TIP */
+#define TRAINING_MASK (BCLK_SCLK_BIT|\
+ ADDCMD_BIT|\
+ WRLVL_BIT|\
+ RDGATE_BIT|\
+ DQ_DQS_BIT)
+
+#endif /* SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_phy_defs.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_phy_defs.h
new file mode 100644
index 00000000..74a12396
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_phy_defs.h
@@ -0,0 +1,4692 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_sgmii_phy_defs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Register bit offsets and masks definitions for MPFS MSS DDR
+ * This was generated directly from the RTL
+ *
+ */
+
+#ifndef MSS_DDR_SGMII_PHY_DEFS_H_
+#define MSS_DDR_SGMII_PHY_DEFS_H_
+
+
+#include "mpfs_hal/mss_hal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __I
+#define __I const volatile
+#endif
+#ifndef __IO
+#define __IO volatile
+#endif
+#ifndef __O
+#define __O volatile
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------- DDR -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+
+/*============================== CFG_DDR_SGMII_PHY definitions ===========================*/
+
+typedef enum { /*!< SOFT_RESET_DDR_PHY.PERIPH_DDR_PHY bitfield definition*/
+ scb_periph_not_in_soft_reset_ddr_phy = 0,
+ scb_periph_reset_ddr_phy = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_PERIPH_DDR_PHY_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DDR_PHY.V_MAP_DDR_PHY bitfield definition*/
+ scb_v_regs_not_in_soft_reset_ddr_phy = 0,
+ scb_v_regs_reset_ddr_phy = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_V_MAP_DDR_PHY_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DDR_PHY.NV_MAP_DDR_PHY bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_ddr_phy = 0,
+ scb_nv_regs_reset_ddr_phy = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_NV_MAP_DDR_PHY_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.BLOCKID_MAIN_PLL bitfield definition*/
+ block_address_main_pll = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_BLOCKID_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.PERIPH_MAIN_PLL bitfield definition*/
+ scb_periph_not_in_soft_reset_main_pll = 0,
+ scb_periph_reset_main_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_PERIPH_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.V_MAP_MAIN_PLL bitfield definition*/
+ scb_v_regs_not_in_soft_reset_main_pll = 0,
+ scb_v_regs_reset_main_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_V_MAP_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.NV_MAP_MAIN_PLL bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_main_pll = 0,
+ scb_nv_regs_reset_main_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_NV_MAP_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.BLOCKID_IOSCB_PLL bitfield definition*/
+ block_address_ioscb_pll = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_BLOCKID_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.PERIPH_IOSCB_PLL bitfield definition*/
+ scb_periph_not_in_soft_reset_ioscb_pll = 0,
+ scb_periph_reset_ioscb_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_PERIPH_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.V_MAP_IOSCB_PLL bitfield definition*/
+ scb_v_regs_not_in_soft_reset_ioscb_pll = 0,
+ scb_v_regs_reset_ioscb_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_V_MAP_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.NV_MAP_IOSCB_PLL bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_ioscb_pll = 0,
+ scb_nv_regs_reset_ioscb_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_NV_MAP_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.BLOCKID_BANK_CTRL bitfield definition*/
+ block_address_bank_ctrl = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_BLOCKID_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.PERIPH_BANK_CTRL bitfield definition*/
+ scb_periph_not_in_soft_reset_bank_ctrl = 0,
+ scb_periph_reset_bank_ctrl = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_PERIPH_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.V_MAP_BANK_CTRL bitfield definition*/
+ scb_v_regs_not_in_soft_reset_bank_ctrl = 0,
+ scb_v_regs_reset_bank_ctrl = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_V_MAP_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.NV_MAP_BANK_CTRL bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_bank_ctrl = 0,
+ scb_nv_regs_reset_bank_ctrl = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_NV_MAP_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.BLOCKID_IOCALIB bitfield definition*/
+ block_address_iocalib = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_BLOCKID_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.PERIPH_IOCALIB bitfield definition*/
+ scb_periph_not_in_soft_reset_iocalib = 0,
+ scb_periph_reset_iocalib = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_PERIPH_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.V_MAP_IOCALIB bitfield definition*/
+ scb_v_regs_not_in_soft_reset_iocalib = 0,
+ scb_v_regs_reset_iocalib = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_V_MAP_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.NV_MAP_IOCALIB bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_iocalib = 0,
+ scb_nv_regs_reset_iocalib = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_NV_MAP_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.BLOCKID_CFM bitfield definition*/
+ block_address_cfm = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_BLOCKID_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.PERIPH_CFM bitfield definition*/
+ scb_periph_not_in_soft_reset_cfm = 0,
+ scb_periph_reset_cfm = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_PERIPH_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.V_MAP_CFM bitfield definition*/
+ scb_v_regs_not_in_soft_reset_cfm = 0,
+ scb_v_regs_reset_cfm = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_V_MAP_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.NV_MAP_CFM bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_cfm = 0,
+ scb_nv_regs_reset_cfm = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_NV_MAP_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.BLOCKID_DECODER_DRIVER bitfield definition*/
+ block_address_decoder_driver = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_BLOCKID_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.PERIPH_DECODER_DRIVER bitfield definition*/
+ scb_periph_not_in_soft_reset_decoder_driver = 0,
+ scb_periph_reset_decoder_driver = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_PERIPH_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.V_MAP_DECODER_DRIVER bitfield definition*/
+ scb_v_regs_not_in_soft_reset_decoder_driver = 0,
+ scb_v_regs_reset_decoder_driver = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_V_MAP_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.NV_MAP_DECODER_DRIVER bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_decoder_driver = 0,
+ scb_nv_regs_reset_decoder_driver = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_NV_MAP_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.BLOCKID_DECODER_ODT bitfield definition*/
+ block_address_decoder_odt = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_BLOCKID_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.PERIPH_DECODER_ODT bitfield definition*/
+ scb_periph_not_in_soft_reset_decoder_odt = 0,
+ scb_periph_reset_decoder_odt = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_PERIPH_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.V_MAP_DECODER_ODT bitfield definition*/
+ scb_v_regs_not_in_soft_reset_decoder_odt = 0,
+ scb_v_regs_reset_decoder_odt = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_V_MAP_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.NV_MAP_DECODER_ODT bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_decoder_odt = 0,
+ scb_nv_regs_reset_decoder_odt = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_NV_MAP_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.BLOCKID_DECODER_IO bitfield definition*/
+ block_address_decoder_io = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_BLOCKID_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.PERIPH_DECODER_IO bitfield definition*/
+ scb_periph_not_in_soft_reset_decoder_io = 0,
+ scb_periph_reset_decoder_io = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_PERIPH_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.V_MAP_DECODER_IO bitfield definition*/
+ scb_v_regs_not_in_soft_reset_decoder_io = 0,
+ scb_v_regs_reset_decoder_io = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_V_MAP_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.NV_MAP_DECODER_IO bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_decoder_io = 0,
+ scb_nv_regs_reset_decoder_io = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_NV_MAP_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_TIP.PERIPH_TIP bitfield definition*/
+ scb_periph_not_in_soft_reset_ddr_tip = 0,
+ scb_periph_reset_ddr_tip = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_PERIPH_TIP_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_TIP.V_MAP_TIP bitfield definition*/
+ scb_v_regs_not_in_soft_reset_ddr_tip = 0,
+ scb_v_regs_reset_ddr_tip = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_V_MAP_TIP_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_TIP.NV_MAP_TIP bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_ddr_tip = 0,
+ scb_nv_regs_reset_ddr_tip = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_NV_MAP_TIP_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DDR_PHY register definition*/
+ __IO uint32_t SOFT_RESET_DDR_PHY;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_NV_MAP_DDR_PHY_TypeDef NV_MAP_DDR_PHY :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_V_MAP_DDR_PHY_TypeDef V_MAP_DDR_PHY :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_PERIPH_DDR_PHY_TypeDef PERIPH_DDR_PHY :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t BLOCKID_DDR_PHY :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_TypeDef;
+
+typedef union{ /*!< DDRPHY_MODE register definition*/
+ __IO uint32_t DDRPHY_MODE;
+ struct
+ {
+ __IO uint32_t DDRMODE :3;
+ __IO uint32_t ECC :1;
+ __IO uint32_t CRC :1;
+ __IO uint32_t Bus_width :3;
+ __IO uint32_t DMI_DBI :1;
+ __IO uint32_t DQ_drive :2;
+ __IO uint32_t DQS_drive :2;
+ __IO uint32_t ADD_CMD_drive :2;
+ __IO uint32_t Clock_out_drive :2;
+ __IO uint32_t DQ_termination :2;
+ __IO uint32_t DQS_termination :2;
+ __IO uint32_t ADD_CMD_input_pin_termination :2;
+ __IO uint32_t preset_odt_clk :2;
+ __IO uint32_t Power_down :1;
+ __IO uint32_t rank :1;
+ __IO uint32_t Command_Address_Pipe :2;
+ __I uint32_t Reserved :3;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DDRPHY_MODE_TypeDef;
+
+typedef union{ /*!< DDRPHY_STARTUP register definition*/
+ __IO uint32_t DDRPHY_STARTUP;
+ struct
+ {
+ __IO uint32_t ADD_CMD_Lockdn :1;
+ __IO uint32_t DATA_Lockdn :1;
+ __IO uint32_t PERSIST_ADD_CMD :1;
+ __IO uint32_t Persist_CLKOUT :1;
+ __IO uint32_t Persist_DATA :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t DYNEN_SCB_PLL0 :1;
+ __IO uint32_t DYNEN_SCB_PLL1 :1;
+ __IO uint32_t DYNEN_SCB_CFM :1;
+ __IO uint32_t DYNEN_SCB_IO_CALIB :1;
+ __IO uint32_t DYNEN_SCB_BANKCNTL :1;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t DYNEN_APB_PLL0 :1;
+ __IO uint32_t DYNEN_APB_PLL1 :1;
+ __IO uint32_t DYNEN_APB_CFM :1;
+ __IO uint32_t DYNEN_APB_IO_CALIB :1;
+ __IO uint32_t DYNEN_APB_BANKCNTL :1;
+ __IO uint32_t DYNEN_APB_DECODER_PRESETS :1;
+ __IO uint32_t reserved3 :10;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DDRPHY_STARTUP_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_MAIN_PLL register definition*/
+ __IO uint32_t SOFT_RESET_MAIN_PLL;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_NV_MAP_MAIN_PLL_TypeDef NV_MAP_MAIN_PLL :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_V_MAP_MAIN_PLL_TypeDef V_MAP_MAIN_PLL :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_PERIPH_MAIN_PLL_TypeDef PERIPH_MAIN_PLL :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_BLOCKID_MAIN_PLL_TypeDef BLOCKID_MAIN_PLL :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_TypeDef;
+
+typedef union{ /*!< PLL_CTRL_MAIN register definition*/
+ __IO uint32_t PLL_CTRL_MAIN;
+ struct
+ {
+ __IO uint32_t REG_POWERDOWN_B :1;
+ __IO uint32_t REG_RFDIV_EN :1;
+ __IO uint32_t REG_DIVQ0_EN :1;
+ __IO uint32_t REG_DIVQ1_EN :1;
+ __IO uint32_t REG_DIVQ2_EN :1;
+ __IO uint32_t REG_DIVQ3_EN :1;
+ __IO uint32_t REG_RFCLK_SEL :1;
+ __I uint32_t RESETONLOCK :1;
+ __I uint32_t BYPCK_SEL :4;
+ __I uint32_t REG_BYPASS_GO_B :1;
+ __I uint32_t reserve10 :3;
+ __I uint32_t REG_BYPASSPRE :4;
+ __I uint32_t REG_BYPASSPOST :4;
+ __IO uint32_t LP_REQUIRES_LOCK :1;
+ __I uint32_t LOCK :1;
+ __I uint32_t LOCK_INT_EN :1;
+ __I uint32_t UNLOCK_INT_EN :1;
+ __I uint32_t LOCK_INT :1;
+ __I uint32_t UNLOCK_INT :1;
+ __I uint32_t reserve11 :1;
+ __I uint32_t LOCK_B :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_REF_FB_MAIN register definition*/
+ __IO uint32_t PLL_REF_FB_MAIN;
+ struct
+ {
+ __I uint32_t FSE_B :1;
+ __I uint32_t FBCK_SEL :2;
+ __I uint32_t FOUTFB_SELMUX_EN :1;
+ __I uint32_t reserve12 :4;
+ __IO uint32_t RFDIV :6;
+ __I uint32_t reserve13 :2;
+ __I uint32_t reserve14 :12;
+ __I uint32_t reserve15 :4;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_REF_FB_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_FRACN_MAIN register definition*/
+ __IO uint32_t PLL_FRACN_MAIN;
+ struct
+ {
+ __I uint32_t FRACN_EN :1;
+ __I uint32_t FRACN_DAC_EN :1;
+ __I uint32_t reserve16 :6;
+ __I uint32_t reserve17 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_FRACN_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_DIV_0_1_MAIN register definition*/
+ __IO uint32_t PLL_DIV_0_1_MAIN;
+ struct
+ {
+ __I uint32_t VCO0PH_SEL :3;
+ __I uint32_t DIV0_START :3;
+ __I uint32_t reserve18 :2;
+ __IO uint32_t POST0DIV :7;
+ __I uint32_t reserve19 :1;
+ __I uint32_t VCO1PH_SEL :3;
+ __I uint32_t DIV1_START :3;
+ __I uint32_t reserve20 :2;
+ __IO uint32_t POST1DIV :7;
+ __I uint32_t reserve21 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_0_1_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_DIV_2_3_MAIN register definition*/
+ __IO uint32_t PLL_DIV_2_3_MAIN;
+ struct
+ {
+ __I uint32_t VCO2PH_SEL :3;
+ __I uint32_t DIV2_START :3;
+ __I uint32_t reserve22 :2;
+ __IO uint32_t POST2DIV :7;
+ __I uint32_t reserve23 :1;
+ __I uint32_t VCO3PH_SEL :3;
+ __I uint32_t DIV3_START :3;
+ __I uint32_t reserve24 :2;
+ __IO uint32_t POST3DIV :7;
+ __I uint32_t CKPOST3_SEL :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_2_3_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_CTRL2_MAIN register definition*/
+ __IO uint32_t PLL_CTRL2_MAIN;
+ struct
+ {
+ __IO uint32_t BWI :2;
+ __IO uint32_t BWP :2;
+ __I uint32_t IREF_EN :1;
+ __I uint32_t IREF_TOGGLE :1;
+ __I uint32_t reserve25 :3;
+ __I uint32_t LOCKCNT :4;
+ __I uint32_t reserve26 :4;
+ __I uint32_t ATEST_EN :1;
+ __I uint32_t ATEST_SEL :3;
+ __I uint32_t reserve27 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL2_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_CAL_MAIN register definition*/
+ __I uint32_t PLL_CAL_MAIN;
+ struct
+ {
+ __I uint32_t DSKEWCALCNT :3;
+ __I uint32_t DSKEWCAL_EN :1;
+ __I uint32_t DSKEWCALBYP :1;
+ __I uint32_t reserve28 :3;
+ __I uint32_t DSKEWCALIN :7;
+ __I uint32_t reserve29 :1;
+ __I uint32_t DSKEWCALOUT :7;
+ __I uint32_t reserve30 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CAL_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_PHADJ_MAIN register definition*/
+ __IO uint32_t PLL_PHADJ_MAIN;
+ struct
+ {
+ __I uint32_t PLL_REG_SYNCREFDIV_EN :1;
+ __I uint32_t PLL_REG_ENABLE_SYNCREFDIV :1;
+ __IO uint32_t REG_OUT0_PHSINIT :3;
+ __IO uint32_t REG_OUT1_PHSINIT :3;
+ __IO uint32_t REG_OUT2_PHSINIT :3;
+ __IO uint32_t REG_OUT3_PHSINIT :3;
+ __IO uint32_t REG_LOADPHS_B :1;
+ __I uint32_t reserve31 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_PHADJ_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_0_MAIN register definition*/
+ __IO uint32_t SSCG_REG_0_MAIN; /* todo: verify should be r/w, it is not in source file from Duolog */
+ struct
+ {
+ __I uint32_t DIVVAL :6;
+ __I uint32_t FRACIN :24;
+ __I uint32_t reserve00 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_0_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_1_MAIN register definition*/
+ __I uint32_t SSCG_REG_1_MAIN;
+ struct
+ {
+ __I uint32_t DOWNSPREAD :1;
+ __I uint32_t SSMD :5;
+ __I uint32_t FRACMOD :24;
+ __I uint32_t reserve01 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_1_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_2_MAIN register definition*/
+ __IO uint32_t SSCG_REG_2_MAIN;
+ struct
+ {
+ __IO uint32_t INTIN :12;
+ __I uint32_t INTMOD :12;
+ __I uint32_t reserve02 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_2_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_3_MAIN register definition*/
+ __IO uint32_t SSCG_REG_3_MAIN; /* todo: verify if should be __IO */
+ struct
+ {
+ __I uint32_t SSE_B :1;
+ __I uint32_t SEL_EXTWAVE :2;
+ __I uint32_t EXT_MAXADDR :8;
+ __I uint32_t TBLADDR :8;
+ __I uint32_t RANDOM_FILTER :1;
+ __I uint32_t RANDOM_SEL :2;
+ __I uint32_t reserve03 :1;
+ __I uint32_t reserve04 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_3_MAIN_TypeDef;
+
+typedef union{ /*!< RPC_RESET_MAIN_PLL register definition*/
+ __IO uint32_t RPC_RESET_MAIN_PLL;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_MAIN_PLL :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_MAIN_PLL_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_IOSCB_PLL register definition*/
+ __IO uint32_t SOFT_RESET_IOSCB_PLL;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_NV_MAP_IOSCB_PLL_TypeDef NV_MAP_IOSCB_PLL :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_V_MAP_IOSCB_PLL_TypeDef V_MAP_IOSCB_PLL :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_PERIPH_IOSCB_PLL_TypeDef PERIPH_IOSCB_PLL :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_BLOCKID_IOSCB_PLL_TypeDef BLOCKID_IOSCB_PLL :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_TypeDef;
+
+typedef union{ /*!< PLL_CTRL_IOSCB register definition*/
+ __IO uint32_t PLL_CTRL_IOSCB;
+ struct
+ {
+ __IO uint32_t REG_POWERDOWN_B :1;
+ __IO uint32_t REG_RFDIV_EN :1;
+ __IO uint32_t REG_DIVQ0_EN :1;
+ __IO uint32_t REG_DIVQ1_EN :1;
+ __IO uint32_t REG_DIVQ2_EN :1;
+ __IO uint32_t REG_DIVQ3_EN :1;
+ __IO uint32_t REG_RFCLK_SEL :1;
+ __I uint32_t RESETONLOCK :1;
+ __I uint32_t BYPCK_SEL :4;
+ __I uint32_t REG_BYPASS_GO_B :1;
+ __I uint32_t reserve10 :3;
+ __I uint32_t REG_BYPASSPRE :4;
+ __I uint32_t REG_BYPASSPOST :4;
+ __IO uint32_t LP_REQUIRES_LOCK :1;
+ __I uint32_t LOCK :1;
+ __I uint32_t LOCK_INT_EN :1;
+ __I uint32_t UNLOCK_INT_EN :1;
+ __I uint32_t LOCK_INT :1;
+ __I uint32_t UNLOCK_INT :1;
+ __I uint32_t reserve11 :1;
+ __I uint32_t LOCK_B :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_REF_FB_IOSCB register definition*/
+ __IO uint32_t PLL_REF_FB_IOSCB;
+ struct
+ {
+ __I uint32_t FSE_B :1;
+ __I uint32_t FBCK_SEL :2;
+ __I uint32_t FOUTFB_SELMUX_EN :1;
+ __I uint32_t reserve12 :4;
+ __IO uint32_t RFDIV :6;
+ __I uint32_t reserve13 :2;
+ __I uint32_t reserve14 :12;
+ __I uint32_t reserve15 :4;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_REF_FB_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_FRACN_IOSCB register definition*/
+ __I uint32_t PLL_FRACN_IOSCB;
+ struct
+ {
+ __I uint32_t FRACN_EN :1;
+ __I uint32_t FRACN_DAC_EN :1;
+ __I uint32_t reserve16 :6;
+ __I uint32_t reserve17 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_FRACN_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_DIV_0_1_IOSCB register definition*/
+ __IO uint32_t PLL_DIV_0_1_IOSCB;
+ struct
+ {
+ __I uint32_t VCO0PH_SEL :3;
+ __I uint32_t DIV0_START :3;
+ __I uint32_t reserve18 :2;
+ __IO uint32_t POST0DIV :7;
+ __I uint32_t reserve19 :1;
+ __I uint32_t VCO1PH_SEL :3;
+ __I uint32_t DIV1_START :3;
+ __I uint32_t reserve20 :2;
+ __IO uint32_t POST1DIV :7;
+ __I uint32_t reserve21 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_0_1_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_DIV_2_3_IOSCB register definition*/
+ __IO uint32_t PLL_DIV_2_3_IOSCB;
+ struct
+ {
+ __I uint32_t VCO2PH_SEL :3;
+ __I uint32_t DIV2_START :3;
+ __I uint32_t reserve22 :2;
+ __IO uint32_t POST2DIV :7;
+ __I uint32_t reserve23 :1;
+ __I uint32_t VCO3PH_SEL :3;
+ __I uint32_t DIV3_START :3;
+ __I uint32_t reserve24 :2;
+ __IO uint32_t POST3DIV :7;
+ __I uint32_t CKPOST3_SEL :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_2_3_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_CTRL2_IOSCB register definition*/
+ __IO uint32_t PLL_CTRL2_IOSCB;
+ struct
+ {
+ __IO uint32_t BWI :2;
+ __IO uint32_t BWP :2;
+ __I uint32_t IREF_EN :1;
+ __I uint32_t IREF_TOGGLE :1;
+ __I uint32_t reserve25 :3;
+ __I uint32_t LOCKCNT :4;
+ __I uint32_t reserve26 :4;
+ __I uint32_t ATEST_EN :1;
+ __I uint32_t ATEST_SEL :3;
+ __I uint32_t reserve27 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL2_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_CAL_IOSCB register definition*/
+ __I uint32_t PLL_CAL_IOSCB;
+ struct
+ {
+ __I uint32_t DSKEWCALCNT :3;
+ __I uint32_t DSKEWCAL_EN :1;
+ __I uint32_t DSKEWCALBYP :1;
+ __I uint32_t reserve28 :3;
+ __I uint32_t DSKEWCALIN :7;
+ __I uint32_t reserve29 :1;
+ __I uint32_t DSKEWCALOUT :7;
+ __I uint32_t reserve30 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CAL_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_PHADJ_IOSCB register definition*/
+ __IO uint32_t PLL_PHADJ_IOSCB;
+ struct
+ {
+ __I uint32_t PLL_REG_SYNCREFDIV_EN :1;
+ __I uint32_t PLL_REG_ENABLE_SYNCREFDIV :1;
+ __IO uint32_t REG_OUT0_PHSINIT :3;
+ __IO uint32_t REG_OUT1_PHSINIT :3;
+ __IO uint32_t REG_OUT2_PHSINIT :3;
+ __IO uint32_t REG_OUT3_PHSINIT :3;
+ __IO uint32_t REG_LOADPHS_B :1;
+ __I uint32_t reserve31 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_PHADJ_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_0_IOSCB register definition*/
+ __I uint32_t SSCG_REG_0_IOSCB;
+ struct
+ {
+ __I uint32_t DIVVAL :6;
+ __I uint32_t FRACIN :24;
+ __I uint32_t reserve00 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_0_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_1_IOSCB register definition*/
+ __I uint32_t SSCG_REG_1_IOSCB;
+ struct
+ {
+ __I uint32_t DOWNSPREAD :1;
+ __I uint32_t SSMD :5;
+ __I uint32_t FRACMOD :24;
+ __I uint32_t reserve01 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_1_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_2_IOSCB register definition*/
+ __IO uint32_t SSCG_REG_2_IOSCB;
+ struct
+ {
+ __IO uint32_t INTIN :12;
+ __I uint32_t INTMOD :12;
+ __I uint32_t reserve02 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_2_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_3_IOSCB register definition*/
+ __I uint32_t SSCG_REG_3_IOSCB;
+ struct
+ {
+ __I uint32_t SSE_B :1;
+ __I uint32_t SEL_EXTWAVE :2;
+ __I uint32_t EXT_MAXADDR :8;
+ __I uint32_t TBLADDR :8;
+ __I uint32_t RANDOM_FILTER :1;
+ __I uint32_t RANDOM_SEL :2;
+ __I uint32_t reserve03 :1;
+ __I uint32_t reserve04 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_3_IOSCB_TypeDef;
+
+typedef union{ /*!< RPC_RESET_IOSCB register definition*/
+ __IO uint32_t RPC_RESET_IOSCB;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_IOSCB :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_IOSCB_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_BANK_CTRL register definition*/
+ __IO uint32_t SOFT_RESET_BANK_CTRL;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_NV_MAP_BANK_CTRL_TypeDef NV_MAP_BANK_CTRL :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_V_MAP_BANK_CTRL_TypeDef V_MAP_BANK_CTRL :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_PERIPH_BANK_CTRL_TypeDef PERIPH_BANK_CTRL :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_BLOCKID_BANK_CTRL_TypeDef BLOCKID_BANK_CTRL :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_TypeDef;
+
+typedef union{ /*!< DPC_BITS register definition*/
+ __IO uint32_t DPC_BITS;
+ struct
+ {
+ __IO uint32_t dpc_vs :4;
+ __IO uint32_t dpc_vrgen_h :6;
+ __IO uint32_t dpc_vrgen_en_h :1;
+ __IO uint32_t dpc_move_en_h :1;
+ __IO uint32_t dpc_vrgen_v :6;
+ __IO uint32_t dpc_vrgen_en_v :1;
+ __IO uint32_t dpc_move_en_v :1;
+ __I uint32_t reserve01 :12;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DPC_BITS_TypeDef;
+
+typedef union{ /*!< BANK_STATUS register definition*/
+ __I uint32_t BANK_STATUS;
+ struct
+ {
+ __I uint32_t sro_calib_status_b :1;
+ __I uint32_t sro_ioen_bnk_b :1;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_BANK_STATUS_TypeDef;
+
+typedef union{ /*!< RPC_RESET_BANK_CTRL register definition*/
+ __IO uint32_t RPC_RESET_BANK_CTRL;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_BANK_CTRL :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_BANK_CTRL_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_IOCALIB register definition*/
+ __IO uint32_t SOFT_RESET_IOCALIB;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_NV_MAP_IOCALIB_TypeDef NV_MAP_IOCALIB :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_V_MAP_IOCALIB_TypeDef V_MAP_IOCALIB :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_PERIPH_IOCALIB_TypeDef PERIPH_IOCALIB :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_BLOCKID_IOCALIB_TypeDef BLOCKID_IOCALIB :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_TypeDef;
+
+typedef union{ /*!< IOC_REG0 register definition*/
+ __IO uint32_t IOC_REG0;
+ struct
+ {
+ __IO uint32_t reg_pcode :6;
+ __IO uint32_t reg_ncode :6;
+ __I uint32_t reg_calib_trim :1;
+ __IO uint32_t reg_calib_start :1;
+ __IO uint32_t reg_calib_lock :1;
+ __I uint32_t reg_calib_load :1;
+ __I uint32_t reg_calib_direction :1;
+ __I uint32_t reg_calib_move_pcode :1;
+ __I uint32_t reg_calib_move_ncode :1;
+ __I uint32_t reserve01 :13;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG0_TypeDef;
+
+typedef union{ /*!< IOC_REG1 register definition*/
+ __I uint32_t IOC_REG1;
+ struct
+ {
+ __I uint32_t sro_code_done_p :1;
+ __I uint32_t sro_code_done_n :1;
+ __I uint32_t sro_calib_status :1;
+ __I uint32_t sro_calib_intrpt :1;
+ __I uint32_t sro_ioen_out :1;
+ __I uint32_t sro_power_on :1;
+ __I uint32_t sro_comp_sel :1;
+ __I uint32_t sro_comp_en :1;
+ __I uint32_t reserve02 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG1_TypeDef;
+
+typedef union{ /*!< IOC_REG2 register definition*/
+ __I uint32_t IOC_REG2;
+ struct
+ {
+ __I uint32_t sro_pcode :7;
+ __I uint32_t sro_ncode :7;
+ __I uint32_t sro_ref_pcode :7;
+ __I uint32_t sro_ref_ncode :7;
+ __I uint32_t sro_comp_out :1;
+ __I uint32_t reserve03 :3;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG2_TypeDef;
+
+typedef union{ /*!< IOC_REG3 register definition*/
+ __I uint32_t IOC_REG3;
+ struct
+ {
+ __I uint32_t reserve04 :5;
+ __I uint32_t reg_calib_poffset :6;
+ __I uint32_t reg_calib_poffset_dir :1;
+ __I uint32_t reg_calib_noffset :6;
+ __I uint32_t reg_calib_noffset_dir :1;
+ __I uint32_t reg_calib_move_slewr :1;
+ __I uint32_t reg_calib_move_slewf :1;
+ __I uint32_t reg_calib_roffset_dir :1;
+ __I uint32_t reg_calib_foffset_dir :1;
+ __I uint32_t reserve05 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG3_TypeDef;
+
+typedef union{ /*!< IOC_REG4 register definition*/
+ __I uint32_t IOC_REG4;
+ struct
+ {
+ __I uint32_t reg_roffset :6;
+ __I uint32_t reg_foffset :6;
+ __I uint32_t reg_slewr :6;
+ __I uint32_t reg_slewf :6;
+ __I uint32_t sro_slew_intrpt :1;
+ __I uint32_t sro_slew_status :1;
+ __I uint32_t sro_slew_comp_out :1;
+ __I uint32_t sro_slew_comp_en :1;
+ __I uint32_t sro_slew_comp_sel :1;
+ __I uint32_t sro_slew_ioen_out :1;
+ __I uint32_t sro_slew_power_on :1;
+ __I uint32_t reserve06 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG4_TypeDef;
+
+typedef union{ /*!< IOC_REG5 register definition*/
+ __I uint32_t IOC_REG5;
+ struct
+ {
+ __I uint32_t sro_ref_slewr :6;
+ __I uint32_t sro_ref_slewf :12;
+ __I uint32_t sro_slewr :6;
+ __I uint32_t sro_slewf :6;
+ __I uint32_t reserve07 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG5_TypeDef;
+
+typedef union{ /*!< IOC_REG6 register definition*/
+ __IO uint32_t IOC_REG6;
+ struct
+ {
+ __IO uint32_t reg_calib_reset :1;
+ __IO uint32_t reg_calib_clkdiv :2;
+ __I uint32_t reserve08 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG6_TypeDef;
+
+typedef union{ /*!< RPC_RESET_IOCALIB register definition*/
+ __IO uint32_t RPC_RESET_IOCALIB;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_IOCALIB :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_IOCALIB_TypeDef;
+
+typedef union{ /*!< rpc_calib register definition*/
+ __IO uint32_t rpc_calib;
+ struct
+ {
+ __IO uint32_t start_pvt :1;
+ __IO uint32_t lock_pvt :1;
+ __I uint32_t Reserved :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc_calib_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_CFM register definition*/
+ __IO uint32_t SOFT_RESET_CFM;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_NV_MAP_CFM_TypeDef NV_MAP_CFM :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_V_MAP_CFM_TypeDef V_MAP_CFM :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_PERIPH_CFM_TypeDef PERIPH_CFM :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_BLOCKID_CFM_TypeDef BLOCKID_CFM :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_TypeDef;
+
+typedef union{ /*!< BCLKMUX register definition*/
+ __IO uint32_t BCLKMUX;
+ struct
+ {
+ __IO uint32_t bclk0_sel :5;
+ __IO uint32_t bclk1_sel :5;
+ __IO uint32_t bclk2_sel :5;
+ __IO uint32_t bclk3_sel :5;
+ __IO uint32_t bclk4_sel :5;
+ __IO uint32_t bclk5_sel :5;
+ __I uint32_t reserve0 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_BCLKMUX_TypeDef;
+
+typedef union{ /*!< PLL_CKMUX register definition*/
+ __IO uint32_t PLL_CKMUX;
+ struct
+ {
+ __IO uint32_t clk_in_mac_tsu :2;
+ __IO uint32_t pll0_rfclk0_sel :2;
+ __IO uint32_t pll0_rfclk1_sel :2;
+ __IO uint32_t pll1_rfclk0_sel :2;
+ __IO uint32_t pll1_rfclk1_sel :2;
+ __IO uint32_t pll1_fdr_sel :5;
+ __I uint32_t reserve1 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CKMUX_TypeDef;
+
+typedef union{ /*!< MSSCLKMUX register definition*/
+ __IO uint32_t MSSCLKMUX;
+ struct
+ {
+ __IO uint32_t mssclk_mux_sel :2;
+ __IO uint32_t mssclk_mux_md :2;
+ __IO uint32_t clk_standby_sel :1;
+ __I uint32_t reserve2 :27;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_MSSCLKMUX_TypeDef;
+
+typedef union{ /*!< SPARE0 register definition*/
+ __IO uint32_t SPARE0;
+ struct
+ {
+ __IO uint32_t spare0 :32;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SPARE0_TypeDef;
+
+typedef union{ /*!< FMETER_ADDR register definition*/
+ __I uint32_t FMETER_ADDR;
+ struct
+ {
+ __I uint32_t addr10 :2;
+ __I uint32_t addr :4;
+ __I uint32_t reserve3 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_FMETER_ADDR_TypeDef;
+
+typedef union{ /*!< FMETER_DATAW register definition*/
+ __I uint32_t FMETER_DATAW;
+ struct
+ {
+ __I uint32_t data :24;
+ __I uint32_t strobe :1;
+ __I uint32_t reserve4 :7;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_FMETER_DATAW_TypeDef;
+
+typedef union{ /*!< FMETER_DATAR register definition*/
+ __I uint32_t FMETER_DATAR;
+ struct
+ {
+ __I uint32_t data :24;
+ __I uint32_t reserve5 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_FMETER_DATAR_TypeDef;
+
+typedef union{ /*!< TEST_CTRL register definition*/
+ __I uint32_t TEST_CTRL;
+ struct
+ {
+ __I uint32_t atest_en :1;
+ __I uint32_t atest_sel :5;
+ __I uint32_t dtest_en :1;
+ __I uint32_t dtest_sel :5;
+ __I uint32_t reserve6 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_TEST_CTRL_TypeDef;
+
+typedef union{ /*!< RPC_RESET_CFM register definition*/
+ __IO uint32_t RPC_RESET_CFM;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_CFM :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_CFM_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DECODER_DRIVER register definition*/
+ __IO uint32_t SOFT_RESET_DECODER_DRIVER;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_NV_MAP_DECODER_DRIVER_TypeDef NV_MAP_DECODER_DRIVER :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_V_MAP_DECODER_DRIVER_TypeDef V_MAP_DECODER_DRIVER :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_PERIPH_DECODER_DRIVER_TypeDef PERIPH_DECODER_DRIVER :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_BLOCKID_DECODER_DRIVER_TypeDef BLOCKID_DECODER_DRIVER :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_TypeDef;
+
+typedef union{ /*!< rpc1_DRV register definition*/
+ __IO uint32_t rpc1_DRV;
+ struct
+ {
+ __IO uint32_t drv_addcmd :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc1_DRV_TypeDef;
+
+typedef union{ /*!< rpc2_DRV register definition*/
+ __IO uint32_t rpc2_DRV;
+ struct
+ {
+ __IO uint32_t drv_clk :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc2_DRV_TypeDef;
+
+typedef union{ /*!< rpc3_DRV register definition*/
+ __IO uint32_t rpc3_DRV;
+ struct
+ {
+ __IO uint32_t drv_dq :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc3_DRV_TypeDef;
+
+typedef union{ /*!< rpc4_DRV register definition*/
+ __IO uint32_t rpc4_DRV;
+ struct
+ {
+ __IO uint32_t drv_dqs :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc4_DRV_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DECODER_ODT register definition*/
+ __IO uint32_t SOFT_RESET_DECODER_ODT;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_NV_MAP_DECODER_ODT_TypeDef NV_MAP_DECODER_ODT :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_V_MAP_DECODER_ODT_TypeDef V_MAP_DECODER_ODT :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_PERIPH_DECODER_ODT_TypeDef PERIPH_DECODER_ODT :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_BLOCKID_DECODER_ODT_TypeDef BLOCKID_DECODER_ODT :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_TypeDef;
+
+typedef union{ /*!< rpc1_ODT register definition*/
+ __IO uint32_t rpc1_ODT;
+ struct
+ {
+ __IO uint32_t odt_addcmd :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc1_ODT_TypeDef;
+
+typedef union{ /*!< rpc2_ODT register definition*/
+ __IO uint32_t rpc2_ODT;
+ struct
+ {
+ __IO uint32_t odt_clk :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc2_ODT_TypeDef;
+
+typedef union{ /*!< rpc3_ODT register definition*/
+ __IO uint32_t rpc3_ODT;
+ struct
+ {
+ __IO uint32_t odt_dq :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc3_ODT_TypeDef;
+
+typedef union{ /*!< rpc4_ODT register definition*/
+ __IO uint32_t rpc4_ODT;
+ struct
+ {
+ __IO uint32_t odt_dqs :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc4_ODT_TypeDef;
+
+typedef union{ /*!< rpc5_ODT register definition*/
+ __IO uint32_t rpc5_ODT;
+ struct
+ {
+ __IO uint32_t odt_dyn_sel_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc5_ODT_TypeDef;
+
+typedef union{ /*!< rpc6_ODT register definition*/
+ __IO uint32_t rpc6_ODT;
+ struct
+ {
+ __IO uint32_t odt_dyn_sel_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc6_ODT_TypeDef;
+
+typedef union{ /*!< rpc7_ODT register definition*/
+ __IO uint32_t rpc7_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc7_ODT_TypeDef;
+
+typedef union{ /*!< rpc8_ODT register definition*/
+ __IO uint32_t rpc8_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc8_ODT_TypeDef;
+
+typedef union{ /*!< rpc9_ODT register definition*/
+ __IO uint32_t rpc9_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc9_ODT_TypeDef;
+
+typedef union{ /*!< rpc10_ODT register definition*/
+ __IO uint32_t rpc10_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc10_ODT_TypeDef;
+
+typedef union{ /*!< rpc11_ODT register definition*/
+ __IO uint32_t rpc11_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_dqs :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc11_ODT_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DECODER_IO register definition*/
+ __IO uint32_t SOFT_RESET_DECODER_IO;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_NV_MAP_DECODER_IO_TypeDef NV_MAP_DECODER_IO :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_V_MAP_DECODER_IO_TypeDef V_MAP_DECODER_IO :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_PERIPH_DECODER_IO_TypeDef PERIPH_DECODER_IO :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_BLOCKID_DECODER_IO_TypeDef BLOCKID_DECODER_IO :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_TypeDef;
+
+typedef union{ /*!< ovrt1 register definition*/
+ __IO uint32_t ovrt1;
+ struct
+ {
+ __IO uint32_t drv_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt1_TypeDef;
+
+typedef union{ /*!< ovrt2 register definition*/
+ __IO uint32_t ovrt2;
+ struct
+ {
+ __IO uint32_t drv_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt2_TypeDef;
+
+typedef union{ /*!< ovrt3 register definition*/
+ __IO uint32_t ovrt3;
+ struct
+ {
+ __IO uint32_t drv_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt3_TypeDef;
+
+typedef union{ /*!< ovrt4 register definition*/
+ __IO uint32_t ovrt4;
+ struct
+ {
+ __IO uint32_t drv_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt4_TypeDef;
+
+typedef union{ /*!< ovrt5 register definition*/
+ __IO uint32_t ovrt5;
+ struct
+ {
+ __IO uint32_t drv_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt5_TypeDef;
+
+typedef union{ /*!< ovrt6 register definition*/
+ __IO uint32_t ovrt6;
+ struct
+ {
+ __IO uint32_t drv_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt6_TypeDef;
+
+typedef union{ /*!< ovrt7 register definition*/
+ __IO uint32_t ovrt7;
+ struct
+ {
+ __IO uint32_t drv_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt7_TypeDef;
+
+typedef union{ /*!< ovrt8 register definition*/
+ __IO uint32_t ovrt8;
+ struct
+ {
+ __IO uint32_t drv_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt8_TypeDef;
+
+typedef union{ /*!< ovrt9 register definition*/
+ __IO uint32_t ovrt9;
+ struct
+ {
+ __IO uint32_t en_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt9_TypeDef;
+
+typedef union{ /*!< ovrt10 register definition*/
+ __IO uint32_t ovrt10;
+ struct
+ {
+ __IO uint32_t en_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt10_TypeDef;
+
+typedef union{ /*!< ovrt11 register definition*/
+ __IO uint32_t ovrt11;
+ struct
+ {
+ __IO uint32_t en_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt11_TypeDef;
+
+typedef union{ /*!< ovrt12 register definition*/
+ __IO uint32_t ovrt12;
+ struct
+ {
+ __IO uint32_t en_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt12_TypeDef;
+
+typedef union{ /*!< ovrt13 register definition*/
+ __IO uint32_t ovrt13;
+ struct
+ {
+ __IO uint32_t en_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt13_TypeDef;
+
+typedef union{ /*!< ovrt14 register definition*/
+ __IO uint32_t ovrt14;
+ struct
+ {
+ __IO uint32_t en_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt14_TypeDef;
+
+typedef union{ /*!< ovrt15 register definition*/
+ __IO uint32_t ovrt15;
+ struct
+ {
+ __IO uint32_t en_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt15_TypeDef;
+
+typedef union{ /*!< ovrt16 register definition*/
+ __IO uint32_t ovrt16;
+ struct
+ {
+ __IO uint32_t en_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt16_TypeDef;
+
+typedef union{ /*!< rpc17 register definition*/
+ __IO uint32_t rpc17;
+ struct
+ {
+ __IO uint32_t bclk_sel_ac :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc17_TypeDef;
+
+typedef union{ /*!< rpc18 register definition*/
+ __IO uint32_t rpc18;
+ struct
+ {
+ __IO uint32_t bclk_sel_addcmd :9;
+ __I uint32_t reserved_01 :23;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc18_TypeDef;
+
+typedef union{ /*!< rpc19 register definition*/
+ __IO uint32_t rpc19;
+ struct
+ {
+ __IO uint32_t bclk_sel_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc19_TypeDef;
+
+typedef union{ /*!< rpc20 register definition*/
+ __IO uint32_t rpc20;
+ struct
+ {
+ __IO uint32_t bclk_sel_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc20_TypeDef;
+
+typedef union{ /*!< rpc21 register definition*/
+ __IO uint32_t rpc21;
+ struct
+ {
+ __IO uint32_t bclk_sel_data :9;
+ __I uint32_t reserved_01 :23;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc21_TypeDef;
+
+typedef union{ /*!< rpc22 register definition*/
+ __IO uint32_t rpc22;
+ struct
+ {
+ __IO uint32_t bclk_sel_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc22_TypeDef;
+
+typedef union{ /*!< rpc23 register definition*/
+ __IO uint32_t rpc23;
+ struct
+ {
+ __IO uint32_t bclk_sel_dqsn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc23_TypeDef;
+
+typedef union{ /*!< rpc24 register definition*/
+ __IO uint32_t rpc24;
+ struct
+ {
+ __IO uint32_t bclk_sel_dqsp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc24_TypeDef;
+
+typedef union{ /*!< rpc25 register definition*/
+ __IO uint32_t rpc25;
+ struct
+ {
+ __IO uint32_t cdr_md_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc25_TypeDef;
+
+typedef union{ /*!< rpc26 register definition*/
+ __IO uint32_t rpc26;
+ struct
+ {
+ __IO uint32_t cdr_md_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc26_TypeDef;
+
+typedef union{ /*!< rpc27 register definition*/
+ __IO uint32_t rpc27;
+ struct
+ {
+ __IO uint32_t clk_md_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc27_TypeDef;
+
+typedef union{ /*!< rpc28 register definition*/
+ __IO uint32_t rpc28;
+ struct
+ {
+ __IO uint32_t clk_sel_addcmd :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc28_TypeDef;
+
+typedef union{ /*!< rpc29 register definition*/
+ __IO uint32_t rpc29;
+ struct
+ {
+ __IO uint32_t clk_sel_data :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc29_TypeDef;
+
+typedef union{ /*!< rpc30 register definition*/
+ __IO uint32_t rpc30;
+ struct
+ {
+ __IO uint32_t code_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc30_TypeDef;
+
+typedef union{ /*!< rpc31 register definition*/
+ __IO uint32_t rpc31;
+ struct
+ {
+ __IO uint32_t code_sel_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc31_TypeDef;
+
+typedef union{ /*!< rpc32 register definition*/
+ __IO uint32_t rpc32;
+ struct
+ {
+ __IO uint32_t comp_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc32_TypeDef;
+
+typedef union{ /*!< rpc33 register definition*/
+ __IO uint32_t rpc33;
+ struct
+ {
+ __IO uint32_t comp_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc33_TypeDef;
+
+typedef union{ /*!< rpc34 register definition*/
+ __IO uint32_t rpc34;
+ struct
+ {
+ __IO uint32_t comp_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc34_TypeDef;
+
+typedef union{ /*!< rpc35 register definition*/
+ __IO uint32_t rpc35;
+ struct
+ {
+ __IO uint32_t comp_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc35_TypeDef;
+
+typedef union{ /*!< rpc36 register definition*/
+ __IO uint32_t rpc36;
+ struct
+ {
+ __IO uint32_t comp_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc36_TypeDef;
+
+typedef union{ /*!< rpc37 register definition*/
+ __IO uint32_t rpc37;
+ struct
+ {
+ __IO uint32_t comp_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc37_TypeDef;
+
+typedef union{ /*!< rpc38 register definition*/
+ __IO uint32_t rpc38;
+ struct
+ {
+ __IO uint32_t divclk_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc38_TypeDef;
+
+typedef union{ /*!< rpc39 register definition*/
+ __IO uint32_t rpc39;
+ struct
+ {
+ __IO uint32_t divclk_sel_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc39_TypeDef;
+
+typedef union{ /*!< rpc40 register definition*/
+ __IO uint32_t rpc40;
+ struct
+ {
+ __IO uint32_t div_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc40_TypeDef;
+
+typedef union{ /*!< rpc41 register definition*/
+ __IO uint32_t rpc41;
+ struct
+ {
+ __IO uint32_t div_data :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc41_TypeDef;
+
+typedef union{ /*!< rpc42 register definition*/
+ __IO uint32_t rpc42;
+ struct
+ {
+ __IO uint32_t dly_md_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc42_TypeDef;
+
+typedef union{ /*!< rpc43 register definition*/
+ __IO uint32_t rpc43;
+ struct
+ {
+ __IO uint32_t dly_md_clkn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc43_TypeDef;
+
+typedef union{ /*!< rpc44 register definition*/
+ __IO uint32_t rpc44;
+ struct
+ {
+ __IO uint32_t dly_md_clkp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc44_TypeDef;
+
+typedef union{ /*!< rpc45 register definition*/
+ __IO uint32_t rpc45;
+ struct
+ {
+ __IO uint32_t dly_md_dq :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc45_TypeDef;
+
+typedef union{ /*!< rpc46 register definition*/
+ __IO uint32_t rpc46;
+ struct
+ {
+ __IO uint32_t dly_md_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc46_TypeDef;
+
+typedef union{ /*!< rpc47 register definition*/
+ __IO uint32_t rpc47;
+ struct
+ {
+ __IO uint32_t dly_md_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc47_TypeDef;
+
+typedef union{ /*!< rpc48 register definition*/
+ __IO uint32_t rpc48;
+ struct
+ {
+ __IO uint32_t dqs_md_data :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc48_TypeDef;
+
+typedef union{ /*!< rpc49 register definition*/
+ __IO uint32_t rpc49;
+ struct
+ {
+ __IO uint32_t dynen_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc49_TypeDef;
+
+typedef union{ /*!< rpc50 register definition*/
+ __IO uint32_t rpc50;
+ struct
+ {
+ __IO uint32_t dynen_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc50_TypeDef;
+
+typedef union{ /*!< rpc51 register definition*/
+ __IO uint32_t rpc51;
+ struct
+ {
+ __IO uint32_t dynen_soft_reset_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc51_TypeDef;
+
+typedef union{ /*!< rpc52 register definition*/
+ __IO uint32_t rpc52;
+ struct
+ {
+ __IO uint32_t dynen_soft_reset_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc52_TypeDef;
+
+typedef union{ /*!< rpc53 register definition*/
+ __IO uint32_t rpc53;
+ struct
+ {
+ __IO uint32_t edgedet_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc53_TypeDef;
+
+typedef union{ /*!< rpc54 register definition*/
+ __IO uint32_t rpc54;
+ struct
+ {
+ __IO uint32_t edgedet_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc54_TypeDef;
+
+typedef union{ /*!< rpc55 register definition*/
+ __IO uint32_t rpc55;
+ struct
+ {
+ __IO uint32_t edgedet_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc55_TypeDef;
+
+typedef union{ /*!< rpc56 register definition*/
+ __IO uint32_t rpc56;
+ struct
+ {
+ __IO uint32_t edgedet_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc56_TypeDef;
+
+typedef union{ /*!< rpc57 register definition*/
+ __IO uint32_t rpc57;
+ struct
+ {
+ __IO uint32_t edgedet_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc57_TypeDef;
+
+typedef union{ /*!< rpc58 register definition*/
+ __IO uint32_t rpc58;
+ struct
+ {
+ __IO uint32_t edgedet_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc58_TypeDef;
+
+typedef union{ /*!< rpc59 register definition*/
+ __IO uint32_t rpc59;
+ struct
+ {
+ __IO uint32_t eyewidth_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc59_TypeDef;
+
+typedef union{ /*!< rpc60 register definition*/
+ __IO uint32_t rpc60;
+ struct
+ {
+ __IO uint32_t eyewidth_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc60_TypeDef;
+
+typedef union{ /*!< rpc61 register definition*/
+ __IO uint32_t rpc61;
+ struct
+ {
+ __IO uint32_t eyewidth_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc61_TypeDef;
+
+typedef union{ /*!< rpc62 register definition*/
+ __IO uint32_t rpc62;
+ struct
+ {
+ __IO uint32_t eyewidth_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc62_TypeDef;
+
+typedef union{ /*!< rpc63 register definition*/
+ __IO uint32_t rpc63;
+ struct
+ {
+ __IO uint32_t eyewidth_dqsn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc63_TypeDef;
+
+typedef union{ /*!< rpc64 register definition*/
+ __IO uint32_t rpc64;
+ struct
+ {
+ __IO uint32_t eyewidth_dqsp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc64_TypeDef;
+
+typedef union{ /*!< rpc65 register definition*/
+ __IO uint32_t rpc65;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc65_TypeDef;
+
+typedef union{ /*!< rpc66 register definition*/
+ __IO uint32_t rpc66;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc66_TypeDef;
+
+typedef union{ /*!< rpc67 register definition*/
+ __IO uint32_t rpc67;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc67_TypeDef;
+
+typedef union{ /*!< rpc68 register definition*/
+ __IO uint32_t rpc68;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc68_TypeDef;
+
+typedef union{ /*!< rpc69 register definition*/
+ __IO uint32_t rpc69;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc69_TypeDef;
+
+typedef union{ /*!< rpc70 register definition*/
+ __IO uint32_t rpc70;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc70_TypeDef;
+
+typedef union{ /*!< rpc71 register definition*/
+ __IO uint32_t rpc71;
+ struct
+ {
+ __IO uint32_t eye_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc71_TypeDef;
+
+typedef union{ /*!< rpc72 register definition*/
+ __IO uint32_t rpc72;
+ struct
+ {
+ __IO uint32_t eye_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc72_TypeDef;
+
+typedef union{ /*!< rpc73 register definition*/
+ __IO uint32_t rpc73;
+ struct
+ {
+ __IO uint32_t eye_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc73_TypeDef;
+
+typedef union{ /*!< rpc74 register definition*/
+ __IO uint32_t rpc74;
+ struct
+ {
+ __IO uint32_t eye_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc74_TypeDef;
+
+typedef union{ /*!< rpc75 register definition*/
+ __IO uint32_t rpc75;
+ struct
+ {
+ __IO uint32_t eye_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc75_TypeDef;
+
+typedef union{ /*!< rpc76 register definition*/
+ __IO uint32_t rpc76;
+ struct
+ {
+ __IO uint32_t eye_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc76_TypeDef;
+
+typedef union{ /*!< rpc77 register definition*/
+ __IO uint32_t rpc77;
+ struct
+ {
+ __IO uint32_t eye_sdr_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc77_TypeDef;
+
+typedef union{ /*!< rpc78 register definition*/
+ __IO uint32_t rpc78;
+ struct
+ {
+ __IO uint32_t eye_sdr_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc78_TypeDef;
+
+typedef union{ /*!< rpc79 register definition*/
+ __IO uint32_t rpc79;
+ struct
+ {
+ __IO uint32_t eye_sdr_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc79_TypeDef;
+
+typedef union{ /*!< rpc80 register definition*/
+ __IO uint32_t rpc80;
+ struct
+ {
+ __IO uint32_t eye_sdr_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc80_TypeDef;
+
+typedef union{ /*!< rpc81 register definition*/
+ __IO uint32_t rpc81;
+ struct
+ {
+ __IO uint32_t eye_sdr_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc81_TypeDef;
+
+typedef union{ /*!< rpc82 register definition*/
+ __IO uint32_t rpc82;
+ struct
+ {
+ __IO uint32_t eye_sdr_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc82_TypeDef;
+
+typedef union{ /*!< rpc83 register definition*/
+ __IO uint32_t rpc83;
+ struct
+ {
+ __IO uint32_t fifowe_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc83_TypeDef;
+
+typedef union{ /*!< rpc84 register definition*/
+ __IO uint32_t rpc84;
+ struct
+ {
+ __IO uint32_t fifowe_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc84_TypeDef;
+
+typedef union{ /*!< rpc85 register definition*/
+ __IO uint32_t rpc85;
+ struct
+ {
+ __IO uint32_t fifowe_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc85_TypeDef;
+
+typedef union{ /*!< rpc86 register definition*/
+ __IO uint32_t rpc86;
+ struct
+ {
+ __IO uint32_t fifowe_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc86_TypeDef;
+
+typedef union{ /*!< rpc87 register definition*/
+ __IO uint32_t rpc87;
+ struct
+ {
+ __IO uint32_t fifowe_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc87_TypeDef;
+
+typedef union{ /*!< rpc88 register definition*/
+ __IO uint32_t rpc88;
+ struct
+ {
+ __IO uint32_t fifowe_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc88_TypeDef;
+
+typedef union{ /*!< rpc89 register definition*/
+ __IO uint32_t rpc89;
+ struct
+ {
+ __IO uint32_t fifo_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc89_TypeDef;
+
+typedef union{ /*!< rpc90 register definition*/
+ __IO uint32_t rpc90;
+ struct
+ {
+ __IO uint32_t fifo_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc90_TypeDef;
+
+typedef union{ /*!< rpc91 register definition*/
+ __IO uint32_t rpc91;
+ struct
+ {
+ __IO uint32_t fifo_run_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc91_TypeDef;
+
+typedef union{ /*!< rpc92 register definition*/
+ __IO uint32_t rpc92;
+ struct
+ {
+ __IO uint32_t fifo_run_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc92_TypeDef;
+
+typedef union{ /*!< rpc93 register definition*/
+ __IO uint32_t rpc93;
+ struct
+ {
+ __IO uint32_t gsr_disable_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc93_TypeDef;
+
+typedef union{ /*!< rpc94 register definition*/
+ __IO uint32_t rpc94;
+ struct
+ {
+ __IO uint32_t gsr_disable_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc94_TypeDef;
+
+typedef union{ /*!< rpc95 register definition*/
+ __IO uint32_t rpc95;
+ struct
+ {
+ __IO uint32_t ibufmd_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc95_TypeDef;
+
+typedef union{ /*!< rpc96 register definition*/
+ __IO uint32_t rpc96;
+ struct
+ {
+ __IO uint32_t ibufmd_clk :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc96_TypeDef;
+
+typedef union{ /*!< rpc97 register definition*/
+ __IO uint32_t rpc97;
+ struct
+ {
+ __IO uint32_t ibufmd_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc97_TypeDef;
+
+typedef union{ /*!< rpc98 register definition*/
+ __IO uint32_t rpc98;
+ struct
+ {
+ __IO uint32_t ibufmd_dqs :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc98_TypeDef;
+
+typedef union{ /*!< rpc99 register definition*/
+ __IO uint32_t rpc99;
+ struct
+ {
+ __IO uint32_t indly_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc99_TypeDef;
+
+typedef union{ /*!< rpc100 register definition*/
+ __IO uint32_t rpc100;
+ struct
+ {
+ __IO uint32_t indly_sel_clkn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc100_TypeDef;
+
+typedef union{ /*!< rpc101 register definition*/
+ __IO uint32_t rpc101;
+ struct
+ {
+ __IO uint32_t indly_sel_clkp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc101_TypeDef;
+
+typedef union{ /*!< rpc102 register definition*/
+ __IO uint32_t rpc102;
+ struct
+ {
+ __IO uint32_t indly_sel_dq :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc102_TypeDef;
+
+typedef union{ /*!< rpc103 register definition*/
+ __IO uint32_t rpc103;
+ struct
+ {
+ __IO uint32_t indly_sel_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc103_TypeDef;
+
+typedef union{ /*!< rpc104 register definition*/
+ __IO uint32_t rpc104;
+ struct
+ {
+ __IO uint32_t indly_sel_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc104_TypeDef;
+
+typedef union{ /*!< rpc105 register definition*/
+ __IO uint32_t rpc105;
+ struct
+ {
+ __IO uint32_t lane_pvt_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc105_TypeDef;
+
+typedef union{ /*!< rpc106 register definition*/
+ __IO uint32_t rpc106;
+ struct
+ {
+ __IO uint32_t lane_pvt_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc106_TypeDef;
+
+typedef union{ /*!< rpc107 register definition*/
+ __IO uint32_t rpc107;
+ struct
+ {
+ __IO uint32_t lsr_disable_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc107_TypeDef;
+
+typedef union{ /*!< rpc108 register definition*/
+ __IO uint32_t rpc108;
+ struct
+ {
+ __IO uint32_t lsr_disable_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc108_TypeDef;
+
+typedef union{ /*!< rpc109 register definition*/
+ __IO uint32_t rpc109;
+ struct
+ {
+ __IO uint32_t lsr_disable_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc109_TypeDef;
+
+typedef union{ /*!< rpc110 register definition*/
+ __IO uint32_t rpc110;
+ struct
+ {
+ __IO uint32_t lsr_disable_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc110_TypeDef;
+
+typedef union{ /*!< rpc111 register definition*/
+ __IO uint32_t rpc111;
+ struct
+ {
+ __IO uint32_t lsr_disable_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc111_TypeDef;
+
+typedef union{ /*!< rpc112 register definition*/
+ __IO uint32_t rpc112;
+ struct
+ {
+ __IO uint32_t lsr_disable_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc112_TypeDef;
+
+typedef union{ /*!< rpc113 register definition*/
+ __IO uint32_t rpc113;
+ struct
+ {
+ __IO uint32_t mvdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc113_TypeDef;
+
+typedef union{ /*!< rpc114 register definition*/
+ __IO uint32_t rpc114;
+ struct
+ {
+ __IO uint32_t mvdly_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc114_TypeDef;
+
+typedef union{ /*!< rpc115 register definition*/
+ __IO uint32_t rpc115;
+ struct
+ {
+ __IO uint32_t mvdly_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc115_TypeDef;
+
+typedef union{ /*!< rpc116 register definition*/
+ __IO uint32_t rpc116;
+ struct
+ {
+ __IO uint32_t mvdly_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc116_TypeDef;
+
+typedef union{ /*!< rpc117 register definition*/
+ __IO uint32_t rpc117;
+ struct
+ {
+ __IO uint32_t mvdly_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc117_TypeDef;
+
+typedef union{ /*!< rpc118 register definition*/
+ __IO uint32_t rpc118;
+ struct
+ {
+ __IO uint32_t mvdly_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc118_TypeDef;
+
+typedef union{ /*!< rpc119 register definition*/
+ __IO uint32_t rpc119;
+ struct
+ {
+ __IO uint32_t oeclk_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc119_TypeDef;
+
+typedef union{ /*!< rpc120 register definition*/
+ __IO uint32_t rpc120;
+ struct
+ {
+ __IO uint32_t oeclk_inv_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc120_TypeDef;
+
+typedef union{ /*!< rpc121 register definition*/
+ __IO uint32_t rpc121;
+ struct
+ {
+ __IO uint32_t oeclk_inv_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc121_TypeDef;
+
+typedef union{ /*!< rpc122 register definition*/
+ __IO uint32_t rpc122;
+ struct
+ {
+ __IO uint32_t oeclk_inv_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc122_TypeDef;
+
+typedef union{ /*!< rpc123 register definition*/
+ __IO uint32_t rpc123;
+ struct
+ {
+ __IO uint32_t oeclk_inv_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc123_TypeDef;
+
+typedef union{ /*!< rpc124 register definition*/
+ __IO uint32_t rpc124;
+ struct
+ {
+ __IO uint32_t oeclk_inv_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc124_TypeDef;
+
+typedef union{ /*!< rpc125 register definition*/
+ __IO uint32_t rpc125;
+ struct
+ {
+ __IO uint32_t oe_md_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc125_TypeDef;
+
+typedef union{ /*!< rpc126 register definition*/
+ __IO uint32_t rpc126;
+ struct
+ {
+ __IO uint32_t oe_md_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc126_TypeDef;
+
+typedef union{ /*!< rpc127 register definition*/
+ __IO uint32_t rpc127;
+ struct
+ {
+ __IO uint32_t oe_md_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc127_TypeDef;
+
+typedef union{ /*!< rpc128 register definition*/
+ __IO uint32_t rpc128;
+ struct
+ {
+ __IO uint32_t oe_md_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc128_TypeDef;
+
+typedef union{ /*!< rpc129 register definition*/
+ __IO uint32_t rpc129;
+ struct
+ {
+ __IO uint32_t oe_md_dqsn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc129_TypeDef;
+
+typedef union{ /*!< rpc130 register definition*/
+ __IO uint32_t rpc130;
+ struct
+ {
+ __IO uint32_t oe_md_dqsp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc130_TypeDef;
+
+typedef union{ /*!< rpc131 register definition*/
+ __IO uint32_t rpc131;
+ struct
+ {
+ __IO uint32_t pause_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc131_TypeDef;
+
+typedef union{ /*!< rpc132 register definition*/
+ __IO uint32_t rpc132;
+ struct
+ {
+ __IO uint32_t pause_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc132_TypeDef;
+
+typedef union{ /*!< rpc133 register definition*/
+ __IO uint32_t rpc133;
+ struct
+ {
+ __IO uint32_t qdr_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc133_TypeDef;
+
+typedef union{ /*!< rpc134 register definition*/
+ __IO uint32_t rpc134;
+ struct
+ {
+ __IO uint32_t qdr_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc134_TypeDef;
+
+typedef union{ /*!< rpc135 register definition*/
+ __IO uint32_t rpc135;
+ struct
+ {
+ __IO uint32_t qdr_md_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc135_TypeDef;
+
+typedef union{ /*!< rpc136 register definition*/
+ __IO uint32_t rpc136;
+ struct
+ {
+ __IO uint32_t qdr_md_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc136_TypeDef;
+
+typedef union{ /*!< rpc137 register definition*/
+ __IO uint32_t rpc137;
+ struct
+ {
+ __IO uint32_t qdr_md_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc137_TypeDef;
+
+typedef union{ /*!< rpc138 register definition*/
+ __IO uint32_t rpc138;
+ struct
+ {
+ __IO uint32_t qdr_md_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc138_TypeDef;
+
+typedef union{ /*!< rpc139 register definition*/
+ __IO uint32_t rpc139;
+ struct
+ {
+ __IO uint32_t qdr_md_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc139_TypeDef;
+
+typedef union{ /*!< rpc140 register definition*/
+ __IO uint32_t rpc140;
+ struct
+ {
+ __IO uint32_t qdr_md_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc140_TypeDef;
+
+typedef union{ /*!< rpc141 register definition*/
+ __IO uint32_t rpc141;
+ struct
+ {
+ __IO uint32_t rank2_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc141_TypeDef;
+
+typedef union{ /*!< rpc142 register definition*/
+ __IO uint32_t rpc142;
+ struct
+ {
+ __IO uint32_t rank2_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc142_TypeDef;
+
+typedef union{ /*!< rpc143 register definition*/
+ __IO uint32_t rpc143;
+ struct
+ {
+ __IO uint32_t rst_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc143_TypeDef;
+
+typedef union{ /*!< rpc144 register definition*/
+ __IO uint32_t rpc144;
+ struct
+ {
+ __IO uint32_t rst_inv_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc144_TypeDef;
+
+typedef union{ /*!< rpc145 register definition*/
+ __IO uint32_t rpc145;
+ struct
+ {
+ __IO uint32_t rxdly_addcmd :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc145_TypeDef;
+
+typedef union{ /*!< rpc146 register definition*/
+ __IO uint32_t rpc146;
+ struct
+ {
+ __IO uint32_t rxdly_clkn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc146_TypeDef;
+
+typedef union{ /*!< rpc147 register definition*/
+ __IO uint32_t rpc147;
+ struct
+ {
+ __IO uint32_t rxdly_clkp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc147_TypeDef;
+
+typedef union{ /*!< rpc148 register definition*/
+ __IO uint32_t rpc148;
+ struct
+ {
+ __IO uint32_t rxdly_dir_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc148_TypeDef;
+
+typedef union{ /*!< rpc149 register definition*/
+ __IO uint32_t rpc149;
+ struct
+ {
+ __IO uint32_t rxdly_dir_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc149_TypeDef;
+
+typedef union{ /*!< rpc150 register definition*/
+ __IO uint32_t rpc150;
+ struct
+ {
+ __IO uint32_t rxdly_dq :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc150_TypeDef;
+
+typedef union{ /*!< rpc151 register definition*/
+ __IO uint32_t rpc151;
+ struct
+ {
+ __IO uint32_t rxdly_dqsn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc151_TypeDef;
+
+typedef union{ /*!< rpc152 register definition*/
+ __IO uint32_t rpc152;
+ struct
+ {
+ __IO uint32_t rxdly_dqsp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc152_TypeDef;
+
+typedef union{ /*!< rpc153 register definition*/
+ __IO uint32_t rpc153;
+ struct
+ {
+ __IO uint32_t rxdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc153_TypeDef;
+
+typedef union{ /*!< rpc154 register definition*/
+ __IO uint32_t rpc154;
+ struct
+ {
+ __IO uint32_t rxdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc154_TypeDef;
+
+typedef union{ /*!< rpc155 register definition*/
+ __IO uint32_t rpc155;
+ struct
+ {
+ __IO uint32_t rxdly_offset_addcmd :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc155_TypeDef;
+
+typedef union{ /*!< rpc156 register definition*/
+ __IO uint32_t rpc156;
+ struct
+ {
+ __IO uint32_t rxdly_offset_data :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc156_TypeDef;
+
+typedef union{ /*!< rpc157 register definition*/
+ __IO uint32_t rpc157;
+ struct
+ {
+ __IO uint32_t rxdly_wide_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc157_TypeDef;
+
+typedef union{ /*!< rpc158 register definition*/
+ __IO uint32_t rpc158;
+ struct
+ {
+ __IO uint32_t rxdly_wide_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc158_TypeDef;
+
+typedef union{ /*!< rpc159 register definition*/
+ __IO uint32_t rpc159;
+ struct
+ {
+ __IO uint32_t rxdly_wide_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc159_TypeDef;
+
+typedef union{ /*!< rpc160 register definition*/
+ __IO uint32_t rpc160;
+ struct
+ {
+ __IO uint32_t rxdly_wide_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc160_TypeDef;
+
+typedef union{ /*!< rpc161 register definition*/
+ __IO uint32_t rpc161;
+ struct
+ {
+ __IO uint32_t rxdly_wide_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc161_TypeDef;
+
+typedef union{ /*!< rpc162 register definition*/
+ __IO uint32_t rpc162;
+ struct
+ {
+ __IO uint32_t rxdly_wide_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc162_TypeDef;
+
+typedef union{ /*!< rpc163 register definition*/
+ __IO uint32_t rpc163;
+ struct
+ {
+ __IO uint32_t rxmvdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc163_TypeDef;
+
+typedef union{ /*!< rpc164 register definition*/
+ __IO uint32_t rpc164;
+ struct
+ {
+ __IO uint32_t rxmvdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc164_TypeDef;
+
+typedef union{ /*!< rpc165 register definition*/
+ __IO uint32_t rpc165;
+ struct
+ {
+ __IO uint32_t rxptr_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc165_TypeDef;
+
+typedef union{ /*!< rpc166 register definition*/
+ __IO uint32_t rpc166;
+ struct
+ {
+ __IO uint32_t rxptr_data :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc166_TypeDef;
+
+typedef union{ /*!< rpc167 register definition*/
+ __IO uint32_t rpc167;
+ struct
+ {
+ __IO uint32_t rx_md_addcmd :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc167_TypeDef;
+
+typedef union{ /*!< rpc168 register definition*/
+ __IO uint32_t rpc168;
+ struct
+ {
+ __IO uint32_t rx_md_clkn :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc168_TypeDef;
+
+typedef union{ /*!< rpc169 register definition*/
+ __IO uint32_t rpc169;
+ struct
+ {
+ __IO uint32_t rx_md_clkp :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc169_TypeDef;
+
+typedef union{ /*!< rpc170 register definition*/
+ __IO uint32_t rpc170;
+ struct
+ {
+ __IO uint32_t rx_md_dq :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc170_TypeDef;
+
+typedef union{ /*!< rpc171 register definition*/
+ __IO uint32_t rpc171;
+ struct
+ {
+ __IO uint32_t rx_md_dqsn :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc171_TypeDef;
+
+typedef union{ /*!< rpc172 register definition*/
+ __IO uint32_t rpc172;
+ struct
+ {
+ __IO uint32_t rx_md_dqsp :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc172_TypeDef;
+
+typedef union{ /*!< rpc173 register definition*/
+ __IO uint32_t rpc173;
+ struct
+ {
+ __IO uint32_t sclk0_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc173_TypeDef;
+
+typedef union{ /*!< rpc174 register definition*/
+ __IO uint32_t rpc174;
+ struct
+ {
+ __IO uint32_t sclk0_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc174_TypeDef;
+
+typedef union{ /*!< rpc175 register definition*/
+ __IO uint32_t rpc175;
+ struct
+ {
+ __IO uint32_t sclk0_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc175_TypeDef;
+
+typedef union{ /*!< rpc176 register definition*/
+ __IO uint32_t rpc176;
+ struct
+ {
+ __IO uint32_t sclk0_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc176_TypeDef;
+
+typedef union{ /*!< rpc177 register definition*/
+ __IO uint32_t rpc177;
+ struct
+ {
+ __IO uint32_t sclk0_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc177_TypeDef;
+
+typedef union{ /*!< rpc178 register definition*/
+ __IO uint32_t rpc178;
+ struct
+ {
+ __IO uint32_t sclk0_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc178_TypeDef;
+
+typedef union{ /*!< rpc179 register definition*/
+ __IO uint32_t rpc179;
+ struct
+ {
+ __IO uint32_t sclk0_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc179_TypeDef;
+
+typedef union{ /*!< rpc180 register definition*/
+ __IO uint32_t rpc180;
+ struct
+ {
+ __IO uint32_t sclk0_inv_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc180_TypeDef;
+
+typedef union{ /*!< rpc181 register definition*/
+ __IO uint32_t rpc181;
+ struct
+ {
+ __IO uint32_t sclk0_inv_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc181_TypeDef;
+
+typedef union{ /*!< rpc182 register definition*/
+ __IO uint32_t rpc182;
+ struct
+ {
+ __IO uint32_t sclk0_inv_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc182_TypeDef;
+
+typedef union{ /*!< rpc183 register definition*/
+ __IO uint32_t rpc183;
+ struct
+ {
+ __IO uint32_t sclk0_inv_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc183_TypeDef;
+
+typedef union{ /*!< rpc184 register definition*/
+ __IO uint32_t rpc184;
+ struct
+ {
+ __IO uint32_t sclk0_inv_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc184_TypeDef;
+
+typedef union{ /*!< rpc185 register definition*/
+ __IO uint32_t rpc185;
+ struct
+ {
+ __IO uint32_t sclk1_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc185_TypeDef;
+
+typedef union{ /*!< rpc186 register definition*/
+ __IO uint32_t rpc186;
+ struct
+ {
+ __IO uint32_t sclk1_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc186_TypeDef;
+
+typedef union{ /*!< rpc187 register definition*/
+ __IO uint32_t rpc187;
+ struct
+ {
+ __IO uint32_t sclk1_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc187_TypeDef;
+
+typedef union{ /*!< rpc188 register definition*/
+ __IO uint32_t rpc188;
+ struct
+ {
+ __IO uint32_t sclk1_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc188_TypeDef;
+
+typedef union{ /*!< rpc189 register definition*/
+ __IO uint32_t rpc189;
+ struct
+ {
+ __IO uint32_t sclk1_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc189_TypeDef;
+
+typedef union{ /*!< rpc190 register definition*/
+ __IO uint32_t rpc190;
+ struct
+ {
+ __IO uint32_t sclk1_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc190_TypeDef;
+
+typedef union{ /*!< rpc191 register definition*/
+ __IO uint32_t rpc191;
+ struct
+ {
+ __IO uint32_t sclk1_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc191_TypeDef;
+
+typedef union{ /*!< rpc192 register definition*/
+ __IO uint32_t rpc192;
+ struct
+ {
+ __IO uint32_t sclk1_inv_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc192_TypeDef;
+
+typedef union{ /*!< rpc193 register definition*/
+ __IO uint32_t rpc193;
+ struct
+ {
+ __IO uint32_t sclk1_inv_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc193_TypeDef;
+
+typedef union{ /*!< rpc194 register definition*/
+ __IO uint32_t rpc194;
+ struct
+ {
+ __IO uint32_t sclk1_inv_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc194_TypeDef;
+
+typedef union{ /*!< rpc195 register definition*/
+ __IO uint32_t rpc195;
+ struct
+ {
+ __IO uint32_t sclk1_inv_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc195_TypeDef;
+
+typedef union{ /*!< rpc196 register definition*/
+ __IO uint32_t rpc196;
+ struct
+ {
+ __IO uint32_t sclk1_inv_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc196_TypeDef;
+
+typedef union{ /*!< rpc197 register definition*/
+ __IO uint32_t rpc197;
+ struct
+ {
+ __IO uint32_t soft_reset_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc197_TypeDef;
+
+typedef union{ /*!< rpc198 register definition*/
+ __IO uint32_t rpc198;
+ struct
+ {
+ __IO uint32_t soft_reset_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc198_TypeDef;
+
+typedef union{ /*!< rpc199 register definition*/
+ __IO uint32_t rpc199;
+ struct
+ {
+ __IO uint32_t spare_iog_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc199_TypeDef;
+
+typedef union{ /*!< rpc200 register definition*/
+ __IO uint32_t rpc200;
+ struct
+ {
+ __IO uint32_t spare_iog_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc200_TypeDef;
+
+typedef union{ /*!< rpc201 register definition*/
+ __IO uint32_t rpc201;
+ struct
+ {
+ __IO uint32_t spare_iog_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc201_TypeDef;
+
+typedef union{ /*!< rpc202 register definition*/
+ __IO uint32_t rpc202;
+ struct
+ {
+ __IO uint32_t spare_iog_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc202_TypeDef;
+
+typedef union{ /*!< rpc203 register definition*/
+ __IO uint32_t rpc203;
+ struct
+ {
+ __IO uint32_t spare_iog_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc203_TypeDef;
+
+typedef union{ /*!< rpc204 register definition*/
+ __IO uint32_t rpc204;
+ struct
+ {
+ __IO uint32_t spare_iog_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc204_TypeDef;
+
+typedef union{ /*!< rpc205 register definition*/
+ __IO uint32_t rpc205;
+ struct
+ {
+ __IO uint32_t spio_sel_di_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc205_TypeDef;
+
+typedef union{ /*!< rpc206 register definition*/
+ __IO uint32_t rpc206;
+ struct
+ {
+ __IO uint32_t spio_sel_di_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc206_TypeDef;
+
+typedef union{ /*!< rpc207 register definition*/
+ __IO uint32_t rpc207;
+ struct
+ {
+ __IO uint32_t stop_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc207_TypeDef;
+
+typedef union{ /*!< rpc208 register definition*/
+ __IO uint32_t rpc208;
+ struct
+ {
+ __IO uint32_t stop_sel_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc208_TypeDef;
+
+typedef union{ /*!< rpc209 register definition*/
+ __IO uint32_t rpc209;
+ struct
+ {
+ __IO uint32_t txclk_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc209_TypeDef;
+
+typedef union{ /*!< rpc210 register definition*/
+ __IO uint32_t rpc210;
+ struct
+ {
+ __IO uint32_t txclk_sel_clkn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc210_TypeDef;
+
+typedef union{ /*!< rpc211 register definition*/
+ __IO uint32_t rpc211;
+ struct
+ {
+ __IO uint32_t txclk_sel_clkp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc211_TypeDef;
+
+typedef union{ /*!< rpc212 register definition*/
+ __IO uint32_t rpc212;
+ struct
+ {
+ __IO uint32_t txclk_sel_dq :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc212_TypeDef;
+
+typedef union{ /*!< rpc213 register definition*/
+ __IO uint32_t rpc213;
+ struct
+ {
+ __IO uint32_t txclk_sel_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc213_TypeDef;
+
+typedef union{ /*!< rpc214 register definition*/
+ __IO uint32_t rpc214;
+ struct
+ {
+ __IO uint32_t txclk_sel_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc214_TypeDef;
+
+typedef union{ /*!< rpc215 register definition*/
+ __IO uint32_t rpc215;
+ struct
+ {
+ __IO uint32_t txdly_addcmd :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc215_TypeDef;
+
+typedef union{ /*!< rpc216 register definition*/
+ __IO uint32_t rpc216;
+ struct
+ {
+ __IO uint32_t txdly_clkn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc216_TypeDef;
+
+typedef union{ /*!< rpc217 register definition*/
+ __IO uint32_t rpc217;
+ struct
+ {
+ __IO uint32_t txdly_clkp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc217_TypeDef;
+
+typedef union{ /*!< rpc218 register definition*/
+ __IO uint32_t rpc218;
+ struct
+ {
+ __IO uint32_t txdly_dir_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc218_TypeDef;
+
+typedef union{ /*!< rpc219 register definition*/
+ __IO uint32_t rpc219;
+ struct
+ {
+ __IO uint32_t txdly_dir_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc219_TypeDef;
+
+typedef union{ /*!< rpc220 register definition*/
+ __IO uint32_t rpc220;
+ struct
+ {
+ __IO uint32_t txdly_dq :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc220_TypeDef;
+
+typedef union{ /*!< rpc221 register definition*/
+ __IO uint32_t rpc221;
+ struct
+ {
+ __IO uint32_t txdly_dqsn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc221_TypeDef;
+
+typedef union{ /*!< rpc222 register definition*/
+ __IO uint32_t rpc222;
+ struct
+ {
+ __IO uint32_t txdly_dqsp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc222_TypeDef;
+
+typedef union{ /*!< rpc223 register definition*/
+ __IO uint32_t rpc223;
+ struct
+ {
+ __IO uint32_t txdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc223_TypeDef;
+
+typedef union{ /*!< rpc224 register definition*/
+ __IO uint32_t rpc224;
+ struct
+ {
+ __IO uint32_t txdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc224_TypeDef;
+
+typedef union{ /*!< rpc225 register definition*/
+ __IO uint32_t rpc225;
+ struct
+ {
+ __IO uint32_t txdly_offset_addcmd :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc225_TypeDef;
+
+typedef union{ /*!< rpc226 register definition*/
+ __IO uint32_t rpc226;
+ struct
+ {
+ __IO uint32_t txdly_offset_data :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc226_TypeDef;
+
+typedef union{ /*!< rpc227 register definition*/
+ __IO uint32_t rpc227;
+ struct
+ {
+ __IO uint32_t txmvdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc227_TypeDef;
+
+typedef union{ /*!< rpc228 register definition*/
+ __IO uint32_t rpc228;
+ struct
+ {
+ __IO uint32_t txmvdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc228_TypeDef;
+
+typedef union{ /*!< rpc229 register definition*/
+ __IO uint32_t rpc229;
+ struct
+ {
+ __IO uint32_t tx_md_addcmd :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc229_TypeDef;
+
+typedef union{ /*!< rpc230 register definition*/
+ __IO uint32_t rpc230;
+ struct
+ {
+ __IO uint32_t tx_md_clkn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc230_TypeDef;
+
+typedef union{ /*!< rpc231 register definition*/
+ __IO uint32_t rpc231;
+ struct
+ {
+ __IO uint32_t tx_md_clkp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc231_TypeDef;
+
+typedef union{ /*!< rpc232 register definition*/
+ __IO uint32_t rpc232;
+ struct
+ {
+ __IO uint32_t tx_md_dq :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc232_TypeDef;
+
+typedef union{ /*!< rpc233 register definition*/
+ __IO uint32_t rpc233;
+ struct
+ {
+ __IO uint32_t tx_md_dqsn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc233_TypeDef;
+
+typedef union{ /*!< rpc234 register definition*/
+ __IO uint32_t rpc234;
+ struct
+ {
+ __IO uint32_t tx_md_dqsp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc234_TypeDef;
+
+typedef union{ /*!< rpc235 register definition*/
+ __IO uint32_t rpc235;
+ struct
+ {
+ __IO uint32_t wpd_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc235_TypeDef;
+
+typedef union{ /*!< rpc236 register definition*/
+ __IO uint32_t rpc236;
+ struct
+ {
+ __IO uint32_t wpd_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc236_TypeDef;
+
+typedef union{ /*!< rpc237 register definition*/
+ __IO uint32_t rpc237;
+ struct
+ {
+ __IO uint32_t wpd_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc237_TypeDef;
+
+typedef union{ /*!< rpc238 register definition*/
+ __IO uint32_t rpc238;
+ struct
+ {
+ __IO uint32_t wpd_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc238_TypeDef;
+
+typedef union{ /*!< rpc239 register definition*/
+ __IO uint32_t rpc239;
+ struct
+ {
+ __IO uint32_t wpd_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc239_TypeDef;
+
+typedef union{ /*!< rpc240 register definition*/
+ __IO uint32_t rpc240;
+ struct
+ {
+ __IO uint32_t wpd_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc240_TypeDef;
+
+typedef union{ /*!< rpc241 register definition*/
+ __IO uint32_t rpc241;
+ struct
+ {
+ __IO uint32_t wpd_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc241_TypeDef;
+
+typedef union{ /*!< rpc242 register definition*/
+ __IO uint32_t rpc242;
+ struct
+ {
+ __IO uint32_t wpd_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc242_TypeDef;
+
+typedef union{ /*!< rpc243 register definition*/
+ __IO uint32_t rpc243;
+ struct
+ {
+ __IO uint32_t wpu_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc243_TypeDef;
+
+typedef union{ /*!< rpc244 register definition*/
+ __IO uint32_t rpc244;
+ struct
+ {
+ __IO uint32_t wpu_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc244_TypeDef;
+
+typedef union{ /*!< rpc245 register definition*/
+ __IO uint32_t rpc245;
+ struct
+ {
+ __IO uint32_t wpu_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc245_TypeDef;
+
+typedef union{ /*!< rpc246 register definition*/
+ __IO uint32_t rpc246;
+ struct
+ {
+ __IO uint32_t wpu_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc246_TypeDef;
+
+typedef union{ /*!< rpc247 register definition*/
+ __IO uint32_t rpc247;
+ struct
+ {
+ __IO uint32_t wpu_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc247_TypeDef;
+
+typedef union{ /*!< rpc248 register definition*/
+ __IO uint32_t rpc248;
+ struct
+ {
+ __IO uint32_t wpu_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc248_TypeDef;
+
+typedef union{ /*!< rpc249 register definition*/
+ __IO uint32_t rpc249;
+ struct
+ {
+ __IO uint32_t wpu_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc249_TypeDef;
+
+typedef union{ /*!< rpc250 register definition*/
+ __IO uint32_t rpc250;
+ struct
+ {
+ __IO uint32_t wpu_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc250_TypeDef;
+
+typedef union{ /*!< spio251 register definition*/
+ __IO uint32_t spio251;
+ struct
+ {
+ __IO uint32_t sel_refclk0 :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_spio251_TypeDef;
+
+typedef union{ /*!< spio252 register definition*/
+ __IO uint32_t spio252;
+ struct
+ {
+ __IO uint32_t sel_refclk1 :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_spio252_TypeDef;
+
+typedef union{ /*!< spio253 register definition*/
+ __IO uint32_t spio253;
+ struct
+ {
+ __IO uint32_t sel_refclk2 :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_spio253_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_TIP register definition*/
+ __IO uint32_t SOFT_RESET_TIP;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_NV_MAP_TIP_TypeDef NV_MAP_TIP :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_V_MAP_TIP_TypeDef V_MAP_TIP :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_PERIPH_TIP_TypeDef PERIPH_TIP :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t BLOCKID_TIP :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_TypeDef;
+
+typedef union{ /*!< rank_select register definition*/
+ __IO uint32_t rank_select;
+ struct
+ {
+ __IO uint32_t rank :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rank_select_TypeDef;
+
+typedef union{ /*!< lane_select register definition*/
+ __IO uint32_t lane_select;
+ struct
+ {
+ __IO uint32_t lane :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_lane_select_TypeDef;
+
+typedef union{ /*!< training_skip register definition*/
+ __IO uint32_t training_skip;
+ struct
+ {
+ __IO uint32_t skip_bclksclk :1;
+ __IO uint32_t skip_addcmd :1;
+ __IO uint32_t skip_wrlvl :1;
+ __IO uint32_t skip_rdgate :1;
+ __IO uint32_t skip_dq_dqs_opt :1;
+ __IO uint32_t skip_write_calibration :1;
+ __IO uint32_t skip_vref_mr6 :1;
+ __IO uint32_t step7 :1;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_skip_TypeDef;
+
+typedef union{ /*!< training_start register definition*/
+ __IO uint32_t training_start;
+ struct
+ {
+ __IO uint32_t start :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_start_TypeDef;
+
+typedef union{ /*!< training_status register definition*/
+ __I uint32_t training_status;
+ struct
+ {
+ __I uint32_t status :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_status_TypeDef;
+
+typedef union{ /*!< training_reset register definition*/
+ __IO uint32_t training_reset;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_reset_TypeDef;
+
+typedef union{ /*!< gt_err_comb register definition*/
+ __I uint32_t gt_err_comb;
+ struct
+ {
+ __I uint32_t error_comb_lanex :6;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_err_comb_TypeDef;
+
+typedef union{ /*!< gt_clk_sel register definition*/
+ __I uint32_t gt_clk_sel;
+ struct
+ {
+ __I uint32_t clk_sel_lanex_rankx :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_clk_sel_TypeDef;
+
+typedef union{ /*!< gt_txdly register definition*/
+ __I uint32_t gt_txdly;
+ struct
+ {
+ __I uint32_t txdly0_lanex :8;
+ __I uint32_t txdly1_lanex :8;
+ __I uint32_t txdly2_lanex :8;
+ __I uint32_t txdly3_lanex :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_txdly_TypeDef;
+
+typedef union{ /*!< gt_steps_180 register definition*/
+ __I uint32_t gt_steps_180;
+ struct
+ {
+ __I uint32_t steps_180_lanex_rankx :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_steps_180_TypeDef;
+
+typedef union{ /*!< gt_state register definition*/
+ __I uint32_t gt_state;
+ struct
+ {
+ __I uint32_t gt_state_lanex :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_state_TypeDef;
+
+typedef union{ /*!< wl_delay_0 register definition*/
+ __I uint32_t wl_delay_0;
+ struct
+ {
+ __I uint32_t wldelay_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_wl_delay_0_TypeDef;
+
+typedef union{ /*!< dq_dqs_err_done register definition*/
+ __I uint32_t dq_dqs_err_done;
+ struct
+ {
+ __I uint32_t dq_dqs_error_done_lanex_rankx :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dq_dqs_err_done_TypeDef;
+
+typedef union{ /*!< dqdqs_window register definition*/
+ __I uint32_t dqdqs_window;
+ struct
+ {
+ __I uint32_t ils_lanex_rankx :8;
+ __I uint32_t irs_lanex_rankx :8;
+ __I uint32_t reserved_01 :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_window_TypeDef;
+
+typedef union{ /*!< dqdqs_state register definition*/
+ __I uint32_t dqdqs_state;
+ struct
+ {
+ __I uint32_t state_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_state_TypeDef;
+
+typedef union{ /*!< delta0 register definition*/
+ __I uint32_t delta0;
+ struct
+ {
+ __I uint32_t delay0_lanex :8;
+ __I uint32_t delay1_lanex :8;
+ __I uint32_t delay2_lanex :8;
+ __I uint32_t delay3_lanex :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_delta0_TypeDef;
+
+typedef union{ /*!< delta1 register definition*/
+ __I uint32_t delta1;
+ struct
+ {
+ __I uint32_t delay4_lanex :8;
+ __I uint32_t delay5_lanex :8;
+ __I uint32_t delay6_lanex :8;
+ __I uint32_t delay7_lanex :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_delta1_TypeDef;
+
+typedef union{ /*!< dqdqs_status0 register definition*/
+ __I uint32_t dqdqs_status0;
+ struct
+ {
+ __I uint32_t init_dly_lanex :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status0_TypeDef;
+
+typedef union{ /*!< dqdqs_status1 register definition*/
+ __I uint32_t dqdqs_status1;
+ struct
+ {
+ __I uint32_t dqs_dly_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status1_TypeDef;
+
+typedef union{ /*!< dqdqs_status2 register definition*/
+ __I uint32_t dqdqs_status2;
+ struct
+ {
+ __I uint32_t bit_width_lanex :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status2_TypeDef;
+
+typedef union{ /*!< dqdqs_status3 register definition*/
+ __I uint32_t dqdqs_status3;
+ struct
+ {
+ __I uint32_t initldqs_2_mid_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status3_TypeDef;
+
+typedef union{ /*!< dqdqs_status4 register definition*/
+ __I uint32_t dqdqs_status4;
+ struct
+ {
+ __I uint32_t mid_2_initldqs_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status4_TypeDef;
+
+typedef union{ /*!< dqdqs_status5 register definition*/
+ __I uint32_t dqdqs_status5;
+ struct
+ {
+ __I uint32_t stw_2_initldqs_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status5_TypeDef;
+
+typedef union{ /*!< dqdqs_status6 register definition*/
+ __I uint32_t dqdqs_status6;
+ struct
+ {
+ __I uint32_t initldqs_2_stw_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status6_TypeDef;
+
+typedef union{ /*!< addcmd_status0 register definition*/
+ __I uint32_t addcmd_status0;
+ struct
+ {
+ __I uint32_t delay_vcophs_sel0 :8;
+ __I uint32_t delay_vcophs_sel1 :8;
+ __I uint32_t delay_vcophs_sel2 :8;
+ __I uint32_t delay_vcophs_sel3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_addcmd_status0_TypeDef;
+
+typedef union{ /*!< addcmd_status1 register definition*/
+ __I uint32_t addcmd_status1;
+ struct
+ {
+ __I uint32_t delay_vcophs_sel4 :8;
+ __I uint32_t delay_vcophs_sel5 :8;
+ __I uint32_t delay_vcophs_sel6 :8;
+ __I uint32_t delay_vcophs_sel7 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_addcmd_status1_TypeDef;
+
+typedef union{ /*!< addcmd_answer register definition*/
+ __I uint32_t addcmd_answer;
+ struct
+ {
+ __I uint32_t vcophs_sel_after_training :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_addcmd_answer_TypeDef;
+
+typedef union{ /*!< bclksclk_answer register definition*/
+ __I uint32_t bclksclk_answer;
+ struct
+ {
+ __I uint32_t bclk0_vcophs_sel :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_bclksclk_answer_TypeDef;
+
+typedef union{ /*!< dqdqs_wrcalib_offset register definition*/
+ __I uint32_t dqdqs_wrcalib_offset;
+ struct
+ {
+ __I uint32_t wrcalib_offset_lanex :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_wrcalib_offset_TypeDef;
+
+typedef union{ /*!< expert_mode_en register definition*/
+ __IO uint32_t expert_mode_en;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_en :1;
+ __IO uint32_t dyn_ovr_pllcnt_en :1;
+ __IO uint32_t dyn_ovr_rdgate_en :1;
+ __IO uint32_t dyn_ovr_wrcalib_en :1;
+ __IO uint32_t dyn_ovr_calif_en :1;
+ __IO uint32_t dyn_ovr_dfi_shim_en :1;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_mode_en_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_move_reg0 register definition*/
+ __IO uint32_t expert_dlycnt_move_reg0;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_move0 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_move1 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_move2 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_move3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_move_reg1 register definition*/
+ __IO uint32_t expert_dlycnt_move_reg1;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_move4 :4;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_catrn_move :1;
+ __IO uint32_t dyn_ovr_dlycnt_ca_move :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_direction_reg0 register definition*/
+ __IO uint32_t expert_dlycnt_direction_reg0;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction0 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction1 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction2 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_direction_reg1 register definition*/
+ __IO uint32_t expert_dlycnt_direction_reg1;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction4 :4;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_catrn_direction :1;
+ __IO uint32_t dyn_ovr_dlycnt_ca_direction :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_load_reg0 register definition*/
+ __IO uint32_t expert_dlycnt_load_reg0;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_load0 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_load1 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_load2 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_load3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_load_reg1 register definition*/
+ __IO uint32_t expert_dlycnt_load_reg1;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_load4 :4;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_catrn_load :1;
+ __IO uint32_t dyn_ovr_dlycnt_ca_load :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_oor_reg0 register definition*/
+ __I uint32_t expert_dlycnt_oor_reg0;
+ struct
+ {
+ __I uint32_t dyn_ovr_dlycnt_dq_oor0 :8;
+ __I uint32_t dyn_ovr_dlycnt_dq_oor1 :8;
+ __I uint32_t dyn_ovr_dlycnt_dq_oor2 :8;
+ __I uint32_t dyn_ovr_dlycnt_dq_oor3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_oor_reg1 register definition*/
+ __I uint32_t expert_dlycnt_oor_reg1;
+ struct
+ {
+ __I uint32_t dyn_ovr_dlycnt_dq_oor4 :4;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor0 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor1 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor2 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor3 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor4 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor0 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor1 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor2 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor3 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor4 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor0 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor1 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor2 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor3 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor4 :1;
+ __I uint32_t dyn_ovr_dlycnt_catrn_oor :1;
+ __I uint32_t dyn_ovr_dlycnt_ca_oor :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_mv_rd_dly_reg register definition*/
+ __IO uint32_t expert_dlycnt_mv_rd_dly_reg;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly4 :1;
+ __I uint32_t reserved_01 :27;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_mv_rd_dly_reg_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_pause register definition*/
+ __IO uint32_t expert_dlycnt_pause;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_addcmd :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data4 :1;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_pause_TypeDef;
+
+typedef union{ /*!< expert_pllcnt register definition*/
+ __IO uint32_t expert_pllcnt;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_rotate :1;
+ __IO uint32_t dyn_ovr_dlycnt_direction :1;
+ __IO uint32_t dyn_ovr_dlycnt_loadphs_b :1;
+ __IO uint32_t dyn_ovr_dlycnt_phsel :4;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_pllcnt_TypeDef;
+
+typedef union{ /*!< expert_dqlane_readback register definition*/
+ __I uint32_t expert_dqlane_readback;
+ struct
+ {
+ __I uint32_t dq_or :5;
+ __I uint32_t dq_and :5;
+ __I uint32_t burst_valid :5;
+ __I uint32_t reserved_01 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dqlane_readback_TypeDef;
+
+typedef union{ /*!< expert_addcmd_ln_readback register definition*/
+ __I uint32_t expert_addcmd_ln_readback;
+ struct
+ {
+ __I uint32_t rx_refclk :8;
+ __I uint32_t rx_addcmd :4;
+ __I uint32_t rx_bclksclk :2;
+ __I uint32_t reserved_01 :18;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_addcmd_ln_readback_TypeDef;
+
+typedef union{ /*!< expert_read_gate_controls register definition*/
+ __IO uint32_t expert_read_gate_controls;
+ struct
+ {
+ __IO uint32_t dyn_ovr_rdgate_clksel :10;
+ __IO uint32_t dyn_ovr_rdgate_steps180 :20;
+ __I uint32_t reserved_01 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_read_gate_controls_TypeDef;
+
+typedef union{ /*!< expert_dq_dqs_optimization0 register definition*/
+ __I uint32_t expert_dq_dqs_optimization0;
+ struct
+ {
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane0 :8;
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane1 :8;
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane2 :8;
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization0_TypeDef;
+
+typedef union{ /*!< expert_dq_dqs_optimization1 register definition*/
+ __I uint32_t expert_dq_dqs_optimization1;
+ struct
+ {
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane4 :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization1_TypeDef;
+
+typedef union{ /*!< expert_wrcalib register definition*/
+ __IO uint32_t expert_wrcalib;
+ struct
+ {
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane0 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane1 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane2 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane3 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane4 :4;
+ __I uint32_t reserved_01 :12;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_wrcalib_TypeDef;
+
+typedef union{ /*!< expert_calif register definition*/
+ __IO uint32_t expert_calif;
+ struct
+ {
+ __IO uint32_t dyn_ovr_calif_read :1;
+ __IO uint32_t dyn_ovr_calif_write :1;
+ __IO uint32_t dyn_ovr_pattern_sel :4;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_calif_TypeDef;
+
+typedef union{ /*!< expert_calif_readback register definition*/
+ __I uint32_t expert_calif_readback;
+ struct
+ {
+ __I uint32_t wrcalib_pattern_match_lane0 :8;
+ __I uint32_t wrcalib_pattern_match_lane1 :8;
+ __I uint32_t wrcalib_pattern_match_lane2 :8;
+ __I uint32_t wrcalib_pattern_match_lane3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_calif_readback_TypeDef;
+
+typedef union{ /*!< expert_calif_readback1 register definition*/
+ __I uint32_t expert_calif_readback1;
+ struct
+ {
+ __I uint32_t wrcalib_pattern_match_lane4 :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_calif_readback1_TypeDef;
+
+typedef union{ /*!< expert_dfi_status_override_to_shim register definition*/
+ __IO uint32_t expert_dfi_status_override_to_shim;
+ struct
+ {
+ __IO uint32_t dfi_init_complete_shim :1;
+ __IO uint32_t dfi_training_complete_shim :1;
+ __IO uint32_t dfi_wrlvl_en_shim :1;
+ __IO uint32_t dfi_rdlvl_en_shim :1;
+ __IO uint32_t dfi_rdlvl_gate_en_shim :1;
+ __I uint32_t reserved_01 :27;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dfi_status_override_to_shim_TypeDef;
+
+typedef union{ /*!< tip_cfg_params register definition*/
+ __IO uint32_t tip_cfg_params;
+ struct
+ {
+ __IO uint32_t addcmd_offset :3;
+ __IO uint32_t bcklsclk_offset :3;
+ __IO uint32_t wrcalib_write_count :7;
+ __IO uint32_t read_gate_min_reads :9;
+ __IO uint32_t addrcmd_wait_count :9;
+ __I uint32_t reserved_01 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_tip_cfg_params_TypeDef;
+
+typedef union{ /*!< tip_vref_param register definition*/
+ __IO uint32_t tip_vref_param;
+ struct
+ {
+ __IO uint32_t vref_override :1;
+ __IO uint32_t data_vref :8;
+ __IO uint32_t ca_vref :8;
+ __I uint32_t reserved_01 :15;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_tip_vref_param_TypeDef;
+
+typedef union{ /*!< lane_alignment_fifo_control register definition*/
+ __IO uint32_t lane_alignment_fifo_control;
+ struct
+ {
+ __IO uint32_t block_fifo :1;
+ __IO uint32_t fifo_reset_n :1;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_lane_alignment_fifo_control_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_SGMII register definition*/
+ __IO uint32_t SOFT_RESET_SGMII;
+ struct
+ {
+ __O uint32_t nv_map_SGMII :1;
+ __O uint32_t v_map_SGMII :1;
+ __I uint32_t reserved_01 :6;
+ __O uint32_t periph_SGMII :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t blockid_SGMII :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_SGMII_TypeDef;
+
+typedef union{ /*!< SGMII_MODE register definition*/
+ __IO uint32_t SGMII_MODE;
+ struct
+ {
+ __IO uint32_t reg_pll_en :1;
+ __IO uint32_t reg_dll_en :1;
+ __IO uint32_t reg_pvt_en :1;
+ __IO uint32_t reg_bc_vrgen_en :1;
+ __IO uint32_t reg_tx0_en :1;
+ __IO uint32_t reg_rx0_en :1;
+ __IO uint32_t reg_tx1_en :1;
+ __IO uint32_t reg_rx1_en :1;
+ __IO uint32_t reg_dll_lock_flt :2;
+ __IO uint32_t reg_dll_adj_code :4;
+ __IO uint32_t reg_rx0_cdr_reset_b :1;
+ __IO uint32_t reg_rx1_cdr_reset_b :1;
+ __IO uint32_t reg_bc_vrgen :6;
+ __IO uint32_t reg_cdr_move_step :1;
+ __IO uint32_t reg_refclk_en_rdiff :1;
+ __IO uint32_t reg_bc_vs :4;
+ __IO uint32_t reg_refclk_en_udrive_p :1;
+ __IO uint32_t reg_refclk_en_ins_hyst_p :1;
+ __IO uint32_t reg_refclk_en_udrive_n :1;
+ __IO uint32_t reg_refclk_en_ins_hyst_n :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SGMII_MODE_TypeDef;
+
+typedef union{ /*!< PLL_CNTL register definition*/
+ __IO uint32_t PLL_CNTL;
+ struct
+ {
+ __IO uint32_t reg_pll_postdiv :7;
+ __I uint32_t aro_pll0_lock :1;
+ __IO uint32_t reg_pll_rfdiv :6;
+ __IO uint32_t reg_pll_reg_rfclk_sel :1;
+ __IO uint32_t reg_pll_lp_requires_lock :1;
+ __IO uint32_t reg_pll_intin :12;
+ __IO uint32_t reg_pll_bwi :2;
+ __IO uint32_t reg_pll_bwp :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CNTL_TypeDef;
+
+typedef union{ /*!< CH0_CNTL register definition*/
+ __IO uint32_t CH0_CNTL;
+ struct
+ {
+ __IO uint32_t reg_tx0_wpu_p :1;
+ __IO uint32_t reg_tx0_wpd_p :1;
+ __IO uint32_t reg_tx0_slew_p :2;
+ __IO uint32_t reg_tx0_drv_p :4;
+ __IO uint32_t reg_tx0_odt_p :4;
+ __IO uint32_t reg_tx0_odt_static_p :3;
+ __IO uint32_t reg_rx0_tim_long :1;
+ __IO uint32_t reg_rx0_wpu_p :1;
+ __IO uint32_t reg_rx0_wpd_p :1;
+ __IO uint32_t reg_rx0_ibufmd_p :3;
+ __IO uint32_t reg_rx0_eyewidth_p :3;
+ __IO uint32_t reg_rx0_odt_p :4;
+ __IO uint32_t reg_rx0_odt_static_p :3;
+ __I uint32_t reserved_01 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_CH0_CNTL_TypeDef;
+
+typedef union{ /*!< CH1_CNTL register definition*/
+ __IO uint32_t CH1_CNTL;
+ struct
+ {
+ __IO uint32_t reg_tx1_wpu_p :1;
+ __IO uint32_t reg_tx1_wpd_p :1;
+ __IO uint32_t reg_tx1_slew_p :2;
+ __IO uint32_t reg_tx1_drv_p :4;
+ __IO uint32_t reg_tx1_odt_p :4;
+ __IO uint32_t reg_tx1_odt_static_p :3;
+ __IO uint32_t reg_rx1_tim_long :1;
+ __IO uint32_t reg_rx1_wpu_p :1;
+ __IO uint32_t reg_rx1_wpd_p :1;
+ __IO uint32_t reg_rx1_ibufmd_p :3;
+ __IO uint32_t reg_rx1_eyewidth_p :3;
+ __IO uint32_t reg_rx1_odt_p :4;
+ __IO uint32_t reg_rx1_odt_static_p :3;
+ __I uint32_t reserved_01 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_CH1_CNTL_TypeDef;
+
+typedef union{ /*!< RECAL_CNTL register definition*/
+ __IO uint32_t RECAL_CNTL;
+ struct
+ {
+ __IO uint32_t reg_recal_diff_range :5;
+ __IO uint32_t reg_recal_start_en :1;
+ __IO uint32_t reg_pvt_calib_start :1;
+ __IO uint32_t reg_pvt_calib_lock :1;
+ __IO uint32_t reg_recal_upd :1;
+ __IO uint32_t bc_vrgen_direction :1;
+ __IO uint32_t bc_vrgen_load :1;
+ __IO uint32_t bc_vrgen_move :1;
+ __IO uint32_t reg_pvt_reg_calib_clkdiv :2;
+ __IO uint32_t reg_pvt_reg_calib_diffr_vsel :2;
+ __I uint32_t sro_dll_90_code :7;
+ __I uint32_t sro_dll_lock :1;
+ __I uint32_t sro_dll_st_code :7;
+ __I uint32_t sro_recal_start :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RECAL_CNTL_TypeDef;
+
+typedef union{ /*!< CLK_CNTL register definition*/
+ __IO uint32_t CLK_CNTL;
+ struct
+ {
+ __IO uint32_t reg_refclk_en_term_p :2;
+ __IO uint32_t reg_refclk_en_rxmode_p :2;
+ __IO uint32_t reg_refclk_en_term_n :2;
+ __IO uint32_t reg_refclk_en_rxmode_n :2;
+ __IO uint32_t reg_refclk_clkbuf_en_pullup :1;
+ __IO uint32_t reg_clkmux_fclk_sel :3;
+ __IO uint32_t reg_clkmux_pll0_rfclk0_sel :2;
+ __IO uint32_t reg_clkmux_pll0_rfclk1_sel :2;
+ __IO uint32_t reg_clkmux_spare0 :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_CLK_CNTL_TypeDef;
+
+typedef union{ /*!< DYN_CNTL register definition*/
+ __IO uint32_t DYN_CNTL;
+ struct
+ {
+ __IO uint32_t reg_pll_dynen :1;
+ __IO uint32_t reg_dll_dynen :1;
+ __IO uint32_t reg_pvt_dynen :1;
+ __IO uint32_t reg_bc_dynen :1;
+ __IO uint32_t reg_clkmux_dynen :1;
+ __IO uint32_t reg_lane0_dynen :1;
+ __IO uint32_t reg_lane1_dynen :1;
+ __I uint32_t bc_vrgen_oor :1;
+ __IO uint32_t reg_pll_soft_reset_periph :1;
+ __IO uint32_t reg_dll_soft_reset_periph :1;
+ __IO uint32_t reg_pvt_soft_reset_periph :1;
+ __IO uint32_t reg_bc_soft_reset_periph :1;
+ __IO uint32_t reg_clkmux_soft_reset_periph :1;
+ __IO uint32_t reg_lane0_soft_reset_periph :1;
+ __IO uint32_t reg_lane1_soft_reset_periph :1;
+ __I uint32_t pvt_calib_status :1;
+ __I uint32_t aro_pll0_vco0ph_sel :3;
+ __I uint32_t aro_pll0_vco1ph_sel :3;
+ __I uint32_t aro_pll0_vco2ph_sel :3;
+ __I uint32_t aro_pll0_vco3ph_sel :3;
+ __I uint32_t aro_ref_diffr :4;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DYN_CNTL_TypeDef;
+
+typedef union{ /*!< PVT_STAT register definition*/
+ __IO uint32_t PVT_STAT;
+ struct
+ {
+ __I uint32_t aro_ref_pcode :6;
+ __I uint32_t aro_ioen_bnk :1;
+ __I uint32_t aro_ioen_bnk_b :1;
+ __I uint32_t aro_ref_ncode :6;
+ __I uint32_t aro_calib_status :1;
+ __I uint32_t aro_calib_status_b :1;
+ __I uint32_t aro_pcode :6;
+ __I uint32_t aro_calib_intrpt :1;
+ __I uint32_t pvt_calib_intrpt :1;
+ __I uint32_t aro_ncode :6;
+ __IO uint32_t pvt_calib_lock :1;
+ __IO uint32_t pvt_calib_start :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PVT_STAT_TypeDef;
+
+typedef union{ /*!< SPARE_CNTL register definition*/
+ __IO uint32_t SPARE_CNTL;
+ struct
+ {
+ __IO uint32_t reg_spare :32;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SPARE_CNTL_TypeDef;
+
+typedef union{ /*!< SPARE_STAT register definition*/
+ __I uint32_t SPARE_STAT;
+ struct
+ {
+ __I uint32_t sro_spare :32;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SPARE_STAT_TypeDef;
+
+/*------------ CFG_DDR_SGMII_PHY definition -----------*/
+typedef struct
+{
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_TypeDef SOFT_RESET_DDR_PHY; /*!< Offset: 0x0 */
+ __IO CFG_DDR_SGMII_PHY_DDRPHY_MODE_TypeDef DDRPHY_MODE; /*!< Offset: 0x4 */
+ __IO CFG_DDR_SGMII_PHY_DDRPHY_STARTUP_TypeDef DDRPHY_STARTUP; /*!< Offset: 0x8 */
+ __IO uint32_t UNUSED_SPACE0[29]; /*!< Offset: 0xc */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_TypeDef SOFT_RESET_MAIN_PLL; /*!< Offset: 0x80 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL_MAIN_TypeDef PLL_CTRL_MAIN; /*!< Offset: 0x84 */
+ __IO CFG_DDR_SGMII_PHY_PLL_REF_FB_MAIN_TypeDef PLL_REF_FB_MAIN; /*!< Offset: 0x88 */
+ __I CFG_DDR_SGMII_PHY_PLL_FRACN_MAIN_TypeDef PLL_FRACN_MAIN; /*!< Offset: 0x8c */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_0_1_MAIN_TypeDef PLL_DIV_0_1_MAIN; /*!< Offset: 0x90 */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_2_3_MAIN_TypeDef PLL_DIV_2_3_MAIN; /*!< Offset: 0x94 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL2_MAIN_TypeDef PLL_CTRL2_MAIN; /*!< Offset: 0x98 */
+ __I CFG_DDR_SGMII_PHY_PLL_CAL_MAIN_TypeDef PLL_CAL_MAIN; /*!< Offset: 0x9c */
+ __IO CFG_DDR_SGMII_PHY_PLL_PHADJ_MAIN_TypeDef PLL_PHADJ_MAIN; /*!< Offset: 0xa0 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_0_MAIN_TypeDef SSCG_REG_0_MAIN; /*!< Offset: 0xa4 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_1_MAIN_TypeDef SSCG_REG_1_MAIN; /*!< Offset: 0xa8 */
+ __IO CFG_DDR_SGMII_PHY_SSCG_REG_2_MAIN_TypeDef SSCG_REG_2_MAIN; /*!< Offset: 0xac */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_3_MAIN_TypeDef SSCG_REG_3_MAIN; /*!< Offset: 0xb0 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_MAIN_PLL_TypeDef RPC_RESET_MAIN_PLL; /*!< Offset: 0xb4 */
+ __I uint32_t UNUSED_SPACE1[18]; /*!< Offset: 0xb8 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_TypeDef SOFT_RESET_IOSCB_PLL; /*!< Offset: 0x100 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL_IOSCB_TypeDef PLL_CTRL_IOSCB; /*!< Offset: 0x104 */
+ __IO CFG_DDR_SGMII_PHY_PLL_REF_FB_IOSCB_TypeDef PLL_REF_FB_IOSCB; /*!< Offset: 0x108 */
+ __I CFG_DDR_SGMII_PHY_PLL_FRACN_IOSCB_TypeDef PLL_FRACN_IOSCB; /*!< Offset: 0x10c */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_0_1_IOSCB_TypeDef PLL_DIV_0_1_IOSCB; /*!< Offset: 0x110 */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_2_3_IOSCB_TypeDef PLL_DIV_2_3_IOSCB; /*!< Offset: 0x114 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL2_IOSCB_TypeDef PLL_CTRL2_IOSCB; /*!< Offset: 0x118 */
+ __I CFG_DDR_SGMII_PHY_PLL_CAL_IOSCB_TypeDef PLL_CAL_IOSCB; /*!< Offset: 0x11c */
+ __IO CFG_DDR_SGMII_PHY_PLL_PHADJ_IOSCB_TypeDef PLL_PHADJ_IOSCB; /*!< Offset: 0x120 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_0_IOSCB_TypeDef SSCG_REG_0_IOSCB; /*!< Offset: 0x124 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_1_IOSCB_TypeDef SSCG_REG_1_IOSCB; /*!< Offset: 0x128 */
+ __IO CFG_DDR_SGMII_PHY_SSCG_REG_2_IOSCB_TypeDef SSCG_REG_2_IOSCB; /*!< Offset: 0x12c */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_3_IOSCB_TypeDef SSCG_REG_3_IOSCB; /*!< Offset: 0x130 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_IOSCB_TypeDef RPC_RESET_IOSCB; /*!< Offset: 0x134 */
+ __I uint32_t UNUSED_SPACE2[18]; /*!< Offset: 0x138 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_TypeDef SOFT_RESET_BANK_CTRL; /*!< Offset: 0x180 */
+ __IO CFG_DDR_SGMII_PHY_DPC_BITS_TypeDef DPC_BITS; /*!< Offset: 0x184 */
+ __I CFG_DDR_SGMII_PHY_BANK_STATUS_TypeDef BANK_STATUS; /*!< Offset: 0x188 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_BANK_CTRL_TypeDef RPC_RESET_BANK_CTRL; /*!< Offset: 0x18c */
+ __I uint32_t UNUSED_SPACE3[28]; /*!< Offset: 0x190 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_TypeDef SOFT_RESET_IOCALIB; /*!< Offset: 0x200 */
+ __IO CFG_DDR_SGMII_PHY_IOC_REG0_TypeDef IOC_REG0; /*!< Offset: 0x204 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG1_TypeDef IOC_REG1; /*!< Offset: 0x208 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG2_TypeDef IOC_REG2; /*!< Offset: 0x20c */
+ __I CFG_DDR_SGMII_PHY_IOC_REG3_TypeDef IOC_REG3; /*!< Offset: 0x210 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG4_TypeDef IOC_REG4; /*!< Offset: 0x214 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG5_TypeDef IOC_REG5; /*!< Offset: 0x218 */
+ __IO CFG_DDR_SGMII_PHY_IOC_REG6_TypeDef IOC_REG6; /*!< Offset: 0x21c */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_IOCALIB_TypeDef RPC_RESET_IOCALIB; /*!< Offset: 0x220 */
+ __IO CFG_DDR_SGMII_PHY_rpc_calib_TypeDef rpc_calib; /*!< Offset: 0x224 */
+ __I uint32_t UNUSED_SPACE4[22]; /*!< Offset: 0x228 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_TypeDef SOFT_RESET_CFM; /*!< Offset: 0x280 */
+ __IO CFG_DDR_SGMII_PHY_BCLKMUX_TypeDef BCLKMUX; /*!< Offset: 0x284 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CKMUX_TypeDef PLL_CKMUX; /*!< Offset: 0x288 */
+ __IO CFG_DDR_SGMII_PHY_MSSCLKMUX_TypeDef MSSCLKMUX; /*!< Offset: 0x28c */
+ __IO CFG_DDR_SGMII_PHY_SPARE0_TypeDef SPARE0; /*!< Offset: 0x290 */
+ __I CFG_DDR_SGMII_PHY_FMETER_ADDR_TypeDef FMETER_ADDR; /*!< Offset: 0x294 */
+ __I CFG_DDR_SGMII_PHY_FMETER_DATAW_TypeDef FMETER_DATAW; /*!< Offset: 0x298 */
+ __I CFG_DDR_SGMII_PHY_FMETER_DATAR_TypeDef FMETER_DATAR; /*!< Offset: 0x29c */
+ __I CFG_DDR_SGMII_PHY_TEST_CTRL_TypeDef TEST_CTRL; /*!< Offset: 0x2a0 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_CFM_TypeDef RPC_RESET_CFM; /*!< Offset: 0x2a4 */
+ __I uint32_t UNUSED_SPACE5[22]; /*!< Offset: 0x2a8 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_TypeDef SOFT_RESET_DECODER_DRIVER; /*!< Offset: 0x300 */
+ __IO CFG_DDR_SGMII_PHY_rpc1_DRV_TypeDef rpc1_DRV; /*!< Offset: 0x304 */
+ __IO CFG_DDR_SGMII_PHY_rpc2_DRV_TypeDef rpc2_DRV; /*!< Offset: 0x308 */
+ __IO CFG_DDR_SGMII_PHY_rpc3_DRV_TypeDef rpc3_DRV; /*!< Offset: 0x30c */
+ __IO CFG_DDR_SGMII_PHY_rpc4_DRV_TypeDef rpc4_DRV; /*!< Offset: 0x310 */
+ __I uint32_t UNUSED_SPACE6[27]; /*!< Offset: 0x314 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_TypeDef SOFT_RESET_DECODER_ODT; /*!< Offset: 0x380 */
+ __IO CFG_DDR_SGMII_PHY_rpc1_ODT_TypeDef rpc1_ODT; /*!< Offset: 0x384 */
+ __IO CFG_DDR_SGMII_PHY_rpc2_ODT_TypeDef rpc2_ODT; /*!< Offset: 0x388 */
+ __IO CFG_DDR_SGMII_PHY_rpc3_ODT_TypeDef rpc3_ODT; /*!< Offset: 0x38c */
+ __IO CFG_DDR_SGMII_PHY_rpc4_ODT_TypeDef rpc4_ODT; /*!< Offset: 0x390 */
+ __IO CFG_DDR_SGMII_PHY_rpc5_ODT_TypeDef rpc5_ODT; /*!< Offset: 0x394 */
+ __IO CFG_DDR_SGMII_PHY_rpc6_ODT_TypeDef rpc6_ODT; /*!< Offset: 0x398 */
+ __IO CFG_DDR_SGMII_PHY_rpc7_ODT_TypeDef rpc7_ODT; /*!< Offset: 0x39c */
+ __IO CFG_DDR_SGMII_PHY_rpc8_ODT_TypeDef rpc8_ODT; /*!< Offset: 0x3a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc9_ODT_TypeDef rpc9_ODT; /*!< Offset: 0x3a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc10_ODT_TypeDef rpc10_ODT; /*!< Offset: 0x3a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc11_ODT_TypeDef rpc11_ODT; /*!< Offset: 0x3ac */
+ __I uint32_t UNUSED_SPACE7[20]; /*!< Offset: 0x3b0 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_TypeDef SOFT_RESET_DECODER_IO; /*!< Offset: 0x400 */
+ __IO CFG_DDR_SGMII_PHY_ovrt1_TypeDef ovrt1; /*!< Offset: 0x404 */
+ __IO CFG_DDR_SGMII_PHY_ovrt2_TypeDef ovrt2; /*!< Offset: 0x408 */
+ __IO CFG_DDR_SGMII_PHY_ovrt3_TypeDef ovrt3; /*!< Offset: 0x40c */
+ __IO CFG_DDR_SGMII_PHY_ovrt4_TypeDef ovrt4; /*!< Offset: 0x410 */
+ __IO CFG_DDR_SGMII_PHY_ovrt5_TypeDef ovrt5; /*!< Offset: 0x414 */
+ __IO CFG_DDR_SGMII_PHY_ovrt6_TypeDef ovrt6; /*!< Offset: 0x418 */
+ __IO CFG_DDR_SGMII_PHY_ovrt7_TypeDef ovrt7; /*!< Offset: 0x41c */
+ __IO CFG_DDR_SGMII_PHY_ovrt8_TypeDef ovrt8; /*!< Offset: 0x420 */
+ __IO CFG_DDR_SGMII_PHY_ovrt9_TypeDef ovrt9; /*!< Offset: 0x424 */
+ __IO CFG_DDR_SGMII_PHY_ovrt10_TypeDef ovrt10; /*!< Offset: 0x428 */
+ __IO CFG_DDR_SGMII_PHY_ovrt11_TypeDef ovrt11; /*!< Offset: 0x42c */
+ __IO CFG_DDR_SGMII_PHY_ovrt12_TypeDef ovrt12; /*!< Offset: 0x430 */
+ __IO CFG_DDR_SGMII_PHY_ovrt13_TypeDef ovrt13; /*!< Offset: 0x434 */
+ __IO CFG_DDR_SGMII_PHY_ovrt14_TypeDef ovrt14; /*!< Offset: 0x438 */
+ __IO CFG_DDR_SGMII_PHY_ovrt15_TypeDef ovrt15; /*!< Offset: 0x43c */
+ __IO CFG_DDR_SGMII_PHY_ovrt16_TypeDef ovrt16; /*!< Offset: 0x440 */
+ __IO CFG_DDR_SGMII_PHY_rpc17_TypeDef rpc17; /*!< Offset: 0x444 */
+ __IO CFG_DDR_SGMII_PHY_rpc18_TypeDef rpc18; /*!< Offset: 0x448 */
+ __IO CFG_DDR_SGMII_PHY_rpc19_TypeDef rpc19; /*!< Offset: 0x44c */
+ __IO CFG_DDR_SGMII_PHY_rpc20_TypeDef rpc20; /*!< Offset: 0x450 */
+ __IO CFG_DDR_SGMII_PHY_rpc21_TypeDef rpc21; /*!< Offset: 0x454 */
+ __IO CFG_DDR_SGMII_PHY_rpc22_TypeDef rpc22; /*!< Offset: 0x458 */
+ __IO CFG_DDR_SGMII_PHY_rpc23_TypeDef rpc23; /*!< Offset: 0x45c */
+ __IO CFG_DDR_SGMII_PHY_rpc24_TypeDef rpc24; /*!< Offset: 0x460 */
+ __IO CFG_DDR_SGMII_PHY_rpc25_TypeDef rpc25; /*!< Offset: 0x464 */
+ __IO CFG_DDR_SGMII_PHY_rpc26_TypeDef rpc26; /*!< Offset: 0x468 */
+ __IO CFG_DDR_SGMII_PHY_rpc27_TypeDef rpc27; /*!< Offset: 0x46c */
+ __IO CFG_DDR_SGMII_PHY_rpc28_TypeDef rpc28; /*!< Offset: 0x470 */
+ __IO CFG_DDR_SGMII_PHY_rpc29_TypeDef rpc29; /*!< Offset: 0x474 */
+ __IO CFG_DDR_SGMII_PHY_rpc30_TypeDef rpc30; /*!< Offset: 0x478 */
+ __IO CFG_DDR_SGMII_PHY_rpc31_TypeDef rpc31; /*!< Offset: 0x47c */
+ __IO CFG_DDR_SGMII_PHY_rpc32_TypeDef rpc32; /*!< Offset: 0x480 */
+ __IO CFG_DDR_SGMII_PHY_rpc33_TypeDef rpc33; /*!< Offset: 0x484 */
+ __IO CFG_DDR_SGMII_PHY_rpc34_TypeDef rpc34; /*!< Offset: 0x488 */
+ __IO CFG_DDR_SGMII_PHY_rpc35_TypeDef rpc35; /*!< Offset: 0x48c */
+ __IO CFG_DDR_SGMII_PHY_rpc36_TypeDef rpc36; /*!< Offset: 0x490 */
+ __IO CFG_DDR_SGMII_PHY_rpc37_TypeDef rpc37; /*!< Offset: 0x494 */
+ __IO CFG_DDR_SGMII_PHY_rpc38_TypeDef rpc38; /*!< Offset: 0x498 */
+ __IO CFG_DDR_SGMII_PHY_rpc39_TypeDef rpc39; /*!< Offset: 0x49c */
+ __IO CFG_DDR_SGMII_PHY_rpc40_TypeDef rpc40; /*!< Offset: 0x4a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc41_TypeDef rpc41; /*!< Offset: 0x4a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc42_TypeDef rpc42; /*!< Offset: 0x4a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc43_TypeDef rpc43; /*!< Offset: 0x4ac */
+ __IO CFG_DDR_SGMII_PHY_rpc44_TypeDef rpc44; /*!< Offset: 0x4b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc45_TypeDef rpc45; /*!< Offset: 0x4b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc46_TypeDef rpc46; /*!< Offset: 0x4b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc47_TypeDef rpc47; /*!< Offset: 0x4bc */
+ __IO CFG_DDR_SGMII_PHY_rpc48_TypeDef rpc48; /*!< Offset: 0x4c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc49_TypeDef rpc49; /*!< Offset: 0x4c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc50_TypeDef rpc50; /*!< Offset: 0x4c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc51_TypeDef rpc51; /*!< Offset: 0x4cc */
+ __IO CFG_DDR_SGMII_PHY_rpc52_TypeDef rpc52; /*!< Offset: 0x4d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc53_TypeDef rpc53; /*!< Offset: 0x4d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc54_TypeDef rpc54; /*!< Offset: 0x4d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc55_TypeDef rpc55; /*!< Offset: 0x4dc */
+ __IO CFG_DDR_SGMII_PHY_rpc56_TypeDef rpc56; /*!< Offset: 0x4e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc57_TypeDef rpc57; /*!< Offset: 0x4e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc58_TypeDef rpc58; /*!< Offset: 0x4e8 */
+ __IO CFG_DDR_SGMII_PHY_rpc59_TypeDef rpc59; /*!< Offset: 0x4ec */
+ __IO CFG_DDR_SGMII_PHY_rpc60_TypeDef rpc60; /*!< Offset: 0x4f0 */
+ __IO CFG_DDR_SGMII_PHY_rpc61_TypeDef rpc61; /*!< Offset: 0x4f4 */
+ __IO CFG_DDR_SGMII_PHY_rpc62_TypeDef rpc62; /*!< Offset: 0x4f8 */
+ __IO CFG_DDR_SGMII_PHY_rpc63_TypeDef rpc63; /*!< Offset: 0x4fc */
+ __IO CFG_DDR_SGMII_PHY_rpc64_TypeDef rpc64; /*!< Offset: 0x500 */
+ __IO CFG_DDR_SGMII_PHY_rpc65_TypeDef rpc65; /*!< Offset: 0x504 */
+ __IO CFG_DDR_SGMII_PHY_rpc66_TypeDef rpc66; /*!< Offset: 0x508 */
+ __IO CFG_DDR_SGMII_PHY_rpc67_TypeDef rpc67; /*!< Offset: 0x50c */
+ __IO CFG_DDR_SGMII_PHY_rpc68_TypeDef rpc68; /*!< Offset: 0x510 */
+ __IO CFG_DDR_SGMII_PHY_rpc69_TypeDef rpc69; /*!< Offset: 0x514 */
+ __IO CFG_DDR_SGMII_PHY_rpc70_TypeDef rpc70; /*!< Offset: 0x518 */
+ __IO CFG_DDR_SGMII_PHY_rpc71_TypeDef rpc71; /*!< Offset: 0x51c */
+ __IO CFG_DDR_SGMII_PHY_rpc72_TypeDef rpc72; /*!< Offset: 0x520 */
+ __IO CFG_DDR_SGMII_PHY_rpc73_TypeDef rpc73; /*!< Offset: 0x524 */
+ __IO CFG_DDR_SGMII_PHY_rpc74_TypeDef rpc74; /*!< Offset: 0x528 */
+ __IO CFG_DDR_SGMII_PHY_rpc75_TypeDef rpc75; /*!< Offset: 0x52c */
+ __IO CFG_DDR_SGMII_PHY_rpc76_TypeDef rpc76; /*!< Offset: 0x530 */
+ __IO CFG_DDR_SGMII_PHY_rpc77_TypeDef rpc77; /*!< Offset: 0x534 */
+ __IO CFG_DDR_SGMII_PHY_rpc78_TypeDef rpc78; /*!< Offset: 0x538 */
+ __IO CFG_DDR_SGMII_PHY_rpc79_TypeDef rpc79; /*!< Offset: 0x53c */
+ __IO CFG_DDR_SGMII_PHY_rpc80_TypeDef rpc80; /*!< Offset: 0x540 */
+ __IO CFG_DDR_SGMII_PHY_rpc81_TypeDef rpc81; /*!< Offset: 0x544 */
+ __IO CFG_DDR_SGMII_PHY_rpc82_TypeDef rpc82; /*!< Offset: 0x548 */
+ __IO CFG_DDR_SGMII_PHY_rpc83_TypeDef rpc83; /*!< Offset: 0x54c */
+ __IO CFG_DDR_SGMII_PHY_rpc84_TypeDef rpc84; /*!< Offset: 0x550 */
+ __IO CFG_DDR_SGMII_PHY_rpc85_TypeDef rpc85; /*!< Offset: 0x554 */
+ __IO CFG_DDR_SGMII_PHY_rpc86_TypeDef rpc86; /*!< Offset: 0x558 */
+ __IO CFG_DDR_SGMII_PHY_rpc87_TypeDef rpc87; /*!< Offset: 0x55c */
+ __IO CFG_DDR_SGMII_PHY_rpc88_TypeDef rpc88; /*!< Offset: 0x560 */
+ __IO CFG_DDR_SGMII_PHY_rpc89_TypeDef rpc89; /*!< Offset: 0x564 */
+ __IO CFG_DDR_SGMII_PHY_rpc90_TypeDef rpc90; /*!< Offset: 0x568 */
+ __IO CFG_DDR_SGMII_PHY_rpc91_TypeDef rpc91; /*!< Offset: 0x56c */
+ __IO CFG_DDR_SGMII_PHY_rpc92_TypeDef rpc92; /*!< Offset: 0x570 */
+ __IO CFG_DDR_SGMII_PHY_rpc93_TypeDef rpc93; /*!< Offset: 0x574 */
+ __IO CFG_DDR_SGMII_PHY_rpc94_TypeDef rpc94; /*!< Offset: 0x578 */
+ __IO CFG_DDR_SGMII_PHY_rpc95_TypeDef rpc95; /*!< Offset: 0x57c */
+ __IO CFG_DDR_SGMII_PHY_rpc96_TypeDef rpc96; /*!< Offset: 0x580 */
+ __IO CFG_DDR_SGMII_PHY_rpc97_TypeDef rpc97; /*!< Offset: 0x584 */
+ __IO CFG_DDR_SGMII_PHY_rpc98_TypeDef rpc98; /*!< Offset: 0x588 */
+ __IO CFG_DDR_SGMII_PHY_rpc99_TypeDef rpc99; /*!< Offset: 0x58c */
+ __IO CFG_DDR_SGMII_PHY_rpc100_TypeDef rpc100; /*!< Offset: 0x590 */
+ __IO CFG_DDR_SGMII_PHY_rpc101_TypeDef rpc101; /*!< Offset: 0x594 */
+ __IO CFG_DDR_SGMII_PHY_rpc102_TypeDef rpc102; /*!< Offset: 0x598 */
+ __IO CFG_DDR_SGMII_PHY_rpc103_TypeDef rpc103; /*!< Offset: 0x59c */
+ __IO CFG_DDR_SGMII_PHY_rpc104_TypeDef rpc104; /*!< Offset: 0x5a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc105_TypeDef rpc105; /*!< Offset: 0x5a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc106_TypeDef rpc106; /*!< Offset: 0x5a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc107_TypeDef rpc107; /*!< Offset: 0x5ac */
+ __IO CFG_DDR_SGMII_PHY_rpc108_TypeDef rpc108; /*!< Offset: 0x5b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc109_TypeDef rpc109; /*!< Offset: 0x5b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc110_TypeDef rpc110; /*!< Offset: 0x5b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc111_TypeDef rpc111; /*!< Offset: 0x5bc */
+ __IO CFG_DDR_SGMII_PHY_rpc112_TypeDef rpc112; /*!< Offset: 0x5c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc113_TypeDef rpc113; /*!< Offset: 0x5c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc114_TypeDef rpc114; /*!< Offset: 0x5c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc115_TypeDef rpc115; /*!< Offset: 0x5cc */
+ __IO CFG_DDR_SGMII_PHY_rpc116_TypeDef rpc116; /*!< Offset: 0x5d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc117_TypeDef rpc117; /*!< Offset: 0x5d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc118_TypeDef rpc118; /*!< Offset: 0x5d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc119_TypeDef rpc119; /*!< Offset: 0x5dc */
+ __IO CFG_DDR_SGMII_PHY_rpc120_TypeDef rpc120; /*!< Offset: 0x5e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc121_TypeDef rpc121; /*!< Offset: 0x5e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc122_TypeDef rpc122; /*!< Offset: 0x5e8 */
+ __IO CFG_DDR_SGMII_PHY_rpc123_TypeDef rpc123; /*!< Offset: 0x5ec */
+ __IO CFG_DDR_SGMII_PHY_rpc124_TypeDef rpc124; /*!< Offset: 0x5f0 */
+ __IO CFG_DDR_SGMII_PHY_rpc125_TypeDef rpc125; /*!< Offset: 0x5f4 */
+ __IO CFG_DDR_SGMII_PHY_rpc126_TypeDef rpc126; /*!< Offset: 0x5f8 */
+ __IO CFG_DDR_SGMII_PHY_rpc127_TypeDef rpc127; /*!< Offset: 0x5fc */
+ __IO CFG_DDR_SGMII_PHY_rpc128_TypeDef rpc128; /*!< Offset: 0x600 */
+ __IO CFG_DDR_SGMII_PHY_rpc129_TypeDef rpc129; /*!< Offset: 0x604 */
+ __IO CFG_DDR_SGMII_PHY_rpc130_TypeDef rpc130; /*!< Offset: 0x608 */
+ __IO CFG_DDR_SGMII_PHY_rpc131_TypeDef rpc131; /*!< Offset: 0x60c */
+ __IO CFG_DDR_SGMII_PHY_rpc132_TypeDef rpc132; /*!< Offset: 0x610 */
+ __IO CFG_DDR_SGMII_PHY_rpc133_TypeDef rpc133; /*!< Offset: 0x614 */
+ __IO CFG_DDR_SGMII_PHY_rpc134_TypeDef rpc134; /*!< Offset: 0x618 */
+ __IO CFG_DDR_SGMII_PHY_rpc135_TypeDef rpc135; /*!< Offset: 0x61c */
+ __IO CFG_DDR_SGMII_PHY_rpc136_TypeDef rpc136; /*!< Offset: 0x620 */
+ __IO CFG_DDR_SGMII_PHY_rpc137_TypeDef rpc137; /*!< Offset: 0x624 */
+ __IO CFG_DDR_SGMII_PHY_rpc138_TypeDef rpc138; /*!< Offset: 0x628 */
+ __IO CFG_DDR_SGMII_PHY_rpc139_TypeDef rpc139; /*!< Offset: 0x62c */
+ __IO CFG_DDR_SGMII_PHY_rpc140_TypeDef rpc140; /*!< Offset: 0x630 */
+ __IO CFG_DDR_SGMII_PHY_rpc141_TypeDef rpc141; /*!< Offset: 0x634 */
+ __IO CFG_DDR_SGMII_PHY_rpc142_TypeDef rpc142; /*!< Offset: 0x638 */
+ __IO CFG_DDR_SGMII_PHY_rpc143_TypeDef rpc143; /*!< Offset: 0x63c */
+ __IO CFG_DDR_SGMII_PHY_rpc144_TypeDef rpc144; /*!< Offset: 0x640 */
+ __IO CFG_DDR_SGMII_PHY_rpc145_TypeDef rpc145; /*!< Offset: 0x644 */
+ __IO CFG_DDR_SGMII_PHY_rpc146_TypeDef rpc146; /*!< Offset: 0x648 */
+ __IO CFG_DDR_SGMII_PHY_rpc147_TypeDef rpc147; /*!< Offset: 0x64c */
+ __IO CFG_DDR_SGMII_PHY_rpc148_TypeDef rpc148; /*!< Offset: 0x650 */
+ __IO CFG_DDR_SGMII_PHY_rpc149_TypeDef rpc149; /*!< Offset: 0x654 */
+ __IO CFG_DDR_SGMII_PHY_rpc150_TypeDef rpc150; /*!< Offset: 0x658 */
+ __IO CFG_DDR_SGMII_PHY_rpc151_TypeDef rpc151; /*!< Offset: 0x65c */
+ __IO CFG_DDR_SGMII_PHY_rpc152_TypeDef rpc152; /*!< Offset: 0x660 */
+ __IO CFG_DDR_SGMII_PHY_rpc153_TypeDef rpc153; /*!< Offset: 0x664 */
+ __IO CFG_DDR_SGMII_PHY_rpc154_TypeDef rpc154; /*!< Offset: 0x668 */
+ __IO CFG_DDR_SGMII_PHY_rpc155_TypeDef rpc155; /*!< Offset: 0x66c */
+ __IO CFG_DDR_SGMII_PHY_rpc156_TypeDef rpc156; /*!< Offset: 0x670 */
+ __IO CFG_DDR_SGMII_PHY_rpc157_TypeDef rpc157; /*!< Offset: 0x674 */
+ __IO CFG_DDR_SGMII_PHY_rpc158_TypeDef rpc158; /*!< Offset: 0x678 */
+ __IO CFG_DDR_SGMII_PHY_rpc159_TypeDef rpc159; /*!< Offset: 0x67c */
+ __IO CFG_DDR_SGMII_PHY_rpc160_TypeDef rpc160; /*!< Offset: 0x680 */
+ __IO CFG_DDR_SGMII_PHY_rpc161_TypeDef rpc161; /*!< Offset: 0x684 */
+ __IO CFG_DDR_SGMII_PHY_rpc162_TypeDef rpc162; /*!< Offset: 0x688 */
+ __IO CFG_DDR_SGMII_PHY_rpc163_TypeDef rpc163; /*!< Offset: 0x68c */
+ __IO CFG_DDR_SGMII_PHY_rpc164_TypeDef rpc164; /*!< Offset: 0x690 */
+ __IO CFG_DDR_SGMII_PHY_rpc165_TypeDef rpc165; /*!< Offset: 0x694 */
+ __IO CFG_DDR_SGMII_PHY_rpc166_TypeDef rpc166; /*!< Offset: 0x698 */
+ __IO CFG_DDR_SGMII_PHY_rpc167_TypeDef rpc167; /*!< Offset: 0x69c */
+ __IO CFG_DDR_SGMII_PHY_rpc168_TypeDef rpc168; /*!< Offset: 0x6a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc169_TypeDef rpc169; /*!< Offset: 0x6a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc170_TypeDef rpc170; /*!< Offset: 0x6a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc171_TypeDef rpc171; /*!< Offset: 0x6ac */
+ __IO CFG_DDR_SGMII_PHY_rpc172_TypeDef rpc172; /*!< Offset: 0x6b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc173_TypeDef rpc173; /*!< Offset: 0x6b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc174_TypeDef rpc174; /*!< Offset: 0x6b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc175_TypeDef rpc175; /*!< Offset: 0x6bc */
+ __IO CFG_DDR_SGMII_PHY_rpc176_TypeDef rpc176; /*!< Offset: 0x6c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc177_TypeDef rpc177; /*!< Offset: 0x6c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc178_TypeDef rpc178; /*!< Offset: 0x6c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc179_TypeDef rpc179; /*!< Offset: 0x6cc */
+ __IO CFG_DDR_SGMII_PHY_rpc180_TypeDef rpc180; /*!< Offset: 0x6d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc181_TypeDef rpc181; /*!< Offset: 0x6d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc182_TypeDef rpc182; /*!< Offset: 0x6d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc183_TypeDef rpc183; /*!< Offset: 0x6dc */
+ __IO CFG_DDR_SGMII_PHY_rpc184_TypeDef rpc184; /*!< Offset: 0x6e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc185_TypeDef rpc185; /*!< Offset: 0x6e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc186_TypeDef rpc186; /*!< Offset: 0x6e8 */
+ __IO CFG_DDR_SGMII_PHY_rpc187_TypeDef rpc187; /*!< Offset: 0x6ec */
+ __IO CFG_DDR_SGMII_PHY_rpc188_TypeDef rpc188; /*!< Offset: 0x6f0 */
+ __IO CFG_DDR_SGMII_PHY_rpc189_TypeDef rpc189; /*!< Offset: 0x6f4 */
+ __IO CFG_DDR_SGMII_PHY_rpc190_TypeDef rpc190; /*!< Offset: 0x6f8 */
+ __IO CFG_DDR_SGMII_PHY_rpc191_TypeDef rpc191; /*!< Offset: 0x6fc */
+ __IO CFG_DDR_SGMII_PHY_rpc192_TypeDef rpc192; /*!< Offset: 0x700 */
+ __IO CFG_DDR_SGMII_PHY_rpc193_TypeDef rpc193; /*!< Offset: 0x704 */
+ __IO CFG_DDR_SGMII_PHY_rpc194_TypeDef rpc194; /*!< Offset: 0x708 */
+ __IO CFG_DDR_SGMII_PHY_rpc195_TypeDef rpc195; /*!< Offset: 0x70c */
+ __IO CFG_DDR_SGMII_PHY_rpc196_TypeDef rpc196; /*!< Offset: 0x710 */
+ __IO CFG_DDR_SGMII_PHY_rpc197_TypeDef rpc197; /*!< Offset: 0x714 */
+ __IO CFG_DDR_SGMII_PHY_rpc198_TypeDef rpc198; /*!< Offset: 0x718 */
+ __IO CFG_DDR_SGMII_PHY_rpc199_TypeDef rpc199; /*!< Offset: 0x71c */
+ __IO CFG_DDR_SGMII_PHY_rpc200_TypeDef rpc200; /*!< Offset: 0x720 */
+ __IO CFG_DDR_SGMII_PHY_rpc201_TypeDef rpc201; /*!< Offset: 0x724 */
+ __IO CFG_DDR_SGMII_PHY_rpc202_TypeDef rpc202; /*!< Offset: 0x728 */
+ __IO CFG_DDR_SGMII_PHY_rpc203_TypeDef rpc203; /*!< Offset: 0x72c */
+ __IO CFG_DDR_SGMII_PHY_rpc204_TypeDef rpc204; /*!< Offset: 0x730 */
+ __IO CFG_DDR_SGMII_PHY_rpc205_TypeDef rpc205; /*!< Offset: 0x734 */
+ __IO CFG_DDR_SGMII_PHY_rpc206_TypeDef rpc206; /*!< Offset: 0x738 */
+ __IO CFG_DDR_SGMII_PHY_rpc207_TypeDef rpc207; /*!< Offset: 0x73c */
+ __IO CFG_DDR_SGMII_PHY_rpc208_TypeDef rpc208; /*!< Offset: 0x740 */
+ __IO CFG_DDR_SGMII_PHY_rpc209_TypeDef rpc209; /*!< Offset: 0x744 */
+ __IO CFG_DDR_SGMII_PHY_rpc210_TypeDef rpc210; /*!< Offset: 0x748 */
+ __IO CFG_DDR_SGMII_PHY_rpc211_TypeDef rpc211; /*!< Offset: 0x74c */
+ __IO CFG_DDR_SGMII_PHY_rpc212_TypeDef rpc212; /*!< Offset: 0x750 */
+ __IO CFG_DDR_SGMII_PHY_rpc213_TypeDef rpc213; /*!< Offset: 0x754 */
+ __IO CFG_DDR_SGMII_PHY_rpc214_TypeDef rpc214; /*!< Offset: 0x758 */
+ __IO CFG_DDR_SGMII_PHY_rpc215_TypeDef rpc215; /*!< Offset: 0x75c */
+ __IO CFG_DDR_SGMII_PHY_rpc216_TypeDef rpc216; /*!< Offset: 0x760 */
+ __IO CFG_DDR_SGMII_PHY_rpc217_TypeDef rpc217; /*!< Offset: 0x764 */
+ __IO CFG_DDR_SGMII_PHY_rpc218_TypeDef rpc218; /*!< Offset: 0x768 */
+ __IO CFG_DDR_SGMII_PHY_rpc219_TypeDef rpc219; /*!< Offset: 0x76c */
+ __IO CFG_DDR_SGMII_PHY_rpc220_TypeDef rpc220; /*!< Offset: 0x770 */
+ __IO CFG_DDR_SGMII_PHY_rpc221_TypeDef rpc221; /*!< Offset: 0x774 */
+ __IO CFG_DDR_SGMII_PHY_rpc222_TypeDef rpc222; /*!< Offset: 0x778 */
+ __IO CFG_DDR_SGMII_PHY_rpc223_TypeDef rpc223; /*!< Offset: 0x77c */
+ __IO CFG_DDR_SGMII_PHY_rpc224_TypeDef rpc224; /*!< Offset: 0x780 */
+ __IO CFG_DDR_SGMII_PHY_rpc225_TypeDef rpc225; /*!< Offset: 0x784 */
+ __IO CFG_DDR_SGMII_PHY_rpc226_TypeDef rpc226; /*!< Offset: 0x788 */
+ __IO CFG_DDR_SGMII_PHY_rpc227_TypeDef rpc227; /*!< Offset: 0x78c */
+ __IO CFG_DDR_SGMII_PHY_rpc228_TypeDef rpc228; /*!< Offset: 0x790 */
+ __IO CFG_DDR_SGMII_PHY_rpc229_TypeDef rpc229; /*!< Offset: 0x794 */
+ __IO CFG_DDR_SGMII_PHY_rpc230_TypeDef rpc230; /*!< Offset: 0x798 */
+ __IO CFG_DDR_SGMII_PHY_rpc231_TypeDef rpc231; /*!< Offset: 0x79c */
+ __IO CFG_DDR_SGMII_PHY_rpc232_TypeDef rpc232; /*!< Offset: 0x7a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc233_TypeDef rpc233; /*!< Offset: 0x7a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc234_TypeDef rpc234; /*!< Offset: 0x7a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc235_TypeDef rpc235; /*!< Offset: 0x7ac */
+ __IO CFG_DDR_SGMII_PHY_rpc236_TypeDef rpc236; /*!< Offset: 0x7b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc237_TypeDef rpc237; /*!< Offset: 0x7b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc238_TypeDef rpc238; /*!< Offset: 0x7b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc239_TypeDef rpc239; /*!< Offset: 0x7bc */
+ __IO CFG_DDR_SGMII_PHY_rpc240_TypeDef rpc240; /*!< Offset: 0x7c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc241_TypeDef rpc241; /*!< Offset: 0x7c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc242_TypeDef rpc242; /*!< Offset: 0x7c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc243_TypeDef rpc243; /*!< Offset: 0x7cc */
+ __IO CFG_DDR_SGMII_PHY_rpc244_TypeDef rpc244; /*!< Offset: 0x7d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc245_TypeDef rpc245; /*!< Offset: 0x7d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc246_TypeDef rpc246; /*!< Offset: 0x7d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc247_TypeDef rpc247; /*!< Offset: 0x7dc */
+ __IO CFG_DDR_SGMII_PHY_rpc248_TypeDef rpc248; /*!< Offset: 0x7e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc249_TypeDef rpc249; /*!< Offset: 0x7e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc250_TypeDef rpc250; /*!< Offset: 0x7e8 */
+ __IO CFG_DDR_SGMII_PHY_spio251_TypeDef spio251; /*!< Offset: 0x7ec */
+ __IO CFG_DDR_SGMII_PHY_spio252_TypeDef spio252; /*!< Offset: 0x7f0 */
+ __IO CFG_DDR_SGMII_PHY_spio253_TypeDef spio253; /*!< Offset: 0x7f4 */
+ __I uint32_t UNUSED_SPACE8[2]; /*!< Offset: 0x7f8 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_TypeDef SOFT_RESET_TIP; /*!< Offset: 0x800 */
+ __IO CFG_DDR_SGMII_PHY_rank_select_TypeDef rank_select; /*!< Offset: 0x804 */
+ __IO CFG_DDR_SGMII_PHY_lane_select_TypeDef lane_select; /*!< Offset: 0x808 */
+ __IO CFG_DDR_SGMII_PHY_training_skip_TypeDef training_skip; /*!< Offset: 0x80c */
+ __IO CFG_DDR_SGMII_PHY_training_start_TypeDef training_start; /*!< Offset: 0x810 */
+ __I CFG_DDR_SGMII_PHY_training_status_TypeDef training_status; /*!< Offset: 0x814 */
+ __IO CFG_DDR_SGMII_PHY_training_reset_TypeDef training_reset; /*!< Offset: 0x818 */
+ __I CFG_DDR_SGMII_PHY_gt_err_comb_TypeDef gt_err_comb; /*!< Offset: 0x81c */
+ __I CFG_DDR_SGMII_PHY_gt_clk_sel_TypeDef gt_clk_sel; /*!< Offset: 0x820 */
+ __I CFG_DDR_SGMII_PHY_gt_txdly_TypeDef gt_txdly; /*!< Offset: 0x824 */
+ __I CFG_DDR_SGMII_PHY_gt_steps_180_TypeDef gt_steps_180; /*!< Offset: 0x828 */
+ __I CFG_DDR_SGMII_PHY_gt_state_TypeDef gt_state; /*!< Offset: 0x82c */
+ __I CFG_DDR_SGMII_PHY_wl_delay_0_TypeDef wl_delay_0; /*!< Offset: 0x830 */
+ __I CFG_DDR_SGMII_PHY_dq_dqs_err_done_TypeDef dq_dqs_err_done; /*!< Offset: 0x834 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_window_TypeDef dqdqs_window; /*!< Offset: 0x838 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_state_TypeDef dqdqs_state; /*!< Offset: 0x83c */
+ __I CFG_DDR_SGMII_PHY_delta0_TypeDef delta0; /*!< Offset: 0x840 */
+ __I CFG_DDR_SGMII_PHY_delta1_TypeDef delta1; /*!< Offset: 0x844 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status0_TypeDef dqdqs_status0; /*!< Offset: 0x848 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status1_TypeDef dqdqs_status1; /*!< Offset: 0x84c */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status2_TypeDef dqdqs_status2; /*!< Offset: 0x850 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status3_TypeDef dqdqs_status3; /*!< Offset: 0x854 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status4_TypeDef dqdqs_status4; /*!< Offset: 0x858 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status5_TypeDef dqdqs_status5; /*!< Offset: 0x85c */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status6_TypeDef dqdqs_status6; /*!< Offset: 0x860 */
+ __I CFG_DDR_SGMII_PHY_addcmd_status0_TypeDef addcmd_status0; /*!< Offset: 0x864 */
+ __I CFG_DDR_SGMII_PHY_addcmd_status1_TypeDef addcmd_status1; /*!< Offset: 0x868 */
+ __I CFG_DDR_SGMII_PHY_addcmd_answer_TypeDef addcmd_answer; /*!< Offset: 0x86c */
+ __I CFG_DDR_SGMII_PHY_bclksclk_answer_TypeDef bclksclk_answer; /*!< Offset: 0x870 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_wrcalib_offset_TypeDef dqdqs_wrcalib_offset; /*!< Offset: 0x874 */
+ __IO CFG_DDR_SGMII_PHY_expert_mode_en_TypeDef expert_mode_en; /*!< Offset: 0x878 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg0_TypeDef expert_dlycnt_move_reg0; /*!< Offset: 0x87c */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg1_TypeDef expert_dlycnt_move_reg1; /*!< Offset: 0x880 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg0_TypeDef expert_dlycnt_direction_reg0; /*!< Offset: 0x884 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg1_TypeDef expert_dlycnt_direction_reg1; /*!< Offset: 0x888 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg0_TypeDef expert_dlycnt_load_reg0; /*!< Offset: 0x88c */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg1_TypeDef expert_dlycnt_load_reg1; /*!< Offset: 0x890 */
+ __I CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg0_TypeDef expert_dlycnt_oor_reg0; /*!< Offset: 0x894 */
+ __I CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg1_TypeDef expert_dlycnt_oor_reg1; /*!< Offset: 0x898 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_mv_rd_dly_reg_TypeDef expert_dlycnt_mv_rd_dly_reg; /*!< Offset: 0x89c */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_pause_TypeDef expert_dlycnt_pause; /*!< Offset: 0x8a0 */
+ __IO CFG_DDR_SGMII_PHY_expert_pllcnt_TypeDef expert_pllcnt; /*!< Offset: 0x8a4 */
+ __I CFG_DDR_SGMII_PHY_expert_dqlane_readback_TypeDef expert_dqlane_readback; /*!< Offset: 0x8a8 */
+ __I CFG_DDR_SGMII_PHY_expert_addcmd_ln_readback_TypeDef expert_addcmd_ln_readback; /*!< Offset: 0x8ac */
+ __IO CFG_DDR_SGMII_PHY_expert_read_gate_controls_TypeDef expert_read_gate_controls; /*!< Offset: 0x8b0 */
+ __I CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization0_TypeDef expert_dq_dqs_optimization0; /*!< Offset: 0x8b4 */
+ __I CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization1_TypeDef expert_dq_dqs_optimization1; /*!< Offset: 0x8b8 */
+ __IO CFG_DDR_SGMII_PHY_expert_wrcalib_TypeDef expert_wrcalib; /*!< Offset: 0x8bc */
+ __IO CFG_DDR_SGMII_PHY_expert_calif_TypeDef expert_calif; /*!< Offset: 0x8c0 */
+ __I CFG_DDR_SGMII_PHY_expert_calif_readback_TypeDef expert_calif_readback; /*!< Offset: 0x8c4 */
+ __I CFG_DDR_SGMII_PHY_expert_calif_readback1_TypeDef expert_calif_readback1; /*!< Offset: 0x8c8 */
+ __IO CFG_DDR_SGMII_PHY_expert_dfi_status_override_to_shim_TypeDef expert_dfi_status_override_to_shim; /*!< Offset: 0x8cc */
+ __IO CFG_DDR_SGMII_PHY_tip_cfg_params_TypeDef tip_cfg_params; /*!< Offset: 0x8d0 */
+ __IO CFG_DDR_SGMII_PHY_tip_vref_param_TypeDef tip_vref_param; /*!< Offset: 0x8d4 */
+ __IO CFG_DDR_SGMII_PHY_lane_alignment_fifo_control_TypeDef lane_alignment_fifo_control; /*!< Offset: 0x8d8 */
+ __I uint32_t UNUSED_SPACE9[201]; /*!< Offset: 0x8dc */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_SGMII_TypeDef SOFT_RESET_SGMII; /*!< Offset: 0xc00 */
+ __IO CFG_DDR_SGMII_PHY_SGMII_MODE_TypeDef SGMII_MODE; /*!< Offset: 0xc04 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CNTL_TypeDef PLL_CNTL; /*!< Offset: 0xc08 */
+ __IO CFG_DDR_SGMII_PHY_CH0_CNTL_TypeDef CH0_CNTL; /*!< Offset: 0xc0c */
+ __IO CFG_DDR_SGMII_PHY_CH1_CNTL_TypeDef CH1_CNTL; /*!< Offset: 0xc10 */
+ __IO CFG_DDR_SGMII_PHY_RECAL_CNTL_TypeDef RECAL_CNTL; /*!< Offset: 0xc14 */
+ __IO CFG_DDR_SGMII_PHY_CLK_CNTL_TypeDef CLK_CNTL; /*!< Offset: 0xc18 */
+ __IO CFG_DDR_SGMII_PHY_DYN_CNTL_TypeDef DYN_CNTL; /*!< Offset: 0xc1c */
+ __IO CFG_DDR_SGMII_PHY_PVT_STAT_TypeDef PVT_STAT; /*!< Offset: 0xc20 */
+ __IO CFG_DDR_SGMII_PHY_SPARE_CNTL_TypeDef SPARE_CNTL; /*!< Offset: 0xc24 */
+ __I CFG_DDR_SGMII_PHY_SPARE_STAT_TypeDef SPARE_STAT; /*!< Offset: 0xc28 */
+} CFG_DDR_SGMII_PHY_TypeDef;
+
+
+/******************************************************************************/
+/* finish of CFG_DDR_SGMII_PHY definitions */
+/******************************************************************************/
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_SGMII_PHY_DEFS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_regs.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_regs.h
new file mode 100644
index 00000000..51f72e9b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_regs.h
@@ -0,0 +1,5558 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_hal.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Register bit offsets and masks definitions for MPFS MSS DDR
+ * This was generated directly from the RTL
+ *
+ */
+
+#ifndef MSS_DDR_REGS_H_
+#define MSS_DDR_REGS_H_
+
+#include "../mss_sysreg.h"
+#include "mss_ddr_sgmii_phy_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------- DDR -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+
+/*============================== CFG_DDR_SGMII_PHY definitions ===========================*/
+
+/* see mss_ddr_sgmii_phy_defs.h */
+
+/******************************************************************************/
+/* finish of CFG_DDR_SGMII_PHY definitions */
+/******************************************************************************/
+
+
+/*============================== DDR_CSR_APB definitions ===========================*/
+
+typedef union{ /*!< CFG_MANUAL_ADDRESS_MAP register definition*/
+ __IO uint32_t CFG_MANUAL_ADDRESS_MAP;
+ struct
+ {
+ __IO uint32_t cfg_manual_address_map :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MANUAL_ADDRESS_MAP_TypeDef;
+
+typedef union{ /*!< CFG_CHIPADDR_MAP register definition*/
+ __IO uint32_t CFG_CHIPADDR_MAP;
+ struct
+ {
+ __IO uint32_t cfg_chipaddr_map :24;
+ __I uint32_t reserved :8;
+ } bitfield;
+} DDR_CSR_APB_CFG_CHIPADDR_MAP_TypeDef;
+
+typedef union{ /*!< CFG_CIDADDR_MAP register definition*/
+ __IO uint32_t CFG_CIDADDR_MAP;
+ struct
+ {
+ __IO uint32_t cfg_cidaddr_map :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_CFG_CIDADDR_MAP_TypeDef;
+
+typedef union{ /*!< CFG_MB_AUTOPCH_COL_BIT_POS_LOW register definition*/
+ __IO uint32_t CFG_MB_AUTOPCH_COL_BIT_POS_LOW;
+ struct
+ {
+ __IO uint32_t cfg_mb_autopch_col_bit_pos_low :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_LOW_TypeDef;
+
+typedef union{ /*!< CFG_MB_AUTOPCH_COL_BIT_POS_HIGH register definition*/
+ __IO uint32_t CFG_MB_AUTOPCH_COL_BIT_POS_HIGH;
+ struct
+ {
+ __IO uint32_t cfg_mb_autopch_col_bit_pos_high :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH_TypeDef;
+
+typedef union{ /*!< CFG_BANKADDR_MAP_0 register definition*/
+ __IO uint32_t CFG_BANKADDR_MAP_0;
+ struct
+ {
+ __IO uint32_t cfg_bankaddr_map_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BANKADDR_MAP_0_TypeDef;
+
+typedef union{ /*!< CFG_BANKADDR_MAP_1 register definition*/
+ __IO uint32_t CFG_BANKADDR_MAP_1;
+ struct
+ {
+ __IO uint32_t cfg_bankaddr_map_1 :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_BANKADDR_MAP_1_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_0 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_0;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_0_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_1 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_1;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_1 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_1_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_2 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_2;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_2 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_2_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_3 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_3;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_3 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_3_TypeDef;
+
+typedef union{ /*!< CFG_COLADDR_MAP_0 register definition*/
+ __IO uint32_t CFG_COLADDR_MAP_0;
+ struct
+ {
+ __IO uint32_t cfg_coladdr_map_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_COLADDR_MAP_0_TypeDef;
+
+typedef union{ /*!< CFG_COLADDR_MAP_1 register definition*/
+ __IO uint32_t CFG_COLADDR_MAP_1;
+ struct
+ {
+ __IO uint32_t cfg_coladdr_map_1 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_COLADDR_MAP_1_TypeDef;
+
+typedef union{ /*!< CFG_COLADDR_MAP_2 register definition*/
+ __IO uint32_t CFG_COLADDR_MAP_2;
+ struct
+ {
+ __IO uint32_t cfg_coladdr_map_2 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_COLADDR_MAP_2_TypeDef;
+
+typedef union{ /*!< CFG_VRCG_ENABLE register definition*/
+ __IO uint32_t CFG_VRCG_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_vrcg_enable :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_VRCG_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_VRCG_DISABLE register definition*/
+ __IO uint32_t CFG_VRCG_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_vrcg_disable :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_VRCG_DISABLE_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_LATENCY_SET register definition*/
+ __IO uint32_t CFG_WRITE_LATENCY_SET;
+ struct
+ {
+ __IO uint32_t cfg_write_latency_set :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_LATENCY_SET_TypeDef;
+
+typedef union{ /*!< CFG_THERMAL_OFFSET register definition*/
+ __IO uint32_t CFG_THERMAL_OFFSET;
+ struct
+ {
+ __IO uint32_t cfg_thermal_offset :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_THERMAL_OFFSET_TypeDef;
+
+typedef union{ /*!< CFG_SOC_ODT register definition*/
+ __IO uint32_t CFG_SOC_ODT;
+ struct
+ {
+ __IO uint32_t cfg_soc_odt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_SOC_ODT_TypeDef;
+
+typedef union{ /*!< CFG_ODTE_CK register definition*/
+ __IO uint32_t CFG_ODTE_CK;
+ struct
+ {
+ __IO uint32_t cfg_odte_ck :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODTE_CK_TypeDef;
+
+typedef union{ /*!< CFG_ODTE_CS register definition*/
+ __IO uint32_t CFG_ODTE_CS;
+ struct
+ {
+ __IO uint32_t cfg_odte_cs :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODTE_CS_TypeDef;
+
+typedef union{ /*!< CFG_ODTD_CA register definition*/
+ __IO uint32_t CFG_ODTD_CA;
+ struct
+ {
+ __IO uint32_t cfg_odtd_ca :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODTD_CA_TypeDef;
+
+typedef union{ /*!< CFG_LPDDR4_FSP_OP register definition*/
+ __IO uint32_t CFG_LPDDR4_FSP_OP;
+ struct
+ {
+ __IO uint32_t cfg_lpddr4_fsp_op :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LPDDR4_FSP_OP_TypeDef;
+
+typedef union{ /*!< CFG_GENERATE_REFRESH_ON_SRX register definition*/
+ __IO uint32_t CFG_GENERATE_REFRESH_ON_SRX;
+ struct
+ {
+ __IO uint32_t cfg_generate_refresh_on_srx :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_GENERATE_REFRESH_ON_SRX_TypeDef;
+
+typedef union{ /*!< CFG_DBI_CL register definition*/
+ __IO uint32_t CFG_DBI_CL;
+ struct
+ {
+ __IO uint32_t cfg_dbi_cl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_DBI_CL_TypeDef;
+
+typedef union{ /*!< CFG_NON_DBI_CL register definition*/
+ __IO uint32_t CFG_NON_DBI_CL;
+ struct
+ {
+ __IO uint32_t cfg_non_dbi_cl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_NON_DBI_CL_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_WRITE_DATA_0 register definition*/
+ __IO uint32_t INIT_FORCE_WRITE_DATA_0;
+ struct
+ {
+ __IO uint32_t init_force_write_data_0 :9;
+ __I uint32_t reserved :23;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_WRITE_DATA_0_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_CRC register definition*/
+ __IO uint32_t CFG_WRITE_CRC;
+ struct
+ {
+ __IO uint32_t cfg_write_crc :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_CRC_TypeDef;
+
+typedef union{ /*!< CFG_MPR_READ_FORMAT register definition*/
+ __IO uint32_t CFG_MPR_READ_FORMAT;
+ struct
+ {
+ __IO uint32_t cfg_mpr_read_format :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_MPR_READ_FORMAT_TypeDef;
+
+typedef union{ /*!< CFG_WR_CMD_LAT_CRC_DM register definition*/
+ __IO uint32_t CFG_WR_CMD_LAT_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wr_cmd_lat_crc_dm :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_CMD_LAT_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_FINE_GRAN_REF_MODE register definition*/
+ __IO uint32_t CFG_FINE_GRAN_REF_MODE;
+ struct
+ {
+ __IO uint32_t cfg_fine_gran_ref_mode :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_FINE_GRAN_REF_MODE_TypeDef;
+
+typedef union{ /*!< CFG_TEMP_SENSOR_READOUT register definition*/
+ __IO uint32_t CFG_TEMP_SENSOR_READOUT;
+ struct
+ {
+ __IO uint32_t cfg_temp_sensor_readout :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TEMP_SENSOR_READOUT_TypeDef;
+
+typedef union{ /*!< CFG_PER_DRAM_ADDR_EN register definition*/
+ __IO uint32_t CFG_PER_DRAM_ADDR_EN;
+ struct
+ {
+ __IO uint32_t cfg_per_dram_addr_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_PER_DRAM_ADDR_EN_TypeDef;
+
+typedef union{ /*!< CFG_GEARDOWN_MODE register definition*/
+ __IO uint32_t CFG_GEARDOWN_MODE;
+ struct
+ {
+ __IO uint32_t cfg_geardown_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_GEARDOWN_MODE_TypeDef;
+
+typedef union{ /*!< CFG_WR_PREAMBLE register definition*/
+ __IO uint32_t CFG_WR_PREAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_wr_preamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_PREAMBLE_TypeDef;
+
+typedef union{ /*!< CFG_RD_PREAMBLE register definition*/
+ __IO uint32_t CFG_RD_PREAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_rd_preamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_PREAMBLE_TypeDef;
+
+typedef union{ /*!< CFG_RD_PREAMB_TRN_MODE register definition*/
+ __IO uint32_t CFG_RD_PREAMB_TRN_MODE;
+ struct
+ {
+ __IO uint32_t cfg_rd_preamb_trn_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_PREAMB_TRN_MODE_TypeDef;
+
+typedef union{ /*!< CFG_SR_ABORT register definition*/
+ __IO uint32_t CFG_SR_ABORT;
+ struct
+ {
+ __IO uint32_t cfg_sr_abort :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_SR_ABORT_TypeDef;
+
+typedef union{ /*!< CFG_CS_TO_CMDADDR_LATENCY register definition*/
+ __IO uint32_t CFG_CS_TO_CMDADDR_LATENCY;
+ struct
+ {
+ __IO uint32_t cfg_cs_to_cmdaddr_latency :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CS_TO_CMDADDR_LATENCY_TypeDef;
+
+typedef union{ /*!< CFG_INT_VREF_MON register definition*/
+ __IO uint32_t CFG_INT_VREF_MON;
+ struct
+ {
+ __IO uint32_t cfg_int_vref_mon :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_INT_VREF_MON_TypeDef;
+
+typedef union{ /*!< CFG_TEMP_CTRL_REF_MODE register definition*/
+ __IO uint32_t CFG_TEMP_CTRL_REF_MODE;
+ struct
+ {
+ __IO uint32_t cfg_temp_ctrl_ref_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TEMP_CTRL_REF_MODE_TypeDef;
+
+typedef union{ /*!< CFG_TEMP_CTRL_REF_RANGE register definition*/
+ __IO uint32_t CFG_TEMP_CTRL_REF_RANGE;
+ struct
+ {
+ __IO uint32_t cfg_temp_ctrl_ref_range :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TEMP_CTRL_REF_RANGE_TypeDef;
+
+typedef union{ /*!< CFG_MAX_PWR_DOWN_MODE register definition*/
+ __IO uint32_t CFG_MAX_PWR_DOWN_MODE;
+ struct
+ {
+ __IO uint32_t cfg_max_pwr_down_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MAX_PWR_DOWN_MODE_TypeDef;
+
+typedef union{ /*!< CFG_READ_DBI register definition*/
+ __IO uint32_t CFG_READ_DBI;
+ struct
+ {
+ __IO uint32_t cfg_read_dbi :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_DBI_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_DBI register definition*/
+ __IO uint32_t CFG_WRITE_DBI;
+ struct
+ {
+ __IO uint32_t cfg_write_dbi :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_DBI_TypeDef;
+
+typedef union{ /*!< CFG_DATA_MASK register definition*/
+ __IO uint32_t CFG_DATA_MASK;
+ struct
+ {
+ __IO uint32_t cfg_data_mask :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DATA_MASK_TypeDef;
+
+typedef union{ /*!< CFG_CA_PARITY_PERSIST_ERR register definition*/
+ __IO uint32_t CFG_CA_PARITY_PERSIST_ERR;
+ struct
+ {
+ __IO uint32_t cfg_ca_parity_persist_err :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_PARITY_PERSIST_ERR_TypeDef;
+
+typedef union{ /*!< CFG_RTT_PARK register definition*/
+ __IO uint32_t CFG_RTT_PARK;
+ struct
+ {
+ __IO uint32_t cfg_rtt_park :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTT_PARK_TypeDef;
+
+typedef union{ /*!< CFG_ODT_INBUF_4_PD register definition*/
+ __IO uint32_t CFG_ODT_INBUF_4_PD;
+ struct
+ {
+ __IO uint32_t cfg_odt_inbuf_4_pd :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_INBUF_4_PD_TypeDef;
+
+typedef union{ /*!< CFG_CA_PARITY_ERR_STATUS register definition*/
+ __IO uint32_t CFG_CA_PARITY_ERR_STATUS;
+ struct
+ {
+ __IO uint32_t cfg_ca_parity_err_status :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_PARITY_ERR_STATUS_TypeDef;
+
+typedef union{ /*!< CFG_CRC_ERROR_CLEAR register definition*/
+ __IO uint32_t CFG_CRC_ERROR_CLEAR;
+ struct
+ {
+ __IO uint32_t cfg_crc_error_clear :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CRC_ERROR_CLEAR_TypeDef;
+
+typedef union{ /*!< CFG_CA_PARITY_LATENCY register definition*/
+ __IO uint32_t CFG_CA_PARITY_LATENCY;
+ struct
+ {
+ __IO uint32_t cfg_ca_parity_latency :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_PARITY_LATENCY_TypeDef;
+
+typedef union{ /*!< CFG_CCD_S register definition*/
+ __IO uint32_t CFG_CCD_S;
+ struct
+ {
+ __IO uint32_t cfg_ccd_s :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CCD_S_TypeDef;
+
+typedef union{ /*!< CFG_CCD_L register definition*/
+ __IO uint32_t CFG_CCD_L;
+ struct
+ {
+ __IO uint32_t cfg_ccd_l :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_CCD_L_TypeDef;
+
+typedef union{ /*!< CFG_VREFDQ_TRN_ENABLE register definition*/
+ __IO uint32_t CFG_VREFDQ_TRN_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_vrefdq_trn_enable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_VREFDQ_TRN_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_VREFDQ_TRN_RANGE register definition*/
+ __IO uint32_t CFG_VREFDQ_TRN_RANGE;
+ struct
+ {
+ __IO uint32_t cfg_vrefdq_trn_range :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_VREFDQ_TRN_RANGE_TypeDef;
+
+typedef union{ /*!< CFG_VREFDQ_TRN_VALUE register definition*/
+ __IO uint32_t CFG_VREFDQ_TRN_VALUE;
+ struct
+ {
+ __IO uint32_t cfg_vrefdq_trn_value :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_VREFDQ_TRN_VALUE_TypeDef;
+
+typedef union{ /*!< CFG_RRD_S register definition*/
+ __IO uint32_t CFG_RRD_S;
+ struct
+ {
+ __IO uint32_t cfg_rrd_s :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_S_TypeDef;
+
+typedef union{ /*!< CFG_RRD_L register definition*/
+ __IO uint32_t CFG_RRD_L;
+ struct
+ {
+ __IO uint32_t cfg_rrd_l :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_L_TypeDef;
+
+typedef union{ /*!< CFG_WTR_S register definition*/
+ __IO uint32_t CFG_WTR_S;
+ struct
+ {
+ __IO uint32_t cfg_wtr_s :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_S_TypeDef;
+
+typedef union{ /*!< CFG_WTR_L register definition*/
+ __IO uint32_t CFG_WTR_L;
+ struct
+ {
+ __IO uint32_t cfg_wtr_l :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_L_TypeDef;
+
+typedef union{ /*!< CFG_WTR_S_CRC_DM register definition*/
+ __IO uint32_t CFG_WTR_S_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wtr_s_crc_dm :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_S_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_WTR_L_CRC_DM register definition*/
+ __IO uint32_t CFG_WTR_L_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wtr_l_crc_dm :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_L_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_WR_CRC_DM register definition*/
+ __IO uint32_t CFG_WR_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wr_crc_dm :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_RFC1 register definition*/
+ __IO uint32_t CFG_RFC1;
+ struct
+ {
+ __IO uint32_t cfg_rfc1 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC1_TypeDef;
+
+typedef union{ /*!< CFG_RFC2 register definition*/
+ __IO uint32_t CFG_RFC2;
+ struct
+ {
+ __IO uint32_t cfg_rfc2 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC2_TypeDef;
+
+typedef union{ /*!< CFG_RFC4 register definition*/
+ __IO uint32_t CFG_RFC4;
+ struct
+ {
+ __IO uint32_t cfg_rfc4 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC4_TypeDef;
+
+typedef union{ /*!< CFG_NIBBLE_DEVICES register definition*/
+ __IO uint32_t CFG_NIBBLE_DEVICES;
+ struct
+ {
+ __IO uint32_t cfg_nibble_devices :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_NIBBLE_DEVICES_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS0_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS0_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs0_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS0_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS0_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs0_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS1_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS1_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS1_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS1_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs1_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS2_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS2_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS2_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS2_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs2_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS3_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS3_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs3_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS3_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS3_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs3_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS4_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS4_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs4_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS4_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS4_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs4_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS5_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS5_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs5_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS5_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS5_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs5_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS6_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS6_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs6_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS6_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS6_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs6_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS7_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS7_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs7_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS7_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS7_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs7_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS8_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS8_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs8_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS8_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS8_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs8_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS9_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS9_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs9_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS9_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS9_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs9_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS10_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS10_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs10_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS10_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS10_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs10_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS11_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS11_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs11_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS11_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS11_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs11_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS12_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS12_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs12_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS12_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS12_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs12_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS13_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS13_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs13_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS13_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS13_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs13_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS14_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS14_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs14_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS14_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS14_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs14_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS15_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS15_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs15_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS15_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS15_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs15_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_1_TypeDef;
+
+typedef union{ /*!< CFG_NUM_LOGICAL_RANKS_PER_3DS register definition*/
+ __IO uint32_t CFG_NUM_LOGICAL_RANKS_PER_3DS;
+ struct
+ {
+ __IO uint32_t cfg_num_logical_ranks_per_3ds :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_NUM_LOGICAL_RANKS_PER_3DS_TypeDef;
+
+typedef union{ /*!< CFG_RFC_DLR1 register definition*/
+ __IO uint32_t CFG_RFC_DLR1;
+ struct
+ {
+ __IO uint32_t cfg_rfc_dlr1 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_DLR1_TypeDef;
+
+typedef union{ /*!< CFG_RFC_DLR2 register definition*/
+ __IO uint32_t CFG_RFC_DLR2;
+ struct
+ {
+ __IO uint32_t cfg_rfc_dlr2 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_DLR2_TypeDef;
+
+typedef union{ /*!< CFG_RFC_DLR4 register definition*/
+ __IO uint32_t CFG_RFC_DLR4;
+ struct
+ {
+ __IO uint32_t cfg_rfc_dlr4 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_DLR4_TypeDef;
+
+typedef union{ /*!< CFG_RRD_DLR register definition*/
+ __IO uint32_t CFG_RRD_DLR;
+ struct
+ {
+ __IO uint32_t cfg_rrd_dlr :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_DLR_TypeDef;
+
+typedef union{ /*!< CFG_FAW_DLR register definition*/
+ __IO uint32_t CFG_FAW_DLR;
+ struct
+ {
+ __IO uint32_t cfg_faw_dlr :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_FAW_DLR_TypeDef;
+
+typedef union{ /*!< CFG_ADVANCE_ACTIVATE_READY register definition*/
+ __IO uint32_t CFG_ADVANCE_ACTIVATE_READY;
+ struct
+ {
+ __IO uint32_t cfg_advance_activate_ready :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ADVANCE_ACTIVATE_READY_TypeDef;
+
+typedef union{ /*!< CTRLR_SOFT_RESET_N register definition*/
+ __IO uint32_t CTRLR_SOFT_RESET_N;
+ struct
+ {
+ __IO uint32_t ctrlr_soft_reset_n :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_SOFT_RESET_N_TypeDef;
+
+typedef union{ /*!< CFG_LOOKAHEAD_PCH register definition*/
+ __IO uint32_t CFG_LOOKAHEAD_PCH;
+ struct
+ {
+ __IO uint32_t cfg_lookahead_pch :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LOOKAHEAD_PCH_TypeDef;
+
+typedef union{ /*!< CFG_LOOKAHEAD_ACT register definition*/
+ __IO uint32_t CFG_LOOKAHEAD_ACT;
+ struct
+ {
+ __IO uint32_t cfg_lookahead_act :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LOOKAHEAD_ACT_TypeDef;
+
+typedef union{ /*!< INIT_AUTOINIT_DISABLE register definition*/
+ __IO uint32_t INIT_AUTOINIT_DISABLE;
+ struct
+ {
+ __IO uint32_t init_autoinit_disable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_AUTOINIT_DISABLE_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_RESET register definition*/
+ __IO uint32_t INIT_FORCE_RESET;
+ struct
+ {
+ __IO uint32_t init_force_reset :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_RESET_TypeDef;
+
+typedef union{ /*!< INIT_GEARDOWN_EN register definition*/
+ __IO uint32_t INIT_GEARDOWN_EN;
+ struct
+ {
+ __IO uint32_t init_geardown_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_GEARDOWN_EN_TypeDef;
+
+typedef union{ /*!< INIT_DISABLE_CKE register definition*/
+ __IO uint32_t INIT_DISABLE_CKE;
+ struct
+ {
+ __IO uint32_t init_disable_cke :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_DISABLE_CKE_TypeDef;
+
+typedef union{ /*!< INIT_CS register definition*/
+ __IO uint32_t INIT_CS;
+ struct
+ {
+ __IO uint32_t init_cs :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_CS_TypeDef;
+
+typedef union{ /*!< INIT_PRECHARGE_ALL register definition*/
+ __IO uint32_t INIT_PRECHARGE_ALL;
+ struct
+ {
+ __IO uint32_t init_precharge_all :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_PRECHARGE_ALL_TypeDef;
+
+typedef union{ /*!< INIT_REFRESH register definition*/
+ __IO uint32_t INIT_REFRESH;
+ struct
+ {
+ __IO uint32_t init_refresh :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_REFRESH_TypeDef;
+
+typedef union{ /*!< INIT_ZQ_CAL_REQ register definition*/
+ __IO uint32_t INIT_ZQ_CAL_REQ;
+ struct
+ {
+ __IO uint32_t init_zq_cal_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ZQ_CAL_REQ_TypeDef;
+
+typedef union{ /*!< INIT_ACK register definition*/
+ __I uint32_t INIT_ACK;
+ struct
+ {
+ __I uint32_t init_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ACK_TypeDef;
+
+typedef union{ /*!< CFG_BL register definition*/
+ __IO uint32_t CFG_BL;
+ struct
+ {
+ __IO uint32_t cfg_bl :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_BL_TypeDef;
+
+typedef union{ /*!< CTRLR_INIT register definition*/
+ __IO uint32_t CTRLR_INIT;
+ struct
+ {
+ __IO uint32_t ctrlr_init :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_INIT_TypeDef;
+
+typedef union{ /*!< CTRLR_INIT_DONE register definition*/
+ __I uint32_t CTRLR_INIT_DONE;
+ struct
+ {
+ __I uint32_t ctrlr_init_done :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_INIT_DONE_TypeDef;
+
+typedef union{ /*!< CFG_AUTO_REF_EN register definition*/
+ __IO uint32_t CFG_AUTO_REF_EN;
+ struct
+ {
+ __IO uint32_t cfg_auto_ref_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_AUTO_REF_EN_TypeDef;
+
+typedef union{ /*!< CFG_RAS register definition*/
+ __IO uint32_t CFG_RAS;
+ struct
+ {
+ __IO uint32_t cfg_ras :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_RAS_TypeDef;
+
+typedef union{ /*!< CFG_RCD register definition*/
+ __IO uint32_t CFG_RCD;
+ struct
+ {
+ __IO uint32_t cfg_rcd :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_RCD_TypeDef;
+
+typedef union{ /*!< CFG_RRD register definition*/
+ __IO uint32_t CFG_RRD;
+ struct
+ {
+ __IO uint32_t cfg_rrd :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_TypeDef;
+
+typedef union{ /*!< CFG_RP register definition*/
+ __IO uint32_t CFG_RP;
+ struct
+ {
+ __IO uint32_t cfg_rp :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_RP_TypeDef;
+
+typedef union{ /*!< CFG_RC register definition*/
+ __IO uint32_t CFG_RC;
+ struct
+ {
+ __IO uint32_t cfg_rc :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_RC_TypeDef;
+
+typedef union{ /*!< CFG_FAW register definition*/
+ __IO uint32_t CFG_FAW;
+ struct
+ {
+ __IO uint32_t cfg_faw :9;
+ __I uint32_t reserved :23;
+ } bitfield;
+} DDR_CSR_APB_CFG_FAW_TypeDef;
+
+typedef union{ /*!< CFG_RFC register definition*/
+ __IO uint32_t CFG_RFC;
+ struct
+ {
+ __IO uint32_t cfg_rfc :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_TypeDef;
+
+typedef union{ /*!< CFG_RTP register definition*/
+ __IO uint32_t CFG_RTP;
+ struct
+ {
+ __IO uint32_t cfg_rtp :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTP_TypeDef;
+
+typedef union{ /*!< CFG_WR register definition*/
+ __IO uint32_t CFG_WR;
+ struct
+ {
+ __IO uint32_t cfg_wr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_TypeDef;
+
+typedef union{ /*!< CFG_WTR register definition*/
+ __IO uint32_t CFG_WTR;
+ struct
+ {
+ __IO uint32_t cfg_wtr :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_TypeDef;
+
+typedef union{ /*!< CFG_PASR register definition*/
+ __IO uint32_t CFG_PASR;
+ struct
+ {
+ __IO uint32_t cfg_pasr :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_PASR_TypeDef;
+
+typedef union{ /*!< CFG_XP register definition*/
+ __IO uint32_t CFG_XP;
+ struct
+ {
+ __IO uint32_t cfg_xp :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_XP_TypeDef;
+
+typedef union{ /*!< CFG_XSR register definition*/
+ __IO uint32_t CFG_XSR;
+ struct
+ {
+ __IO uint32_t cfg_xsr :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_XSR_TypeDef;
+
+typedef union{ /*!< CFG_CL register definition*/
+ __IO uint32_t CFG_CL;
+ struct
+ {
+ __IO uint32_t cfg_cl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_CL_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_WRITE register definition*/
+ __IO uint32_t CFG_READ_TO_WRITE;
+ struct
+ {
+ __IO uint32_t cfg_read_to_write :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_WRITE_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_WRITE register definition*/
+ __IO uint32_t CFG_WRITE_TO_WRITE;
+ struct
+ {
+ __IO uint32_t cfg_write_to_write :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_WRITE_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_READ register definition*/
+ __IO uint32_t CFG_READ_TO_READ;
+ struct
+ {
+ __IO uint32_t cfg_read_to_read :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_READ_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_READ register definition*/
+ __IO uint32_t CFG_WRITE_TO_READ;
+ struct
+ {
+ __IO uint32_t cfg_write_to_read :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_READ_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_WRITE_ODT register definition*/
+ __IO uint32_t CFG_READ_TO_WRITE_ODT;
+ struct
+ {
+ __IO uint32_t cfg_read_to_write_odt :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_WRITE_ODT_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_WRITE_ODT register definition*/
+ __IO uint32_t CFG_WRITE_TO_WRITE_ODT;
+ struct
+ {
+ __IO uint32_t cfg_write_to_write_odt :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_WRITE_ODT_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_READ_ODT register definition*/
+ __IO uint32_t CFG_READ_TO_READ_ODT;
+ struct
+ {
+ __IO uint32_t cfg_read_to_read_odt :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_READ_ODT_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_READ_ODT register definition*/
+ __IO uint32_t CFG_WRITE_TO_READ_ODT;
+ struct
+ {
+ __IO uint32_t cfg_write_to_read_odt :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_READ_ODT_TypeDef;
+
+typedef union{ /*!< CFG_MIN_READ_IDLE register definition*/
+ __IO uint32_t CFG_MIN_READ_IDLE;
+ struct
+ {
+ __IO uint32_t cfg_min_read_idle :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_MIN_READ_IDLE_TypeDef;
+
+typedef union{ /*!< CFG_MRD register definition*/
+ __IO uint32_t CFG_MRD;
+ struct
+ {
+ __IO uint32_t cfg_mrd :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRD_TypeDef;
+
+typedef union{ /*!< CFG_BT register definition*/
+ __IO uint32_t CFG_BT;
+ struct
+ {
+ __IO uint32_t cfg_bt :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_BT_TypeDef;
+
+typedef union{ /*!< CFG_DS register definition*/
+ __IO uint32_t CFG_DS;
+ struct
+ {
+ __IO uint32_t cfg_ds :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_DS_TypeDef;
+
+typedef union{ /*!< CFG_QOFF register definition*/
+ __IO uint32_t CFG_QOFF;
+ struct
+ {
+ __IO uint32_t cfg_qoff :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_QOFF_TypeDef;
+
+typedef union{ /*!< CFG_RTT register definition*/
+ __IO uint32_t CFG_RTT;
+ struct
+ {
+ __IO uint32_t cfg_rtt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTT_TypeDef;
+
+typedef union{ /*!< CFG_DLL_DISABLE register definition*/
+ __IO uint32_t CFG_DLL_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_dll_disable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DLL_DISABLE_TypeDef;
+
+typedef union{ /*!< CFG_REF_PER register definition*/
+ __IO uint32_t CFG_REF_PER;
+ struct
+ {
+ __IO uint32_t cfg_ref_per :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_REF_PER_TypeDef;
+
+typedef union{ /*!< CFG_STARTUP_DELAY register definition*/
+ __IO uint32_t CFG_STARTUP_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_startup_delay :19;
+ __I uint32_t reserved :13;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARTUP_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_MEM_COLBITS register definition*/
+ __IO uint32_t CFG_MEM_COLBITS;
+ struct
+ {
+ __IO uint32_t cfg_mem_colbits :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_COLBITS_TypeDef;
+
+typedef union{ /*!< CFG_MEM_ROWBITS register definition*/
+ __IO uint32_t CFG_MEM_ROWBITS;
+ struct
+ {
+ __IO uint32_t cfg_mem_rowbits :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_ROWBITS_TypeDef;
+
+typedef union{ /*!< CFG_MEM_BANKBITS register definition*/
+ __IO uint32_t CFG_MEM_BANKBITS;
+ struct
+ {
+ __IO uint32_t cfg_mem_bankbits :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_BANKBITS_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS0 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS0;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs0 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS0_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS1 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS1;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs1 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS1_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS2 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS2;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS2_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS3 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS3;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs3 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS3_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS4 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS4;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs4 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS4_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS5 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS5;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs5 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS5_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS6 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS6;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs6 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS6_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS7 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS7;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs7 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS7_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS0 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS0;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs0 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS0_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS1 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS1;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs1 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS1_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS2 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS2;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS2_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS3 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS3;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs3 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS3_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS4 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS4;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs4 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS4_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS5 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS5;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs5 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS5_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS6 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS6;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs6 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS6_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS7 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS7;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs7 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS7_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_TURN_ON register definition*/
+ __IO uint32_t CFG_ODT_RD_TURN_ON;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_turn_on :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_TURN_ON_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_TURN_ON register definition*/
+ __IO uint32_t CFG_ODT_WR_TURN_ON;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_turn_on :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_TURN_ON_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_TURN_OFF register definition*/
+ __IO uint32_t CFG_ODT_RD_TURN_OFF;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_turn_off :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_TURN_OFF_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_TURN_OFF register definition*/
+ __IO uint32_t CFG_ODT_WR_TURN_OFF;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_turn_off :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_TURN_OFF_TypeDef;
+
+typedef union{ /*!< CFG_EMR3 register definition*/
+ __IO uint32_t CFG_EMR3;
+ struct
+ {
+ __IO uint32_t cfg_emr3 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_EMR3_TypeDef;
+
+typedef union{ /*!< CFG_TWO_T register definition*/
+ __IO uint32_t CFG_TWO_T;
+ struct
+ {
+ __IO uint32_t cfg_two_t :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TWO_T_TypeDef;
+
+typedef union{ /*!< CFG_TWO_T_SEL_CYCLE register definition*/
+ __IO uint32_t CFG_TWO_T_SEL_CYCLE;
+ struct
+ {
+ __IO uint32_t cfg_two_t_sel_cycle :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TWO_T_SEL_CYCLE_TypeDef;
+
+typedef union{ /*!< CFG_REGDIMM register definition*/
+ __IO uint32_t CFG_REGDIMM;
+ struct
+ {
+ __IO uint32_t cfg_regdimm :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REGDIMM_TypeDef;
+
+typedef union{ /*!< CFG_MOD register definition*/
+ __IO uint32_t CFG_MOD;
+ struct
+ {
+ __IO uint32_t cfg_mod :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_MOD_TypeDef;
+
+typedef union{ /*!< CFG_XS register definition*/
+ __IO uint32_t CFG_XS;
+ struct
+ {
+ __IO uint32_t cfg_xs :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_XS_TypeDef;
+
+typedef union{ /*!< CFG_XSDLL register definition*/
+ __IO uint32_t CFG_XSDLL;
+ struct
+ {
+ __IO uint32_t cfg_xsdll :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_XSDLL_TypeDef;
+
+typedef union{ /*!< CFG_XPR register definition*/
+ __IO uint32_t CFG_XPR;
+ struct
+ {
+ __IO uint32_t cfg_xpr :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_XPR_TypeDef;
+
+typedef union{ /*!< CFG_AL_MODE register definition*/
+ __IO uint32_t CFG_AL_MODE;
+ struct
+ {
+ __IO uint32_t cfg_al_mode :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AL_MODE_TypeDef;
+
+typedef union{ /*!< CFG_CWL register definition*/
+ __IO uint32_t CFG_CWL;
+ struct
+ {
+ __IO uint32_t cfg_cwl :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_CWL_TypeDef;
+
+typedef union{ /*!< CFG_BL_MODE register definition*/
+ __IO uint32_t CFG_BL_MODE;
+ struct
+ {
+ __IO uint32_t cfg_bl_mode :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_BL_MODE_TypeDef;
+
+typedef union{ /*!< CFG_TDQS register definition*/
+ __IO uint32_t CFG_TDQS;
+ struct
+ {
+ __IO uint32_t cfg_tdqs :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TDQS_TypeDef;
+
+typedef union{ /*!< CFG_RTT_WR register definition*/
+ __IO uint32_t CFG_RTT_WR;
+ struct
+ {
+ __IO uint32_t cfg_rtt_wr :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTT_WR_TypeDef;
+
+typedef union{ /*!< CFG_LP_ASR register definition*/
+ __IO uint32_t CFG_LP_ASR;
+ struct
+ {
+ __IO uint32_t cfg_lp_asr :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_LP_ASR_TypeDef;
+
+typedef union{ /*!< CFG_AUTO_SR register definition*/
+ __IO uint32_t CFG_AUTO_SR;
+ struct
+ {
+ __IO uint32_t cfg_auto_sr :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_AUTO_SR_TypeDef;
+
+typedef union{ /*!< CFG_SRT register definition*/
+ __IO uint32_t CFG_SRT;
+ struct
+ {
+ __IO uint32_t cfg_srt :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_SRT_TypeDef;
+
+typedef union{ /*!< CFG_ADDR_MIRROR register definition*/
+ __IO uint32_t CFG_ADDR_MIRROR;
+ struct
+ {
+ __IO uint32_t cfg_addr_mirror :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ADDR_MIRROR_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_TYPE register definition*/
+ __IO uint32_t CFG_ZQ_CAL_TYPE;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_type :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_TYPE_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_PER register definition*/
+ __IO uint32_t CFG_ZQ_CAL_PER;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_per :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_PER_TypeDef;
+
+typedef union{ /*!< CFG_AUTO_ZQ_CAL_EN register definition*/
+ __IO uint32_t CFG_AUTO_ZQ_CAL_EN;
+ struct
+ {
+ __IO uint32_t cfg_auto_zq_cal_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_AUTO_ZQ_CAL_EN_TypeDef;
+
+typedef union{ /*!< CFG_MEMORY_TYPE register definition*/
+ __IO uint32_t CFG_MEMORY_TYPE;
+ struct
+ {
+ __IO uint32_t cfg_memory_type :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEMORY_TYPE_TypeDef;
+
+typedef union{ /*!< CFG_ONLY_SRANK_CMDS register definition*/
+ __IO uint32_t CFG_ONLY_SRANK_CMDS;
+ struct
+ {
+ __IO uint32_t cfg_only_srank_cmds :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ONLY_SRANK_CMDS_TypeDef;
+
+typedef union{ /*!< CFG_NUM_RANKS register definition*/
+ __IO uint32_t CFG_NUM_RANKS;
+ struct
+ {
+ __IO uint32_t cfg_num_ranks :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_NUM_RANKS_TypeDef;
+
+typedef union{ /*!< CFG_QUAD_RANK register definition*/
+ __IO uint32_t CFG_QUAD_RANK;
+ struct
+ {
+ __IO uint32_t cfg_quad_rank :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_QUAD_RANK_TypeDef;
+
+typedef union{ /*!< CFG_EARLY_RANK_TO_WR_START register definition*/
+ __IO uint32_t CFG_EARLY_RANK_TO_WR_START;
+ struct
+ {
+ __IO uint32_t cfg_early_rank_to_wr_start :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_EARLY_RANK_TO_WR_START_TypeDef;
+
+typedef union{ /*!< CFG_EARLY_RANK_TO_RD_START register definition*/
+ __IO uint32_t CFG_EARLY_RANK_TO_RD_START;
+ struct
+ {
+ __IO uint32_t cfg_early_rank_to_rd_start :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_EARLY_RANK_TO_RD_START_TypeDef;
+
+typedef union{ /*!< CFG_PASR_BANK register definition*/
+ __IO uint32_t CFG_PASR_BANK;
+ struct
+ {
+ __IO uint32_t cfg_pasr_bank :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_PASR_BANK_TypeDef;
+
+typedef union{ /*!< CFG_PASR_SEG register definition*/
+ __IO uint32_t CFG_PASR_SEG;
+ struct
+ {
+ __IO uint32_t cfg_pasr_seg :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_PASR_SEG_TypeDef;
+
+typedef union{ /*!< INIT_MRR_MODE register definition*/
+ __IO uint32_t INIT_MRR_MODE;
+ struct
+ {
+ __IO uint32_t init_mrr_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_MRR_MODE_TypeDef;
+
+typedef union{ /*!< INIT_MR_W_REQ register definition*/
+ __IO uint32_t INIT_MR_W_REQ;
+ struct
+ {
+ __IO uint32_t init_mr_w_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_W_REQ_TypeDef;
+
+typedef union{ /*!< INIT_MR_ADDR register definition*/
+ __IO uint32_t INIT_MR_ADDR;
+ struct
+ {
+ __IO uint32_t init_mr_addr :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_ADDR_TypeDef;
+
+typedef union{ /*!< INIT_MR_WR_DATA register definition*/
+ __IO uint32_t INIT_MR_WR_DATA;
+ struct
+ {
+ __IO uint32_t init_mr_wr_data :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_WR_DATA_TypeDef;
+
+typedef union{ /*!< INIT_MR_WR_MASK register definition*/
+ __IO uint32_t INIT_MR_WR_MASK;
+ struct
+ {
+ __IO uint32_t init_mr_wr_mask :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_WR_MASK_TypeDef;
+
+typedef union{ /*!< INIT_NOP register definition*/
+ __IO uint32_t INIT_NOP;
+ struct
+ {
+ __IO uint32_t init_nop :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_NOP_TypeDef;
+
+typedef union{ /*!< CFG_INIT_DURATION register definition*/
+ __IO uint32_t CFG_INIT_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_init_duration :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_INIT_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQINIT_CAL_DURATION register definition*/
+ __IO uint32_t CFG_ZQINIT_CAL_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zqinit_cal_duration :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQINIT_CAL_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_L_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_L_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_l_duration :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_L_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_S_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_S_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_s_duration :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_S_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_R_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_R_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_r_duration :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_R_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_MRR register definition*/
+ __IO uint32_t CFG_MRR;
+ struct
+ {
+ __IO uint32_t cfg_mrr :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRR_TypeDef;
+
+typedef union{ /*!< CFG_MRW register definition*/
+ __IO uint32_t CFG_MRW;
+ struct
+ {
+ __IO uint32_t cfg_mrw :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRW_TypeDef;
+
+typedef union{ /*!< CFG_ODT_POWERDOWN register definition*/
+ __IO uint32_t CFG_ODT_POWERDOWN;
+ struct
+ {
+ __IO uint32_t cfg_odt_powerdown :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_POWERDOWN_TypeDef;
+
+typedef union{ /*!< CFG_WL register definition*/
+ __IO uint32_t CFG_WL;
+ struct
+ {
+ __IO uint32_t cfg_wl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_WL_TypeDef;
+
+typedef union{ /*!< CFG_RL register definition*/
+ __IO uint32_t CFG_RL;
+ struct
+ {
+ __IO uint32_t cfg_rl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_RL_TypeDef;
+
+typedef union{ /*!< CFG_CAL_READ_PERIOD register definition*/
+ __IO uint32_t CFG_CAL_READ_PERIOD;
+ struct
+ {
+ __IO uint32_t cfg_cal_read_period :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_CAL_READ_PERIOD_TypeDef;
+
+typedef union{ /*!< CFG_NUM_CAL_READS register definition*/
+ __IO uint32_t CFG_NUM_CAL_READS;
+ struct
+ {
+ __IO uint32_t cfg_num_cal_reads :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_NUM_CAL_READS_TypeDef;
+
+typedef union{ /*!< INIT_SELF_REFRESH register definition*/
+ __IO uint32_t INIT_SELF_REFRESH;
+ struct
+ {
+ __IO uint32_t init_self_refresh :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_SELF_REFRESH_TypeDef;
+
+typedef union{ /*!< INIT_SELF_REFRESH_STATUS register definition*/
+ __I uint32_t INIT_SELF_REFRESH_STATUS;
+ struct
+ {
+ __I uint32_t init_self_refresh_status :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_SELF_REFRESH_STATUS_TypeDef;
+
+typedef union{ /*!< INIT_POWER_DOWN register definition*/
+ __IO uint32_t INIT_POWER_DOWN;
+ struct
+ {
+ __IO uint32_t init_power_down :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_POWER_DOWN_TypeDef;
+
+typedef union{ /*!< INIT_POWER_DOWN_STATUS register definition*/
+ __I uint32_t INIT_POWER_DOWN_STATUS;
+ struct
+ {
+ __I uint32_t init_power_down_status :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_POWER_DOWN_STATUS_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_WRITE register definition*/
+ __IO uint32_t INIT_FORCE_WRITE;
+ struct
+ {
+ __IO uint32_t init_force_write :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_WRITE_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_WRITE_CS register definition*/
+ __IO uint32_t INIT_FORCE_WRITE_CS;
+ struct
+ {
+ __IO uint32_t init_force_write_cs :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_WRITE_CS_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_INIT_DISABLE register definition*/
+ __IO uint32_t CFG_CTRLR_INIT_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_init_disable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_INIT_DISABLE_TypeDef;
+
+typedef union{ /*!< CTRLR_READY register definition*/
+ __I uint32_t CTRLR_READY;
+ struct
+ {
+ __I uint32_t ctrlr_ready :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_READY_TypeDef;
+
+typedef union{ /*!< INIT_RDIMM_READY register definition*/
+ __I uint32_t INIT_RDIMM_READY;
+ struct
+ {
+ __I uint32_t init_rdimm_ready :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RDIMM_READY_TypeDef;
+
+typedef union{ /*!< INIT_RDIMM_COMPLETE register definition*/
+ __IO uint32_t INIT_RDIMM_COMPLETE;
+ struct
+ {
+ __IO uint32_t init_rdimm_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RDIMM_COMPLETE_TypeDef;
+
+typedef union{ /*!< CFG_RDIMM_LAT register definition*/
+ __IO uint32_t CFG_RDIMM_LAT;
+ struct
+ {
+ __IO uint32_t cfg_rdimm_lat :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RDIMM_LAT_TypeDef;
+
+typedef union{ /*!< CFG_RDIMM_BSIDE_INVERT register definition*/
+ __IO uint32_t CFG_RDIMM_BSIDE_INVERT;
+ struct
+ {
+ __IO uint32_t cfg_rdimm_bside_invert :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RDIMM_BSIDE_INVERT_TypeDef;
+
+typedef union{ /*!< CFG_LRDIMM register definition*/
+ __IO uint32_t CFG_LRDIMM;
+ struct
+ {
+ __IO uint32_t cfg_lrdimm :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LRDIMM_TypeDef;
+
+typedef union{ /*!< INIT_MEMORY_RESET_MASK register definition*/
+ __IO uint32_t INIT_MEMORY_RESET_MASK;
+ struct
+ {
+ __IO uint32_t init_memory_reset_mask :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_MEMORY_RESET_MASK_TypeDef;
+
+typedef union{ /*!< CFG_RD_PREAMB_TOGGLE register definition*/
+ __IO uint32_t CFG_RD_PREAMB_TOGGLE;
+ struct
+ {
+ __IO uint32_t cfg_rd_preamb_toggle :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_PREAMB_TOGGLE_TypeDef;
+
+typedef union{ /*!< CFG_RD_POSTAMBLE register definition*/
+ __IO uint32_t CFG_RD_POSTAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_rd_postamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_POSTAMBLE_TypeDef;
+
+typedef union{ /*!< CFG_PU_CAL register definition*/
+ __IO uint32_t CFG_PU_CAL;
+ struct
+ {
+ __IO uint32_t cfg_pu_cal :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_PU_CAL_TypeDef;
+
+typedef union{ /*!< CFG_DQ_ODT register definition*/
+ __IO uint32_t CFG_DQ_ODT;
+ struct
+ {
+ __IO uint32_t cfg_dq_odt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_DQ_ODT_TypeDef;
+
+typedef union{ /*!< CFG_CA_ODT register definition*/
+ __IO uint32_t CFG_CA_ODT;
+ struct
+ {
+ __IO uint32_t cfg_ca_odt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_ODT_TypeDef;
+
+typedef union{ /*!< CFG_ZQLATCH_DURATION register definition*/
+ __IO uint32_t CFG_ZQLATCH_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zqlatch_duration :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQLATCH_DURATION_TypeDef;
+
+typedef union{ /*!< INIT_CAL_SELECT register definition*/
+ __IO uint32_t INIT_CAL_SELECT;
+ struct
+ {
+ __IO uint32_t init_cal_select :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_SELECT_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_R_REQ register definition*/
+ __IO uint32_t INIT_CAL_L_R_REQ;
+ struct
+ {
+ __IO uint32_t init_cal_l_r_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_R_REQ_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_B_SIZE register definition*/
+ __IO uint32_t INIT_CAL_L_B_SIZE;
+ struct
+ {
+ __IO uint32_t init_cal_l_b_size :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_B_SIZE_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_R_ACK register definition*/
+ __I uint32_t INIT_CAL_L_R_ACK;
+ struct
+ {
+ __I uint32_t init_cal_l_r_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_R_ACK_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_READ_COMPLETE register definition*/
+ __I uint32_t INIT_CAL_L_READ_COMPLETE;
+ struct
+ {
+ __I uint32_t init_cal_l_read_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_READ_COMPLETE_TypeDef;
+
+typedef union{ /*!< INIT_RWFIFO register definition*/
+ __IO uint32_t INIT_RWFIFO;
+ struct
+ {
+ __IO uint32_t init_rwfifo :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RWFIFO_TypeDef;
+
+typedef union{ /*!< INIT_RD_DQCAL register definition*/
+ __IO uint32_t INIT_RD_DQCAL;
+ struct
+ {
+ __IO uint32_t init_rd_dqcal :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RD_DQCAL_TypeDef;
+
+typedef union{ /*!< INIT_START_DQSOSC register definition*/
+ __IO uint32_t INIT_START_DQSOSC;
+ struct
+ {
+ __IO uint32_t init_start_dqsosc :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_START_DQSOSC_TypeDef;
+
+typedef union{ /*!< INIT_STOP_DQSOSC register definition*/
+ __IO uint32_t INIT_STOP_DQSOSC;
+ struct
+ {
+ __IO uint32_t init_stop_dqsosc :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_STOP_DQSOSC_TypeDef;
+
+typedef union{ /*!< INIT_ZQ_CAL_START register definition*/
+ __IO uint32_t INIT_ZQ_CAL_START;
+ struct
+ {
+ __IO uint32_t init_zq_cal_start :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ZQ_CAL_START_TypeDef;
+
+typedef union{ /*!< CFG_WR_POSTAMBLE register definition*/
+ __IO uint32_t CFG_WR_POSTAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_wr_postamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_POSTAMBLE_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_ADDR_0 register definition*/
+ __IO uint32_t INIT_CAL_L_ADDR_0;
+ struct
+ {
+ __IO uint32_t init_cal_l_addr_0 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_ADDR_0_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_ADDR_1 register definition*/
+ __IO uint32_t INIT_CAL_L_ADDR_1;
+ struct
+ {
+ __IO uint32_t init_cal_l_addr_1 :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_ADDR_1_TypeDef;
+
+typedef union{ /*!< CFG_CTRLUPD_TRIG register definition*/
+ __IO uint32_t CFG_CTRLUPD_TRIG;
+ struct
+ {
+ __IO uint32_t cfg_ctrlupd_trig :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLUPD_TRIG_TypeDef;
+
+typedef union{ /*!< CFG_CTRLUPD_START_DELAY register definition*/
+ __IO uint32_t CFG_CTRLUPD_START_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_ctrlupd_start_delay :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLUPD_START_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_CTRLUPD_MAX register definition*/
+ __IO uint32_t CFG_DFI_T_CTRLUPD_MAX;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_ctrlupd_max :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_CTRLUPD_MAX_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_SEL register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_SEL;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_sel :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_SEL_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_VALUE register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_VALUE;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_value :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_VALUE_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_TURN_OFF_DELAY register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_TURN_OFF_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_turn_off_delay :9;
+ __I uint32_t reserved :23;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_TURN_OFF_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_slow_restart_window :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_RESTART_HOLDOFF register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_RESTART_HOLDOFF;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_restart_holdoff :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_RESTART_HOLDOFF_TypeDef;
+
+typedef union{ /*!< CFG_PARITY_RDIMM_DELAY register definition*/
+ __IO uint32_t CFG_PARITY_RDIMM_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_parity_rdimm_delay :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_PARITY_RDIMM_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_ENABLE register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_enable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_ASYNC_ODT register definition*/
+ __IO uint32_t CFG_ASYNC_ODT;
+ struct
+ {
+ __IO uint32_t cfg_async_odt :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ASYNC_ODT_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_duration :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_MRRI register definition*/
+ __IO uint32_t CFG_MRRI;
+ struct
+ {
+ __IO uint32_t cfg_mrri :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRRI_TypeDef;
+
+typedef union{ /*!< INIT_ODT_FORCE_EN register definition*/
+ __IO uint32_t INIT_ODT_FORCE_EN;
+ struct
+ {
+ __IO uint32_t init_odt_force_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ODT_FORCE_EN_TypeDef;
+
+typedef union{ /*!< INIT_ODT_FORCE_RANK register definition*/
+ __IO uint32_t INIT_ODT_FORCE_RANK;
+ struct
+ {
+ __IO uint32_t init_odt_force_rank :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_INIT_ODT_FORCE_RANK_TypeDef;
+
+typedef union{ /*!< CFG_PHYUPD_ACK_DELAY register definition*/
+ __IO uint32_t CFG_PHYUPD_ACK_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_phyupd_ack_delay :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_PHYUPD_ACK_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_MIRROR_X16_BG0_BG1 register definition*/
+ __IO uint32_t CFG_MIRROR_X16_BG0_BG1;
+ struct
+ {
+ __IO uint32_t cfg_mirror_x16_bg0_bg1 :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MIRROR_X16_BG0_BG1_TypeDef;
+
+typedef union{ /*!< INIT_PDA_MR_W_REQ register definition*/
+ __IO uint32_t INIT_PDA_MR_W_REQ;
+ struct
+ {
+ __IO uint32_t init_pda_mr_w_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_PDA_MR_W_REQ_TypeDef;
+
+typedef union{ /*!< INIT_PDA_NIBBLE_SELECT register definition*/
+ __IO uint32_t INIT_PDA_NIBBLE_SELECT;
+ struct
+ {
+ __IO uint32_t init_pda_nibble_select :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_INIT_PDA_NIBBLE_SELECT_TypeDef;
+
+typedef union{ /*!< CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH register definition*/
+ __IO uint32_t CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH;
+ struct
+ {
+ __IO uint32_t cfg_dram_clk_disable_in_self_refresh :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH_TypeDef;
+
+typedef union{ /*!< CFG_CKSRE register definition*/
+ __IO uint32_t CFG_CKSRE;
+ struct
+ {
+ __IO uint32_t cfg_cksre :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_CKSRE_TypeDef;
+
+typedef union{ /*!< CFG_CKSRX register definition*/
+ __IO uint32_t CFG_CKSRX;
+ struct
+ {
+ __IO uint32_t cfg_cksrx :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_CKSRX_TypeDef;
+
+typedef union{ /*!< CFG_RCD_STAB register definition*/
+ __IO uint32_t CFG_RCD_STAB;
+ struct
+ {
+ __IO uint32_t cfg_rcd_stab :14;
+ __I uint32_t reserved :18;
+ } bitfield;
+} DDR_CSR_APB_CFG_RCD_STAB_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_CTRL_DELAY register definition*/
+ __IO uint32_t CFG_DFI_T_CTRL_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_ctrl_delay :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_CTRL_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_DRAM_CLK_ENABLE register definition*/
+ __IO uint32_t CFG_DFI_T_DRAM_CLK_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_dram_clk_enable :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_DRAM_CLK_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_IDLE_TIME_TO_SELF_REFRESH register definition*/
+ __IO uint32_t CFG_IDLE_TIME_TO_SELF_REFRESH;
+ struct
+ {
+ __IO uint32_t cfg_idle_time_to_self_refresh :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_IDLE_TIME_TO_SELF_REFRESH_TypeDef;
+
+typedef union{ /*!< CFG_IDLE_TIME_TO_POWER_DOWN register definition*/
+ __IO uint32_t CFG_IDLE_TIME_TO_POWER_DOWN;
+ struct
+ {
+ __IO uint32_t cfg_idle_time_to_power_down :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_IDLE_TIME_TO_POWER_DOWN_TypeDef;
+
+typedef union{ /*!< CFG_BURST_RW_REFRESH_HOLDOFF register definition*/
+ __IO uint32_t CFG_BURST_RW_REFRESH_HOLDOFF;
+ struct
+ {
+ __IO uint32_t cfg_burst_rw_refresh_holdoff :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_BURST_RW_REFRESH_HOLDOFF_TypeDef;
+
+typedef union{ /*!< INIT_REFRESH_COUNT register definition*/
+ __I uint32_t INIT_REFRESH_COUNT;
+ struct
+ {
+ __I uint32_t init_refresh_count :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_INIT_REFRESH_COUNT_TypeDef;
+
+typedef union{ /*!< CFG_BG_INTERLEAVE register definition*/
+ __IO uint32_t CFG_BG_INTERLEAVE;
+ struct
+ {
+ __IO uint32_t cfg_bg_interleave :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_BG_INTERLEAVE_TypeDef;
+
+typedef union{ /*!< CFG_REFRESH_DURING_PHY_TRAINING register definition*/
+ __IO uint32_t CFG_REFRESH_DURING_PHY_TRAINING;
+ struct
+ {
+ __IO uint32_t cfg_refresh_during_phy_training :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REFRESH_DURING_PHY_TRAINING_TypeDef;
+
+typedef union{ /*!< MT_EN register definition*/
+ __IO uint32_t MT_EN;
+ struct
+ {
+ __IO uint32_t mt_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_EN_TypeDef;
+
+typedef union{ /*!< MT_EN_SINGLE register definition*/
+ __IO uint32_t MT_EN_SINGLE;
+ struct
+ {
+ __IO uint32_t mt_en_single :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_EN_SINGLE_TypeDef;
+
+typedef union{ /*!< MT_STOP_ON_ERROR register definition*/
+ __IO uint32_t MT_STOP_ON_ERROR;
+ struct
+ {
+ __IO uint32_t mt_stop_on_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_STOP_ON_ERROR_TypeDef;
+
+typedef union{ /*!< MT_RD_ONLY register definition*/
+ __IO uint32_t MT_RD_ONLY;
+ struct
+ {
+ __IO uint32_t mt_rd_only :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_RD_ONLY_TypeDef;
+
+typedef union{ /*!< MT_WR_ONLY register definition*/
+ __IO uint32_t MT_WR_ONLY;
+ struct
+ {
+ __IO uint32_t mt_wr_only :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_WR_ONLY_TypeDef;
+
+typedef union{ /*!< MT_DATA_PATTERN register definition*/
+ __IO uint32_t MT_DATA_PATTERN;
+ struct
+ {
+ __IO uint32_t mt_data_pattern :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_MT_DATA_PATTERN_TypeDef;
+
+typedef union{ /*!< MT_ADDR_PATTERN register definition*/
+ __IO uint32_t MT_ADDR_PATTERN;
+ struct
+ {
+ __IO uint32_t mt_addr_pattern :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_MT_ADDR_PATTERN_TypeDef;
+
+typedef union{ /*!< MT_DATA_INVERT register definition*/
+ __IO uint32_t MT_DATA_INVERT;
+ struct
+ {
+ __IO uint32_t mt_data_invert :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_DATA_INVERT_TypeDef;
+
+typedef union{ /*!< MT_ADDR_BITS register definition*/
+ __IO uint32_t MT_ADDR_BITS;
+ struct
+ {
+ __IO uint32_t mt_addr_bits :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MT_ADDR_BITS_TypeDef;
+
+typedef union{ /*!< MT_ERROR_STS register definition*/
+ __I uint32_t MT_ERROR_STS;
+ struct
+ {
+ __I uint32_t mt_error_sts :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_STS_TypeDef;
+
+typedef union{ /*!< MT_DONE_ACK register definition*/
+ __I uint32_t MT_DONE_ACK;
+ struct
+ {
+ __I uint32_t mt_done_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_DONE_ACK_TypeDef;
+
+typedef union{ /*!< MT_START_ADDR_0 register definition*/
+ __IO uint32_t MT_START_ADDR_0;
+ struct
+ {
+ __IO uint32_t mt_start_addr_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_START_ADDR_0_TypeDef;
+
+typedef union{ /*!< MT_START_ADDR_1 register definition*/
+ __IO uint32_t MT_START_ADDR_1;
+ struct
+ {
+ __IO uint32_t mt_start_addr_1 :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_MT_START_ADDR_1_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_0 register definition*/
+ __IO uint32_t MT_ERROR_MASK_0;
+ struct
+ {
+ __IO uint32_t mt_error_mask_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_0_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_1 register definition*/
+ __IO uint32_t MT_ERROR_MASK_1;
+ struct
+ {
+ __IO uint32_t mt_error_mask_1 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_1_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_2 register definition*/
+ __IO uint32_t MT_ERROR_MASK_2;
+ struct
+ {
+ __IO uint32_t mt_error_mask_2 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_2_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_3 register definition*/
+ __IO uint32_t MT_ERROR_MASK_3;
+ struct
+ {
+ __IO uint32_t mt_error_mask_3 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_3_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_4 register definition*/
+ __IO uint32_t MT_ERROR_MASK_4;
+ struct
+ {
+ __IO uint32_t mt_error_mask_4 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_4_TypeDef;
+
+typedef union{ /*!< MT_USER_DATA_PATTERN register definition*/
+ __IO uint32_t MT_USER_DATA_PATTERN;
+ struct
+ {
+ __IO uint32_t mt_user_data_pattern :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_MT_USER_DATA_PATTERN_TypeDef;
+
+typedef union{ /*!< MT_ALG_AUTO_PCH register definition*/
+ __IO uint32_t MT_ALG_AUTO_PCH;
+ struct
+ {
+ __IO uint32_t mt_alg_auto_pch :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_ALG_AUTO_PCH_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P0 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P0;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p0 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P0_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P1 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P1;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p1 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P1_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P2 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P2;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p2 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P2_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P3 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P3;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p3 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P3_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P4 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P4;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p4 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P4_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P5 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P5;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p5 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P5_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P6 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P6;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p6 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P6_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P7 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P7;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p7 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P7_TypeDef;
+
+typedef union{ /*!< CFG_REORDER_EN register definition*/
+ __IO uint32_t CFG_REORDER_EN;
+ struct
+ {
+ __IO uint32_t cfg_reorder_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REORDER_EN_TypeDef;
+
+typedef union{ /*!< CFG_REORDER_QUEUE_EN register definition*/
+ __IO uint32_t CFG_REORDER_QUEUE_EN;
+ struct
+ {
+ __IO uint32_t cfg_reorder_queue_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REORDER_QUEUE_EN_TypeDef;
+
+typedef union{ /*!< CFG_INTRAPORT_REORDER_EN register definition*/
+ __IO uint32_t CFG_INTRAPORT_REORDER_EN;
+ struct
+ {
+ __IO uint32_t cfg_intraport_reorder_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_INTRAPORT_REORDER_EN_TypeDef;
+
+typedef union{ /*!< CFG_MAINTAIN_COHERENCY register definition*/
+ __IO uint32_t CFG_MAINTAIN_COHERENCY;
+ struct
+ {
+ __IO uint32_t cfg_maintain_coherency :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MAINTAIN_COHERENCY_TypeDef;
+
+typedef union{ /*!< CFG_Q_AGE_LIMIT register definition*/
+ __IO uint32_t CFG_Q_AGE_LIMIT;
+ struct
+ {
+ __IO uint32_t cfg_q_age_limit :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_Q_AGE_LIMIT_TypeDef;
+
+typedef union{ /*!< CFG_RO_CLOSED_PAGE_POLICY register definition*/
+ __IO uint32_t CFG_RO_CLOSED_PAGE_POLICY;
+ struct
+ {
+ __IO uint32_t cfg_ro_closed_page_policy :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RO_CLOSED_PAGE_POLICY_TypeDef;
+
+typedef union{ /*!< CFG_REORDER_RW_ONLY register definition*/
+ __IO uint32_t CFG_REORDER_RW_ONLY;
+ struct
+ {
+ __IO uint32_t cfg_reorder_rw_only :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REORDER_RW_ONLY_TypeDef;
+
+typedef union{ /*!< CFG_RO_PRIORITY_EN register definition*/
+ __IO uint32_t CFG_RO_PRIORITY_EN;
+ struct
+ {
+ __IO uint32_t cfg_ro_priority_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RO_PRIORITY_EN_TypeDef;
+
+typedef union{ /*!< CFG_DM_EN register definition*/
+ __IO uint32_t CFG_DM_EN;
+ struct
+ {
+ __IO uint32_t cfg_dm_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DM_EN_TypeDef;
+
+typedef union{ /*!< CFG_RMW_EN register definition*/
+ __IO uint32_t CFG_RMW_EN;
+ struct
+ {
+ __IO uint32_t cfg_rmw_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RMW_EN_TypeDef;
+
+typedef union{ /*!< CFG_ECC_CORRECTION_EN register definition*/
+ __IO uint32_t CFG_ECC_CORRECTION_EN;
+ struct
+ {
+ __IO uint32_t cfg_ecc_correction_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ECC_CORRECTION_EN_TypeDef;
+
+typedef union{ /*!< CFG_ECC_BYPASS register definition*/
+ __IO uint32_t CFG_ECC_BYPASS;
+ struct
+ {
+ __IO uint32_t cfg_ecc_bypass :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ECC_BYPASS_TypeDef;
+
+typedef union{ /*!< INIT_WRITE_DATA_1B_ECC_ERROR_GEN register definition*/
+ __IO uint32_t INIT_WRITE_DATA_1B_ECC_ERROR_GEN;
+ struct
+ {
+ __IO uint32_t init_write_data_1b_ecc_error_gen :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_INIT_WRITE_DATA_1B_ECC_ERROR_GEN_TypeDef;
+
+typedef union{ /*!< INIT_WRITE_DATA_2B_ECC_ERROR_GEN register definition*/
+ __IO uint32_t INIT_WRITE_DATA_2B_ECC_ERROR_GEN;
+ struct
+ {
+ __IO uint32_t init_write_data_2b_ecc_error_gen :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_INIT_WRITE_DATA_2B_ECC_ERROR_GEN_TypeDef;
+
+typedef union{ /*!< CFG_ECC_1BIT_INT_THRESH register definition*/
+ __IO uint32_t CFG_ECC_1BIT_INT_THRESH;
+ struct
+ {
+ __IO uint32_t cfg_ecc_1bit_int_thresh :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ECC_1BIT_INT_THRESH_TypeDef;
+
+typedef union{ /*!< STAT_INT_ECC_1BIT_THRESH register definition*/
+ __I uint32_t STAT_INT_ECC_1BIT_THRESH;
+ struct
+ {
+ __I uint32_t stat_int_ecc_1bit_thresh :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_INT_ECC_1BIT_THRESH_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_ADDR register definition*/
+ __IO uint32_t INIT_READ_CAPTURE_ADDR;
+ struct
+ {
+ __IO uint32_t init_read_capture_addr :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_ADDR_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_0 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_0;
+ struct
+ {
+ __I uint32_t init_read_capture_data_0 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_0_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_1 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_1;
+ struct
+ {
+ __I uint32_t init_read_capture_data_1 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_1_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_2 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_2;
+ struct
+ {
+ __I uint32_t init_read_capture_data_2 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_2_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_3 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_3;
+ struct
+ {
+ __I uint32_t init_read_capture_data_3 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_3_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_4 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_4;
+ struct
+ {
+ __I uint32_t init_read_capture_data_4 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_4_TypeDef;
+
+typedef union{ /*!< CFG_ERROR_GROUP_SEL register definition*/
+ __IO uint32_t CFG_ERROR_GROUP_SEL;
+ struct
+ {
+ __IO uint32_t cfg_error_group_sel :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ERROR_GROUP_SEL_TypeDef;
+
+typedef union{ /*!< CFG_DATA_SEL register definition*/
+ __IO uint32_t CFG_DATA_SEL;
+ struct
+ {
+ __IO uint32_t cfg_data_sel :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_DATA_SEL_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MODE register definition*/
+ __IO uint32_t CFG_TRIG_MODE;
+ struct
+ {
+ __IO uint32_t cfg_trig_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MODE_TypeDef;
+
+typedef union{ /*!< CFG_POST_TRIG_CYCS register definition*/
+ __IO uint32_t CFG_POST_TRIG_CYCS;
+ struct
+ {
+ __IO uint32_t cfg_post_trig_cycs :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_POST_TRIG_CYCS_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MASK register definition*/
+ __IO uint32_t CFG_TRIG_MASK;
+ struct
+ {
+ __IO uint32_t cfg_trig_mask :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MASK_TypeDef;
+
+typedef union{ /*!< CFG_EN_MASK register definition*/
+ __IO uint32_t CFG_EN_MASK;
+ struct
+ {
+ __IO uint32_t cfg_en_mask :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_EN_MASK_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_ADDR register definition*/
+ __IO uint32_t MTC_ACQ_ADDR;
+ struct
+ {
+ __IO uint32_t mtc_acq_addr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_ADDR_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_CYCS_STORED register definition*/
+ __I uint32_t MTC_ACQ_CYCS_STORED;
+ struct
+ {
+ __I uint32_t mtc_acq_cycs_stored :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_CYCS_STORED_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_TRIG_DETECT register definition*/
+ __I uint32_t MTC_ACQ_TRIG_DETECT;
+ struct
+ {
+ __I uint32_t mtc_acq_trig_detect :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_TRIG_DETECT_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_MEM_TRIG_ADDR register definition*/
+ __I uint32_t MTC_ACQ_MEM_TRIG_ADDR;
+ struct
+ {
+ __I uint32_t mtc_acq_mem_trig_addr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_MEM_TRIG_ADDR_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_MEM_LAST_ADDR register definition*/
+ __I uint32_t MTC_ACQ_MEM_LAST_ADDR;
+ struct
+ {
+ __I uint32_t mtc_acq_mem_last_addr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_MEM_LAST_ADDR_TypeDef;
+
+typedef union{ /*!< MTC_ACK register definition*/
+ __I uint32_t MTC_ACK;
+ struct
+ {
+ __I uint32_t mtc_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACK_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MT_ADDR_0 register definition*/
+ __IO uint32_t CFG_TRIG_MT_ADDR_0;
+ struct
+ {
+ __IO uint32_t cfg_trig_mt_addr_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MT_ADDR_0_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MT_ADDR_1 register definition*/
+ __IO uint32_t CFG_TRIG_MT_ADDR_1;
+ struct
+ {
+ __IO uint32_t cfg_trig_mt_addr_1 :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MT_ADDR_1_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_0 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_0;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_0_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_1 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_1;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_1 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_1_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_2 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_2;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_2 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_2_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_3 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_3;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_3 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_3_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_4 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_4;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_4 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_4_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_WR_DATA_0 register definition*/
+ __IO uint32_t MTC_ACQ_WR_DATA_0;
+ struct
+ {
+ __IO uint32_t mtc_acq_wr_data_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_WR_DATA_0_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_WR_DATA_1 register definition*/
+ __IO uint32_t MTC_ACQ_WR_DATA_1;
+ struct
+ {
+ __IO uint32_t mtc_acq_wr_data_1 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_WR_DATA_1_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_WR_DATA_2 register definition*/
+ __IO uint32_t MTC_ACQ_WR_DATA_2;
+ struct
+ {
+ __IO uint32_t mtc_acq_wr_data_2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_WR_DATA_2_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_RD_DATA_0 register definition*/
+ __I uint32_t MTC_ACQ_RD_DATA_0;
+ struct
+ {
+ __I uint32_t mtc_acq_rd_data_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_RD_DATA_0_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_RD_DATA_1 register definition*/
+ __I uint32_t MTC_ACQ_RD_DATA_1;
+ struct
+ {
+ __I uint32_t mtc_acq_rd_data_1 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_RD_DATA_1_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_RD_DATA_2 register definition*/
+ __I uint32_t MTC_ACQ_RD_DATA_2;
+ struct
+ {
+ __I uint32_t mtc_acq_rd_data_2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_RD_DATA_2_TypeDef;
+
+typedef union{ /*!< CFG_PRE_TRIG_CYCS register definition*/
+ __IO uint32_t CFG_PRE_TRIG_CYCS;
+ struct
+ {
+ __IO uint32_t cfg_pre_trig_cycs :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_PRE_TRIG_CYCS_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_ERROR_CNT register definition*/
+ __I uint32_t MTC_ACQ_ERROR_CNT;
+ struct
+ {
+ __I uint32_t mtc_acq_error_cnt :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_ERROR_CNT_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_ERROR_CNT_OVFL register definition*/
+ __I uint32_t MTC_ACQ_ERROR_CNT_OVFL;
+ struct
+ {
+ __I uint32_t mtc_acq_error_cnt_ovfl :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_ERROR_CNT_OVFL_TypeDef;
+
+typedef union{ /*!< CFG_DATA_SEL_FIRST_ERROR register definition*/
+ __IO uint32_t CFG_DATA_SEL_FIRST_ERROR;
+ struct
+ {
+ __IO uint32_t cfg_data_sel_first_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DATA_SEL_FIRST_ERROR_TypeDef;
+
+typedef union{ /*!< CFG_DQ_WIDTH register definition*/
+ __IO uint32_t CFG_DQ_WIDTH;
+ struct
+ {
+ __IO uint32_t cfg_dq_width :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_DQ_WIDTH_TypeDef;
+
+typedef union{ /*!< CFG_ACTIVE_DQ_SEL register definition*/
+ __IO uint32_t CFG_ACTIVE_DQ_SEL;
+ struct
+ {
+ __IO uint32_t cfg_active_dq_sel :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_ACTIVE_DQ_SEL_TypeDef;
+
+typedef union{ /*!< STAT_CA_PARITY_ERROR register definition*/
+ __I uint32_t STAT_CA_PARITY_ERROR;
+ struct
+ {
+ __I uint32_t stat_ca_parity_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_CA_PARITY_ERROR_TypeDef;
+
+typedef union{ /*!< INIT_CA_PARITY_ERROR_GEN_REQ register definition*/
+ __IO uint32_t INIT_CA_PARITY_ERROR_GEN_REQ;
+ struct
+ {
+ __IO uint32_t init_ca_parity_error_gen_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_REQ_TypeDef;
+
+typedef union{ /*!< INIT_CA_PARITY_ERROR_GEN_CMD register definition*/
+ __IO uint32_t INIT_CA_PARITY_ERROR_GEN_CMD;
+ struct
+ {
+ __IO uint32_t init_ca_parity_error_gen_cmd :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_CMD_TypeDef;
+
+typedef union{ /*!< INIT_CA_PARITY_ERROR_GEN_ACK register definition*/
+ __I uint32_t INIT_CA_PARITY_ERROR_GEN_ACK;
+ struct
+ {
+ __I uint32_t init_ca_parity_error_gen_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_ACK_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_RDDATA_EN register definition*/
+ __IO uint32_t CFG_DFI_T_RDDATA_EN;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_rddata_en :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_RDDATA_EN_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_PHY_RDLAT register definition*/
+ __IO uint32_t CFG_DFI_T_PHY_RDLAT;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_phy_rdlat :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_PHY_RDLAT_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_PHY_WRLAT register definition*/
+ __IO uint32_t CFG_DFI_T_PHY_WRLAT;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_phy_wrlat :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_PHY_WRLAT_TypeDef;
+
+typedef union{ /*!< CFG_DFI_PHYUPD_EN register definition*/
+ __IO uint32_t CFG_DFI_PHYUPD_EN;
+ struct
+ {
+ __IO uint32_t cfg_dfi_phyupd_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_PHYUPD_EN_TypeDef;
+
+typedef union{ /*!< INIT_DFI_LP_DATA_REQ register definition*/
+ __IO uint32_t INIT_DFI_LP_DATA_REQ;
+ struct
+ {
+ __IO uint32_t init_dfi_lp_data_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_LP_DATA_REQ_TypeDef;
+
+typedef union{ /*!< INIT_DFI_LP_CTRL_REQ register definition*/
+ __IO uint32_t INIT_DFI_LP_CTRL_REQ;
+ struct
+ {
+ __IO uint32_t init_dfi_lp_ctrl_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_LP_CTRL_REQ_TypeDef;
+
+typedef union{ /*!< STAT_DFI_LP_ACK register definition*/
+ __I uint32_t STAT_DFI_LP_ACK;
+ struct
+ {
+ __I uint32_t stat_dfi_lp_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_LP_ACK_TypeDef;
+
+typedef union{ /*!< INIT_DFI_LP_WAKEUP register definition*/
+ __IO uint32_t INIT_DFI_LP_WAKEUP;
+ struct
+ {
+ __IO uint32_t init_dfi_lp_wakeup :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_LP_WAKEUP_TypeDef;
+
+typedef union{ /*!< INIT_DFI_DRAM_CLK_DISABLE register definition*/
+ __IO uint32_t INIT_DFI_DRAM_CLK_DISABLE;
+ struct
+ {
+ __IO uint32_t init_dfi_dram_clk_disable :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_DRAM_CLK_DISABLE_TypeDef;
+
+typedef union{ /*!< STAT_DFI_TRAINING_ERROR register definition*/
+ __I uint32_t STAT_DFI_TRAINING_ERROR;
+ struct
+ {
+ __I uint32_t stat_dfi_training_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_TRAINING_ERROR_TypeDef;
+
+typedef union{ /*!< STAT_DFI_ERROR register definition*/
+ __I uint32_t STAT_DFI_ERROR;
+ struct
+ {
+ __I uint32_t stat_dfi_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_ERROR_TypeDef;
+
+typedef union{ /*!< STAT_DFI_ERROR_INFO register definition*/
+ __I uint32_t STAT_DFI_ERROR_INFO;
+ struct
+ {
+ __I uint32_t stat_dfi_error_info :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_ERROR_INFO_TypeDef;
+
+typedef union{ /*!< CFG_DFI_DATA_BYTE_DISABLE register definition*/
+ __IO uint32_t CFG_DFI_DATA_BYTE_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_dfi_data_byte_disable :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_DATA_BYTE_DISABLE_TypeDef;
+
+typedef union{ /*!< STAT_DFI_INIT_COMPLETE register definition*/
+ __I uint32_t STAT_DFI_INIT_COMPLETE;
+ struct
+ {
+ __I uint32_t stat_dfi_init_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_INIT_COMPLETE_TypeDef;
+
+typedef union{ /*!< STAT_DFI_TRAINING_COMPLETE register definition*/
+ __I uint32_t STAT_DFI_TRAINING_COMPLETE;
+ struct
+ {
+ __I uint32_t stat_dfi_training_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_TRAINING_COMPLETE_TypeDef;
+
+typedef union{ /*!< CFG_DFI_LVL_SEL register definition*/
+ __IO uint32_t CFG_DFI_LVL_SEL;
+ struct
+ {
+ __IO uint32_t cfg_dfi_lvl_sel :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_LVL_SEL_TypeDef;
+
+typedef union{ /*!< CFG_DFI_LVL_PERIODIC register definition*/
+ __IO uint32_t CFG_DFI_LVL_PERIODIC;
+ struct
+ {
+ __IO uint32_t cfg_dfi_lvl_periodic :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_LVL_PERIODIC_TypeDef;
+
+typedef union{ /*!< CFG_DFI_LVL_PATTERN register definition*/
+ __IO uint32_t CFG_DFI_LVL_PATTERN;
+ struct
+ {
+ __IO uint32_t cfg_dfi_lvl_pattern :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_LVL_PATTERN_TypeDef;
+
+typedef union{ /*!< PHY_DFI_INIT_START register definition*/
+ __IO uint32_t PHY_DFI_INIT_START;
+ struct
+ {
+ __IO uint32_t phy_dfi_init_start :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_DFI_INIT_START_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI1_0 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI1_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI1_1 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI1_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi1_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_1_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI2_0 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI2_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI2_1 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI2_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi2_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_1_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI1_0 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI1_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI1_1 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI1_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi1_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_1_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI2_0 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI2_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI2_1 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI2_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi2_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_1_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI1_0 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI1_0;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_0_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI1_1 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI1_1;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi1_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_1_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI2_0 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI2_0;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_0_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI2_1 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI2_1;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi2_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_1_TypeDef;
+
+typedef union{ /*!< CFG_ENABLE_BUS_HOLD_AXI1 register definition*/
+ __IO uint32_t CFG_ENABLE_BUS_HOLD_AXI1;
+ struct
+ {
+ __IO uint32_t cfg_enable_bus_hold_axi1 :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI1_TypeDef;
+
+typedef union{ /*!< CFG_ENABLE_BUS_HOLD_AXI2 register definition*/
+ __IO uint32_t CFG_ENABLE_BUS_HOLD_AXI2;
+ struct
+ {
+ __IO uint32_t cfg_enable_bus_hold_axi2 :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI2_TypeDef;
+
+typedef union{ /*!< CFG_AXI_AUTO_PCH register definition*/
+ __IO uint32_t CFG_AXI_AUTO_PCH;
+ struct
+ {
+ __IO uint32_t cfg_axi_auto_pch :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_AUTO_PCH_TypeDef;
+
+typedef union{ /*!< PHY_RESET_CONTROL register definition*/
+ __IO uint32_t PHY_RESET_CONTROL;
+ struct
+ {
+ __IO uint32_t phy_reset_control :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_PHY_RESET_CONTROL_TypeDef;
+
+typedef union{ /*!< PHY_PC_RANK register definition*/
+ __IO uint32_t PHY_PC_RANK;
+ struct
+ {
+ __IO uint32_t phy_pc_rank :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_PHY_PC_RANK_TypeDef;
+
+typedef union{ /*!< PHY_RANKS_TO_TRAIN register definition*/
+ __IO uint32_t PHY_RANKS_TO_TRAIN;
+ struct
+ {
+ __IO uint32_t phy_ranks_to_train :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_PHY_RANKS_TO_TRAIN_TypeDef;
+
+typedef union{ /*!< PHY_WRITE_REQUEST register definition*/
+ __IO uint32_t PHY_WRITE_REQUEST;
+ struct
+ {
+ __IO uint32_t phy_write_request :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_WRITE_REQUEST_TypeDef;
+
+typedef union{ /*!< PHY_WRITE_REQUEST_DONE register definition*/
+ __I uint32_t PHY_WRITE_REQUEST_DONE;
+ struct
+ {
+ __I uint32_t phy_write_request_done :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_WRITE_REQUEST_DONE_TypeDef;
+
+typedef union{ /*!< PHY_READ_REQUEST register definition*/
+ __IO uint32_t PHY_READ_REQUEST;
+ struct
+ {
+ __IO uint32_t phy_read_request :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_READ_REQUEST_TypeDef;
+
+typedef union{ /*!< PHY_READ_REQUEST_DONE register definition*/
+ __I uint32_t PHY_READ_REQUEST_DONE;
+ struct
+ {
+ __I uint32_t phy_read_request_done :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_READ_REQUEST_DONE_TypeDef;
+
+typedef union{ /*!< PHY_WRITE_LEVEL_DELAY register definition*/
+ __IO uint32_t PHY_WRITE_LEVEL_DELAY;
+ struct
+ {
+ __IO uint32_t phy_write_level_delay :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_WRITE_LEVEL_DELAY_TypeDef;
+
+typedef union{ /*!< PHY_GATE_TRAIN_DELAY register definition*/
+ __IO uint32_t PHY_GATE_TRAIN_DELAY;
+ struct
+ {
+ __IO uint32_t phy_gate_train_delay :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_GATE_TRAIN_DELAY_TypeDef;
+
+typedef union{ /*!< PHY_EYE_TRAIN_DELAY register definition*/
+ __IO uint32_t PHY_EYE_TRAIN_DELAY;
+ struct
+ {
+ __IO uint32_t phy_eye_train_delay :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_EYE_TRAIN_DELAY_TypeDef;
+
+typedef union{ /*!< PHY_EYE_PAT register definition*/
+ __IO uint32_t PHY_EYE_PAT;
+ struct
+ {
+ __IO uint32_t phy_eye_pat :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_PHY_EYE_PAT_TypeDef;
+
+typedef union{ /*!< PHY_START_RECAL register definition*/
+ __IO uint32_t PHY_START_RECAL;
+ struct
+ {
+ __IO uint32_t phy_start_recal :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_START_RECAL_TypeDef;
+
+typedef union{ /*!< PHY_CLR_DFI_LVL_PERIODIC register definition*/
+ __IO uint32_t PHY_CLR_DFI_LVL_PERIODIC;
+ struct
+ {
+ __IO uint32_t phy_clr_dfi_lvl_periodic :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_CLR_DFI_LVL_PERIODIC_TypeDef;
+
+typedef union{ /*!< PHY_TRAIN_STEP_ENABLE register definition*/
+ __IO uint32_t PHY_TRAIN_STEP_ENABLE;
+ struct
+ {
+ __IO uint32_t phy_train_step_enable :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_TRAIN_STEP_ENABLE_TypeDef;
+
+typedef union{ /*!< PHY_LPDDR_DQ_CAL_PAT register definition*/
+ __IO uint32_t PHY_LPDDR_DQ_CAL_PAT;
+ struct
+ {
+ __IO uint32_t phy_lpddr_dq_cal_pat :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_LPDDR_DQ_CAL_PAT_TypeDef;
+
+typedef union{ /*!< PHY_INDPNDT_TRAINING register definition*/
+ __IO uint32_t PHY_INDPNDT_TRAINING;
+ struct
+ {
+ __IO uint32_t phy_indpndt_training :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_INDPNDT_TRAINING_TypeDef;
+
+typedef union{ /*!< PHY_ENCODED_QUAD_CS register definition*/
+ __IO uint32_t PHY_ENCODED_QUAD_CS;
+ struct
+ {
+ __IO uint32_t phy_encoded_quad_cs :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_ENCODED_QUAD_CS_TypeDef;
+
+typedef union{ /*!< PHY_HALF_CLK_DLY_ENABLE register definition*/
+ __IO uint32_t PHY_HALF_CLK_DLY_ENABLE;
+ struct
+ {
+ __IO uint32_t phy_half_clk_dly_enable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_HALF_CLK_DLY_ENABLE_TypeDef;
+
+/*------------ ADDR_MAP register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_MANUAL_ADDRESS_MAP_TypeDef CFG_MANUAL_ADDRESS_MAP; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_CHIPADDR_MAP_TypeDef CFG_CHIPADDR_MAP; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_CIDADDR_MAP_TypeDef CFG_CIDADDR_MAP; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_LOW_TypeDef CFG_MB_AUTOPCH_COL_BIT_POS_LOW; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH_TypeDef CFG_MB_AUTOPCH_COL_BIT_POS_HIGH; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_BANKADDR_MAP_0_TypeDef CFG_BANKADDR_MAP_0; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_BANKADDR_MAP_1_TypeDef CFG_BANKADDR_MAP_1; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_0_TypeDef CFG_ROWADDR_MAP_0; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_1_TypeDef CFG_ROWADDR_MAP_1; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_2_TypeDef CFG_ROWADDR_MAP_2; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_3_TypeDef CFG_ROWADDR_MAP_3; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_COLADDR_MAP_0_TypeDef CFG_COLADDR_MAP_0; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_COLADDR_MAP_1_TypeDef CFG_COLADDR_MAP_1; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_COLADDR_MAP_2_TypeDef CFG_COLADDR_MAP_2; /*!< Offset: 0x34 */
+} DDR_CSR_APB_ADDR_MAP_TypeDef;
+
+/*------------ MC_BASE3 register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_VRCG_ENABLE_TypeDef CFG_VRCG_ENABLE; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_VRCG_DISABLE_TypeDef CFG_VRCG_DISABLE; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_WRITE_LATENCY_SET_TypeDef CFG_WRITE_LATENCY_SET; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_THERMAL_OFFSET_TypeDef CFG_THERMAL_OFFSET; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_SOC_ODT_TypeDef CFG_SOC_ODT; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_ODTE_CK_TypeDef CFG_ODTE_CK; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_ODTE_CS_TypeDef CFG_ODTE_CS; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_ODTD_CA_TypeDef CFG_ODTD_CA; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_LPDDR4_FSP_OP_TypeDef CFG_LPDDR4_FSP_OP; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_GENERATE_REFRESH_ON_SRX_TypeDef CFG_GENERATE_REFRESH_ON_SRX; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_CFG_DBI_CL_TypeDef CFG_DBI_CL; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_NON_DBI_CL_TypeDef CFG_NON_DBI_CL; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_INIT_FORCE_WRITE_DATA_0_TypeDef INIT_FORCE_WRITE_DATA_0; /*!< Offset: 0x30 */
+ __I uint32_t UNUSED_SPACE0[63]; /*!< Offset: 0x34 */
+} DDR_CSR_APB_MC_BASE3_TypeDef;
+
+/*------------ MC_BASE1 register bundle definition -----------*/
+typedef struct /*!< Offset: 0x3c00 */
+{
+ __IO DDR_CSR_APB_CFG_WRITE_CRC_TypeDef CFG_WRITE_CRC; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_MPR_READ_FORMAT_TypeDef CFG_MPR_READ_FORMAT; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_WR_CMD_LAT_CRC_DM_TypeDef CFG_WR_CMD_LAT_CRC_DM; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_FINE_GRAN_REF_MODE_TypeDef CFG_FINE_GRAN_REF_MODE; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_TEMP_SENSOR_READOUT_TypeDef CFG_TEMP_SENSOR_READOUT; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_PER_DRAM_ADDR_EN_TypeDef CFG_PER_DRAM_ADDR_EN; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_GEARDOWN_MODE_TypeDef CFG_GEARDOWN_MODE; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_WR_PREAMBLE_TypeDef CFG_WR_PREAMBLE; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_RD_PREAMBLE_TypeDef CFG_RD_PREAMBLE; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_RD_PREAMB_TRN_MODE_TypeDef CFG_RD_PREAMB_TRN_MODE; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_CFG_SR_ABORT_TypeDef CFG_SR_ABORT; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_CS_TO_CMDADDR_LATENCY_TypeDef CFG_CS_TO_CMDADDR_LATENCY; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_INT_VREF_MON_TypeDef CFG_INT_VREF_MON; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_TEMP_CTRL_REF_MODE_TypeDef CFG_TEMP_CTRL_REF_MODE; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_CFG_TEMP_CTRL_REF_RANGE_TypeDef CFG_TEMP_CTRL_REF_RANGE; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_CFG_MAX_PWR_DOWN_MODE_TypeDef CFG_MAX_PWR_DOWN_MODE; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_READ_DBI_TypeDef CFG_READ_DBI; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_WRITE_DBI_TypeDef CFG_WRITE_DBI; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_CFG_DATA_MASK_TypeDef CFG_DATA_MASK; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_CFG_CA_PARITY_PERSIST_ERR_TypeDef CFG_CA_PARITY_PERSIST_ERR; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_CFG_RTT_PARK_TypeDef CFG_RTT_PARK; /*!< Offset: 0x50 */
+ __IO DDR_CSR_APB_CFG_ODT_INBUF_4_PD_TypeDef CFG_ODT_INBUF_4_PD; /*!< Offset: 0x54 */
+ __IO DDR_CSR_APB_CFG_CA_PARITY_ERR_STATUS_TypeDef CFG_CA_PARITY_ERR_STATUS; /*!< Offset: 0x58 */
+ __IO DDR_CSR_APB_CFG_CRC_ERROR_CLEAR_TypeDef CFG_CRC_ERROR_CLEAR; /*!< Offset: 0x5c */
+ __IO DDR_CSR_APB_CFG_CA_PARITY_LATENCY_TypeDef CFG_CA_PARITY_LATENCY; /*!< Offset: 0x60 */
+ __IO DDR_CSR_APB_CFG_CCD_S_TypeDef CFG_CCD_S; /*!< Offset: 0x64 */
+ __IO DDR_CSR_APB_CFG_CCD_L_TypeDef CFG_CCD_L; /*!< Offset: 0x68 */
+ __IO DDR_CSR_APB_CFG_VREFDQ_TRN_ENABLE_TypeDef CFG_VREFDQ_TRN_ENABLE; /*!< Offset: 0x6c */
+ __IO DDR_CSR_APB_CFG_VREFDQ_TRN_RANGE_TypeDef CFG_VREFDQ_TRN_RANGE; /*!< Offset: 0x70 */
+ __IO DDR_CSR_APB_CFG_VREFDQ_TRN_VALUE_TypeDef CFG_VREFDQ_TRN_VALUE; /*!< Offset: 0x74 */
+ __IO DDR_CSR_APB_CFG_RRD_S_TypeDef CFG_RRD_S; /*!< Offset: 0x78 */
+ __IO DDR_CSR_APB_CFG_RRD_L_TypeDef CFG_RRD_L; /*!< Offset: 0x7c */
+ __IO DDR_CSR_APB_CFG_WTR_S_TypeDef CFG_WTR_S; /*!< Offset: 0x80 */
+ __IO DDR_CSR_APB_CFG_WTR_L_TypeDef CFG_WTR_L; /*!< Offset: 0x84 */
+ __IO DDR_CSR_APB_CFG_WTR_S_CRC_DM_TypeDef CFG_WTR_S_CRC_DM; /*!< Offset: 0x88 */
+ __IO DDR_CSR_APB_CFG_WTR_L_CRC_DM_TypeDef CFG_WTR_L_CRC_DM; /*!< Offset: 0x8c */
+ __IO DDR_CSR_APB_CFG_WR_CRC_DM_TypeDef CFG_WR_CRC_DM; /*!< Offset: 0x90 */
+ __IO DDR_CSR_APB_CFG_RFC1_TypeDef CFG_RFC1; /*!< Offset: 0x94 */
+ __IO DDR_CSR_APB_CFG_RFC2_TypeDef CFG_RFC2; /*!< Offset: 0x98 */
+ __IO DDR_CSR_APB_CFG_RFC4_TypeDef CFG_RFC4; /*!< Offset: 0x9c */
+ __I uint32_t UNUSED_SPACE0[9]; /*!< Offset: 0xa0 */
+ __IO DDR_CSR_APB_CFG_NIBBLE_DEVICES_TypeDef CFG_NIBBLE_DEVICES; /*!< Offset: 0xc4 */
+ __I uint32_t UNUSED_SPACE1[6]; /*!< Offset: 0xc8 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_0_TypeDef CFG_BIT_MAP_INDEX_CS0_0; /*!< Offset: 0xe0 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_1_TypeDef CFG_BIT_MAP_INDEX_CS0_1; /*!< Offset: 0xe4 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_0_TypeDef CFG_BIT_MAP_INDEX_CS1_0; /*!< Offset: 0xe8 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_1_TypeDef CFG_BIT_MAP_INDEX_CS1_1; /*!< Offset: 0xec */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_0_TypeDef CFG_BIT_MAP_INDEX_CS2_0; /*!< Offset: 0xf0 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_1_TypeDef CFG_BIT_MAP_INDEX_CS2_1; /*!< Offset: 0xf4 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_0_TypeDef CFG_BIT_MAP_INDEX_CS3_0; /*!< Offset: 0xf8 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_1_TypeDef CFG_BIT_MAP_INDEX_CS3_1; /*!< Offset: 0xfc */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_0_TypeDef CFG_BIT_MAP_INDEX_CS4_0; /*!< Offset: 0x100 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_1_TypeDef CFG_BIT_MAP_INDEX_CS4_1; /*!< Offset: 0x104 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_0_TypeDef CFG_BIT_MAP_INDEX_CS5_0; /*!< Offset: 0x108 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_1_TypeDef CFG_BIT_MAP_INDEX_CS5_1; /*!< Offset: 0x10c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_0_TypeDef CFG_BIT_MAP_INDEX_CS6_0; /*!< Offset: 0x110 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_1_TypeDef CFG_BIT_MAP_INDEX_CS6_1; /*!< Offset: 0x114 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_0_TypeDef CFG_BIT_MAP_INDEX_CS7_0; /*!< Offset: 0x118 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_1_TypeDef CFG_BIT_MAP_INDEX_CS7_1; /*!< Offset: 0x11c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_0_TypeDef CFG_BIT_MAP_INDEX_CS8_0; /*!< Offset: 0x120 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_1_TypeDef CFG_BIT_MAP_INDEX_CS8_1; /*!< Offset: 0x124 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_0_TypeDef CFG_BIT_MAP_INDEX_CS9_0; /*!< Offset: 0x128 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_1_TypeDef CFG_BIT_MAP_INDEX_CS9_1; /*!< Offset: 0x12c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_0_TypeDef CFG_BIT_MAP_INDEX_CS10_0; /*!< Offset: 0x130 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_1_TypeDef CFG_BIT_MAP_INDEX_CS10_1; /*!< Offset: 0x134 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_0_TypeDef CFG_BIT_MAP_INDEX_CS11_0; /*!< Offset: 0x138 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_1_TypeDef CFG_BIT_MAP_INDEX_CS11_1; /*!< Offset: 0x13c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_0_TypeDef CFG_BIT_MAP_INDEX_CS12_0; /*!< Offset: 0x140 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_1_TypeDef CFG_BIT_MAP_INDEX_CS12_1; /*!< Offset: 0x144 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_0_TypeDef CFG_BIT_MAP_INDEX_CS13_0; /*!< Offset: 0x148 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_1_TypeDef CFG_BIT_MAP_INDEX_CS13_1; /*!< Offset: 0x14c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_0_TypeDef CFG_BIT_MAP_INDEX_CS14_0; /*!< Offset: 0x150 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_1_TypeDef CFG_BIT_MAP_INDEX_CS14_1; /*!< Offset: 0x154 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_0_TypeDef CFG_BIT_MAP_INDEX_CS15_0; /*!< Offset: 0x158 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_1_TypeDef CFG_BIT_MAP_INDEX_CS15_1; /*!< Offset: 0x15c */
+ __IO DDR_CSR_APB_CFG_NUM_LOGICAL_RANKS_PER_3DS_TypeDef CFG_NUM_LOGICAL_RANKS_PER_3DS; /*!< Offset: 0x160 */
+ __IO DDR_CSR_APB_CFG_RFC_DLR1_TypeDef CFG_RFC_DLR1; /*!< Offset: 0x164 */
+ __IO DDR_CSR_APB_CFG_RFC_DLR2_TypeDef CFG_RFC_DLR2; /*!< Offset: 0x168 */
+ __IO DDR_CSR_APB_CFG_RFC_DLR4_TypeDef CFG_RFC_DLR4; /*!< Offset: 0x16c */
+ __IO DDR_CSR_APB_CFG_RRD_DLR_TypeDef CFG_RRD_DLR; /*!< Offset: 0x170 */
+ __IO DDR_CSR_APB_CFG_FAW_DLR_TypeDef CFG_FAW_DLR; /*!< Offset: 0x174 */
+ __I uint32_t UNUSED_SPACE2[8]; /*!< Offset: 0x178 */
+ __IO DDR_CSR_APB_CFG_ADVANCE_ACTIVATE_READY_TypeDef CFG_ADVANCE_ACTIVATE_READY; /*!< Offset: 0x198 */
+ __I uint32_t UNUSED_SPACE3[6]; /*!< Offset: 0x19c */
+} DDR_CSR_APB_MC_BASE1_TypeDef;
+
+/*------------ MC_BASE2 register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CTRLR_SOFT_RESET_N_TypeDef CTRLR_SOFT_RESET_N; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_LOOKAHEAD_PCH_TypeDef CFG_LOOKAHEAD_PCH; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_LOOKAHEAD_ACT_TypeDef CFG_LOOKAHEAD_ACT; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_INIT_AUTOINIT_DISABLE_TypeDef INIT_AUTOINIT_DISABLE; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_INIT_FORCE_RESET_TypeDef INIT_FORCE_RESET; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_INIT_GEARDOWN_EN_TypeDef INIT_GEARDOWN_EN; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_INIT_DISABLE_CKE_TypeDef INIT_DISABLE_CKE; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_INIT_CS_TypeDef INIT_CS; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_INIT_PRECHARGE_ALL_TypeDef INIT_PRECHARGE_ALL; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_INIT_REFRESH_TypeDef INIT_REFRESH; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_INIT_ZQ_CAL_REQ_TypeDef INIT_ZQ_CAL_REQ; /*!< Offset: 0x2c */
+ __I DDR_CSR_APB_INIT_ACK_TypeDef INIT_ACK; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_BL_TypeDef CFG_BL; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_CTRLR_INIT_TypeDef CTRLR_INIT; /*!< Offset: 0x38 */
+ __I DDR_CSR_APB_CTRLR_INIT_DONE_TypeDef CTRLR_INIT_DONE; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_AUTO_REF_EN_TypeDef CFG_AUTO_REF_EN; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_RAS_TypeDef CFG_RAS; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_CFG_RCD_TypeDef CFG_RCD; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_CFG_RRD_TypeDef CFG_RRD; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_CFG_RP_TypeDef CFG_RP; /*!< Offset: 0x50 */
+ __IO DDR_CSR_APB_CFG_RC_TypeDef CFG_RC; /*!< Offset: 0x54 */
+ __IO DDR_CSR_APB_CFG_FAW_TypeDef CFG_FAW; /*!< Offset: 0x58 */
+ __IO DDR_CSR_APB_CFG_RFC_TypeDef CFG_RFC; /*!< Offset: 0x5c */
+ __IO DDR_CSR_APB_CFG_RTP_TypeDef CFG_RTP; /*!< Offset: 0x60 */
+ __IO DDR_CSR_APB_CFG_WR_TypeDef CFG_WR; /*!< Offset: 0x64 */
+ __IO DDR_CSR_APB_CFG_WTR_TypeDef CFG_WTR; /*!< Offset: 0x68 */
+ __I uint32_t UNUSED_SPACE1; /*!< Offset: 0x6c */
+ __IO DDR_CSR_APB_CFG_PASR_TypeDef CFG_PASR; /*!< Offset: 0x70 */
+ __IO DDR_CSR_APB_CFG_XP_TypeDef CFG_XP; /*!< Offset: 0x74 */
+ __IO DDR_CSR_APB_CFG_XSR_TypeDef CFG_XSR; /*!< Offset: 0x78 */
+ __I uint32_t UNUSED_SPACE2; /*!< Offset: 0x7c */
+ __IO DDR_CSR_APB_CFG_CL_TypeDef CFG_CL; /*!< Offset: 0x80 */
+ __I uint32_t UNUSED_SPACE3; /*!< Offset: 0x84 */
+ __IO DDR_CSR_APB_CFG_READ_TO_WRITE_TypeDef CFG_READ_TO_WRITE; /*!< Offset: 0x88 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_WRITE_TypeDef CFG_WRITE_TO_WRITE; /*!< Offset: 0x8c */
+ __IO DDR_CSR_APB_CFG_READ_TO_READ_TypeDef CFG_READ_TO_READ; /*!< Offset: 0x90 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_READ_TypeDef CFG_WRITE_TO_READ; /*!< Offset: 0x94 */
+ __IO DDR_CSR_APB_CFG_READ_TO_WRITE_ODT_TypeDef CFG_READ_TO_WRITE_ODT; /*!< Offset: 0x98 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_WRITE_ODT_TypeDef CFG_WRITE_TO_WRITE_ODT; /*!< Offset: 0x9c */
+ __IO DDR_CSR_APB_CFG_READ_TO_READ_ODT_TypeDef CFG_READ_TO_READ_ODT; /*!< Offset: 0xa0 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_READ_ODT_TypeDef CFG_WRITE_TO_READ_ODT; /*!< Offset: 0xa4 */
+ __IO DDR_CSR_APB_CFG_MIN_READ_IDLE_TypeDef CFG_MIN_READ_IDLE; /*!< Offset: 0xa8 */
+ __IO DDR_CSR_APB_CFG_MRD_TypeDef CFG_MRD; /*!< Offset: 0xac */
+ __IO DDR_CSR_APB_CFG_BT_TypeDef CFG_BT; /*!< Offset: 0xb0 */
+ __IO DDR_CSR_APB_CFG_DS_TypeDef CFG_DS; /*!< Offset: 0xb4 */
+ __IO DDR_CSR_APB_CFG_QOFF_TypeDef CFG_QOFF; /*!< Offset: 0xb8 */
+ __I uint32_t UNUSED_SPACE4[2]; /*!< Offset: 0xbc */
+ __IO DDR_CSR_APB_CFG_RTT_TypeDef CFG_RTT; /*!< Offset: 0xc4 */
+ __IO DDR_CSR_APB_CFG_DLL_DISABLE_TypeDef CFG_DLL_DISABLE; /*!< Offset: 0xc8 */
+ __IO DDR_CSR_APB_CFG_REF_PER_TypeDef CFG_REF_PER; /*!< Offset: 0xcc */
+ __IO DDR_CSR_APB_CFG_STARTUP_DELAY_TypeDef CFG_STARTUP_DELAY; /*!< Offset: 0xd0 */
+ __IO DDR_CSR_APB_CFG_MEM_COLBITS_TypeDef CFG_MEM_COLBITS; /*!< Offset: 0xd4 */
+ __IO DDR_CSR_APB_CFG_MEM_ROWBITS_TypeDef CFG_MEM_ROWBITS; /*!< Offset: 0xd8 */
+ __IO DDR_CSR_APB_CFG_MEM_BANKBITS_TypeDef CFG_MEM_BANKBITS; /*!< Offset: 0xdc */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS0_TypeDef CFG_ODT_RD_MAP_CS0; /*!< Offset: 0xe0 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS1_TypeDef CFG_ODT_RD_MAP_CS1; /*!< Offset: 0xe4 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS2_TypeDef CFG_ODT_RD_MAP_CS2; /*!< Offset: 0xe8 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS3_TypeDef CFG_ODT_RD_MAP_CS3; /*!< Offset: 0xec */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS4_TypeDef CFG_ODT_RD_MAP_CS4; /*!< Offset: 0xf0 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS5_TypeDef CFG_ODT_RD_MAP_CS5; /*!< Offset: 0xf4 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS6_TypeDef CFG_ODT_RD_MAP_CS6; /*!< Offset: 0xf8 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS7_TypeDef CFG_ODT_RD_MAP_CS7; /*!< Offset: 0xfc */
+ __I uint32_t UNUSED_SPACE5[8]; /*!< Offset: 0x100 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS0_TypeDef CFG_ODT_WR_MAP_CS0; /*!< Offset: 0x120 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS1_TypeDef CFG_ODT_WR_MAP_CS1; /*!< Offset: 0x124 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS2_TypeDef CFG_ODT_WR_MAP_CS2; /*!< Offset: 0x128 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS3_TypeDef CFG_ODT_WR_MAP_CS3; /*!< Offset: 0x12c */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS4_TypeDef CFG_ODT_WR_MAP_CS4; /*!< Offset: 0x130 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS5_TypeDef CFG_ODT_WR_MAP_CS5; /*!< Offset: 0x134 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS6_TypeDef CFG_ODT_WR_MAP_CS6; /*!< Offset: 0x138 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS7_TypeDef CFG_ODT_WR_MAP_CS7; /*!< Offset: 0x13c */
+ __I uint32_t UNUSED_SPACE6[8]; /*!< Offset: 0x140 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_TURN_ON_TypeDef CFG_ODT_RD_TURN_ON; /*!< Offset: 0x160 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_TURN_ON_TypeDef CFG_ODT_WR_TURN_ON; /*!< Offset: 0x164 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_TURN_OFF_TypeDef CFG_ODT_RD_TURN_OFF; /*!< Offset: 0x168 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_TURN_OFF_TypeDef CFG_ODT_WR_TURN_OFF; /*!< Offset: 0x16c */
+ __I uint32_t UNUSED_SPACE7[2]; /*!< Offset: 0x170 */
+ __IO DDR_CSR_APB_CFG_EMR3_TypeDef CFG_EMR3; /*!< Offset: 0x178 */
+ __IO DDR_CSR_APB_CFG_TWO_T_TypeDef CFG_TWO_T; /*!< Offset: 0x17c */
+ __IO DDR_CSR_APB_CFG_TWO_T_SEL_CYCLE_TypeDef CFG_TWO_T_SEL_CYCLE; /*!< Offset: 0x180 */
+ __IO DDR_CSR_APB_CFG_REGDIMM_TypeDef CFG_REGDIMM; /*!< Offset: 0x184 */
+ __IO DDR_CSR_APB_CFG_MOD_TypeDef CFG_MOD; /*!< Offset: 0x188 */
+ __IO DDR_CSR_APB_CFG_XS_TypeDef CFG_XS; /*!< Offset: 0x18c */
+ __IO DDR_CSR_APB_CFG_XSDLL_TypeDef CFG_XSDLL; /*!< Offset: 0x190 */
+ __IO DDR_CSR_APB_CFG_XPR_TypeDef CFG_XPR; /*!< Offset: 0x194 */
+ __IO DDR_CSR_APB_CFG_AL_MODE_TypeDef CFG_AL_MODE; /*!< Offset: 0x198 */
+ __IO DDR_CSR_APB_CFG_CWL_TypeDef CFG_CWL; /*!< Offset: 0x19c */
+ __IO DDR_CSR_APB_CFG_BL_MODE_TypeDef CFG_BL_MODE; /*!< Offset: 0x1a0 */
+ __IO DDR_CSR_APB_CFG_TDQS_TypeDef CFG_TDQS; /*!< Offset: 0x1a4 */
+ __IO DDR_CSR_APB_CFG_RTT_WR_TypeDef CFG_RTT_WR; /*!< Offset: 0x1a8 */
+ __IO DDR_CSR_APB_CFG_LP_ASR_TypeDef CFG_LP_ASR; /*!< Offset: 0x1ac */
+ __IO DDR_CSR_APB_CFG_AUTO_SR_TypeDef CFG_AUTO_SR; /*!< Offset: 0x1b0 */
+ __IO DDR_CSR_APB_CFG_SRT_TypeDef CFG_SRT; /*!< Offset: 0x1b4 */
+ __IO DDR_CSR_APB_CFG_ADDR_MIRROR_TypeDef CFG_ADDR_MIRROR; /*!< Offset: 0x1b8 */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_TYPE_TypeDef CFG_ZQ_CAL_TYPE; /*!< Offset: 0x1bc */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_PER_TypeDef CFG_ZQ_CAL_PER; /*!< Offset: 0x1c0 */
+ __IO DDR_CSR_APB_CFG_AUTO_ZQ_CAL_EN_TypeDef CFG_AUTO_ZQ_CAL_EN; /*!< Offset: 0x1c4 */
+ __IO DDR_CSR_APB_CFG_MEMORY_TYPE_TypeDef CFG_MEMORY_TYPE; /*!< Offset: 0x1c8 */
+ __IO DDR_CSR_APB_CFG_ONLY_SRANK_CMDS_TypeDef CFG_ONLY_SRANK_CMDS; /*!< Offset: 0x1cc */
+ __IO DDR_CSR_APB_CFG_NUM_RANKS_TypeDef CFG_NUM_RANKS; /*!< Offset: 0x1d0 */
+ __IO DDR_CSR_APB_CFG_QUAD_RANK_TypeDef CFG_QUAD_RANK; /*!< Offset: 0x1d4 */
+ __I uint32_t UNUSED_SPACE8; /*!< Offset: 0x1d8 */
+ __IO DDR_CSR_APB_CFG_EARLY_RANK_TO_WR_START_TypeDef CFG_EARLY_RANK_TO_WR_START; /*!< Offset: 0x1dc */
+ __IO DDR_CSR_APB_CFG_EARLY_RANK_TO_RD_START_TypeDef CFG_EARLY_RANK_TO_RD_START; /*!< Offset: 0x1e0 */
+ __IO DDR_CSR_APB_CFG_PASR_BANK_TypeDef CFG_PASR_BANK; /*!< Offset: 0x1e4 */
+ __IO DDR_CSR_APB_CFG_PASR_SEG_TypeDef CFG_PASR_SEG; /*!< Offset: 0x1e8 */
+ __IO DDR_CSR_APB_INIT_MRR_MODE_TypeDef INIT_MRR_MODE; /*!< Offset: 0x1ec */
+ __IO DDR_CSR_APB_INIT_MR_W_REQ_TypeDef INIT_MR_W_REQ; /*!< Offset: 0x1f0 */
+ __IO DDR_CSR_APB_INIT_MR_ADDR_TypeDef INIT_MR_ADDR; /*!< Offset: 0x1f4 */
+ __IO DDR_CSR_APB_INIT_MR_WR_DATA_TypeDef INIT_MR_WR_DATA; /*!< Offset: 0x1f8 */
+ __IO DDR_CSR_APB_INIT_MR_WR_MASK_TypeDef INIT_MR_WR_MASK; /*!< Offset: 0x1fc */
+ __IO DDR_CSR_APB_INIT_NOP_TypeDef INIT_NOP; /*!< Offset: 0x200 */
+ __IO DDR_CSR_APB_CFG_INIT_DURATION_TypeDef CFG_INIT_DURATION; /*!< Offset: 0x204 */
+ __IO DDR_CSR_APB_CFG_ZQINIT_CAL_DURATION_TypeDef CFG_ZQINIT_CAL_DURATION; /*!< Offset: 0x208 */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_L_DURATION_TypeDef CFG_ZQ_CAL_L_DURATION; /*!< Offset: 0x20c */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_S_DURATION_TypeDef CFG_ZQ_CAL_S_DURATION; /*!< Offset: 0x210 */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_R_DURATION_TypeDef CFG_ZQ_CAL_R_DURATION; /*!< Offset: 0x214 */
+ __IO DDR_CSR_APB_CFG_MRR_TypeDef CFG_MRR; /*!< Offset: 0x218 */
+ __IO DDR_CSR_APB_CFG_MRW_TypeDef CFG_MRW; /*!< Offset: 0x21c */
+ __IO DDR_CSR_APB_CFG_ODT_POWERDOWN_TypeDef CFG_ODT_POWERDOWN; /*!< Offset: 0x220 */
+ __IO DDR_CSR_APB_CFG_WL_TypeDef CFG_WL; /*!< Offset: 0x224 */
+ __IO DDR_CSR_APB_CFG_RL_TypeDef CFG_RL; /*!< Offset: 0x228 */
+ __IO DDR_CSR_APB_CFG_CAL_READ_PERIOD_TypeDef CFG_CAL_READ_PERIOD; /*!< Offset: 0x22c */
+ __IO DDR_CSR_APB_CFG_NUM_CAL_READS_TypeDef CFG_NUM_CAL_READS; /*!< Offset: 0x230 */
+ __IO DDR_CSR_APB_INIT_SELF_REFRESH_TypeDef INIT_SELF_REFRESH; /*!< Offset: 0x234 */
+ __I DDR_CSR_APB_INIT_SELF_REFRESH_STATUS_TypeDef INIT_SELF_REFRESH_STATUS; /*!< Offset: 0x238 */
+ __IO DDR_CSR_APB_INIT_POWER_DOWN_TypeDef INIT_POWER_DOWN; /*!< Offset: 0x23c */
+ __I DDR_CSR_APB_INIT_POWER_DOWN_STATUS_TypeDef INIT_POWER_DOWN_STATUS; /*!< Offset: 0x240 */
+ __IO DDR_CSR_APB_INIT_FORCE_WRITE_TypeDef INIT_FORCE_WRITE; /*!< Offset: 0x244 */
+ __IO DDR_CSR_APB_INIT_FORCE_WRITE_CS_TypeDef INIT_FORCE_WRITE_CS; /*!< Offset: 0x248 */
+ __IO DDR_CSR_APB_CFG_CTRLR_INIT_DISABLE_TypeDef CFG_CTRLR_INIT_DISABLE; /*!< Offset: 0x24c */
+ __I DDR_CSR_APB_CTRLR_READY_TypeDef CTRLR_READY; /*!< Offset: 0x250 */
+ __I DDR_CSR_APB_INIT_RDIMM_READY_TypeDef INIT_RDIMM_READY; /*!< Offset: 0x254 */
+ __IO DDR_CSR_APB_INIT_RDIMM_COMPLETE_TypeDef INIT_RDIMM_COMPLETE; /*!< Offset: 0x258 */
+ __IO DDR_CSR_APB_CFG_RDIMM_LAT_TypeDef CFG_RDIMM_LAT; /*!< Offset: 0x25c */
+ __IO DDR_CSR_APB_CFG_RDIMM_BSIDE_INVERT_TypeDef CFG_RDIMM_BSIDE_INVERT; /*!< Offset: 0x260 */
+ __IO DDR_CSR_APB_CFG_LRDIMM_TypeDef CFG_LRDIMM; /*!< Offset: 0x264 */
+ __IO DDR_CSR_APB_INIT_MEMORY_RESET_MASK_TypeDef INIT_MEMORY_RESET_MASK; /*!< Offset: 0x268 */
+ __IO DDR_CSR_APB_CFG_RD_PREAMB_TOGGLE_TypeDef CFG_RD_PREAMB_TOGGLE; /*!< Offset: 0x26c */
+ __IO DDR_CSR_APB_CFG_RD_POSTAMBLE_TypeDef CFG_RD_POSTAMBLE; /*!< Offset: 0x270 */
+ __IO DDR_CSR_APB_CFG_PU_CAL_TypeDef CFG_PU_CAL; /*!< Offset: 0x274 */
+ __IO DDR_CSR_APB_CFG_DQ_ODT_TypeDef CFG_DQ_ODT; /*!< Offset: 0x278 */
+ __IO DDR_CSR_APB_CFG_CA_ODT_TypeDef CFG_CA_ODT; /*!< Offset: 0x27c */
+ __IO DDR_CSR_APB_CFG_ZQLATCH_DURATION_TypeDef CFG_ZQLATCH_DURATION; /*!< Offset: 0x280 */
+ __IO DDR_CSR_APB_INIT_CAL_SELECT_TypeDef INIT_CAL_SELECT; /*!< Offset: 0x284 */
+ __IO DDR_CSR_APB_INIT_CAL_L_R_REQ_TypeDef INIT_CAL_L_R_REQ; /*!< Offset: 0x288 */
+ __IO DDR_CSR_APB_INIT_CAL_L_B_SIZE_TypeDef INIT_CAL_L_B_SIZE; /*!< Offset: 0x28c */
+ __I DDR_CSR_APB_INIT_CAL_L_R_ACK_TypeDef INIT_CAL_L_R_ACK; /*!< Offset: 0x290 */
+ __I DDR_CSR_APB_INIT_CAL_L_READ_COMPLETE_TypeDef INIT_CAL_L_READ_COMPLETE; /*!< Offset: 0x294 */
+ __I uint32_t UNUSED_SPACE9[2]; /*!< Offset: 0x298 */
+ __IO DDR_CSR_APB_INIT_RWFIFO_TypeDef INIT_RWFIFO; /*!< Offset: 0x2a0 */
+ __IO DDR_CSR_APB_INIT_RD_DQCAL_TypeDef INIT_RD_DQCAL; /*!< Offset: 0x2a4 */
+ __IO DDR_CSR_APB_INIT_START_DQSOSC_TypeDef INIT_START_DQSOSC; /*!< Offset: 0x2a8 */
+ __IO DDR_CSR_APB_INIT_STOP_DQSOSC_TypeDef INIT_STOP_DQSOSC; /*!< Offset: 0x2ac */
+ __IO DDR_CSR_APB_INIT_ZQ_CAL_START_TypeDef INIT_ZQ_CAL_START; /*!< Offset: 0x2b0 */
+ __IO DDR_CSR_APB_CFG_WR_POSTAMBLE_TypeDef CFG_WR_POSTAMBLE; /*!< Offset: 0x2b4 */
+ __I uint32_t UNUSED_SPACE10; /*!< Offset: 0x2b8 */
+ __IO DDR_CSR_APB_INIT_CAL_L_ADDR_0_TypeDef INIT_CAL_L_ADDR_0; /*!< Offset: 0x2bc */
+ __IO DDR_CSR_APB_INIT_CAL_L_ADDR_1_TypeDef INIT_CAL_L_ADDR_1; /*!< Offset: 0x2c0 */
+ __IO DDR_CSR_APB_CFG_CTRLUPD_TRIG_TypeDef CFG_CTRLUPD_TRIG; /*!< Offset: 0x2c4 */
+ __IO DDR_CSR_APB_CFG_CTRLUPD_START_DELAY_TypeDef CFG_CTRLUPD_START_DELAY; /*!< Offset: 0x2c8 */
+ __IO DDR_CSR_APB_CFG_DFI_T_CTRLUPD_MAX_TypeDef CFG_DFI_T_CTRLUPD_MAX; /*!< Offset: 0x2cc */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_SEL_TypeDef CFG_CTRLR_BUSY_SEL; /*!< Offset: 0x2d0 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_VALUE_TypeDef CFG_CTRLR_BUSY_VALUE; /*!< Offset: 0x2d4 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_TURN_OFF_DELAY_TypeDef CFG_CTRLR_BUSY_TURN_OFF_DELAY; /*!< Offset: 0x2d8 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW_TypeDef CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW; /*!< Offset: 0x2dc */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_RESTART_HOLDOFF_TypeDef CFG_CTRLR_BUSY_RESTART_HOLDOFF; /*!< Offset: 0x2e0 */
+ __IO DDR_CSR_APB_CFG_PARITY_RDIMM_DELAY_TypeDef CFG_PARITY_RDIMM_DELAY; /*!< Offset: 0x2e4 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_ENABLE_TypeDef CFG_CTRLR_BUSY_ENABLE; /*!< Offset: 0x2e8 */
+ __IO DDR_CSR_APB_CFG_ASYNC_ODT_TypeDef CFG_ASYNC_ODT; /*!< Offset: 0x2ec */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_DURATION_TypeDef CFG_ZQ_CAL_DURATION; /*!< Offset: 0x2f0 */
+ __IO DDR_CSR_APB_CFG_MRRI_TypeDef CFG_MRRI; /*!< Offset: 0x2f4 */
+ __IO DDR_CSR_APB_INIT_ODT_FORCE_EN_TypeDef INIT_ODT_FORCE_EN; /*!< Offset: 0x2f8 */
+ __IO DDR_CSR_APB_INIT_ODT_FORCE_RANK_TypeDef INIT_ODT_FORCE_RANK; /*!< Offset: 0x2fc */
+ __IO DDR_CSR_APB_CFG_PHYUPD_ACK_DELAY_TypeDef CFG_PHYUPD_ACK_DELAY; /*!< Offset: 0x300 */
+ __IO DDR_CSR_APB_CFG_MIRROR_X16_BG0_BG1_TypeDef CFG_MIRROR_X16_BG0_BG1; /*!< Offset: 0x304 */
+ __IO DDR_CSR_APB_INIT_PDA_MR_W_REQ_TypeDef INIT_PDA_MR_W_REQ; /*!< Offset: 0x308 */
+ __IO DDR_CSR_APB_INIT_PDA_NIBBLE_SELECT_TypeDef INIT_PDA_NIBBLE_SELECT; /*!< Offset: 0x30c */
+ __IO DDR_CSR_APB_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH_TypeDef CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH; /*!< Offset: 0x310 */
+ __IO DDR_CSR_APB_CFG_CKSRE_TypeDef CFG_CKSRE; /*!< Offset: 0x314 */
+ __IO DDR_CSR_APB_CFG_CKSRX_TypeDef CFG_CKSRX; /*!< Offset: 0x318 */
+ __IO DDR_CSR_APB_CFG_RCD_STAB_TypeDef CFG_RCD_STAB; /*!< Offset: 0x31c */
+ __IO DDR_CSR_APB_CFG_DFI_T_CTRL_DELAY_TypeDef CFG_DFI_T_CTRL_DELAY; /*!< Offset: 0x320 */
+ __IO DDR_CSR_APB_CFG_DFI_T_DRAM_CLK_ENABLE_TypeDef CFG_DFI_T_DRAM_CLK_ENABLE; /*!< Offset: 0x324 */
+ __IO DDR_CSR_APB_CFG_IDLE_TIME_TO_SELF_REFRESH_TypeDef CFG_IDLE_TIME_TO_SELF_REFRESH; /*!< Offset: 0x328 */
+ __IO DDR_CSR_APB_CFG_IDLE_TIME_TO_POWER_DOWN_TypeDef CFG_IDLE_TIME_TO_POWER_DOWN; /*!< Offset: 0x32c */
+ __IO DDR_CSR_APB_CFG_BURST_RW_REFRESH_HOLDOFF_TypeDef CFG_BURST_RW_REFRESH_HOLDOFF; /*!< Offset: 0x330 */
+ __I DDR_CSR_APB_INIT_REFRESH_COUNT_TypeDef INIT_REFRESH_COUNT; /*!< Offset: 0x334 */
+ __I uint32_t UNUSED_SPACE11[19]; /*!< Offset: 0x338 */
+ __IO DDR_CSR_APB_CFG_BG_INTERLEAVE_TypeDef CFG_BG_INTERLEAVE; /*!< Offset: 0x384 */
+ __I uint32_t UNUSED_SPACE12[29]; /*!< Offset: 0x388 */
+ __IO DDR_CSR_APB_CFG_REFRESH_DURING_PHY_TRAINING_TypeDef CFG_REFRESH_DURING_PHY_TRAINING; /*!< Offset: 0x3fc */
+} DDR_CSR_APB_MC_BASE2_TypeDef;
+
+/*------------ MEM_TEST register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_MT_EN_TypeDef MT_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_MT_EN_SINGLE_TypeDef MT_EN_SINGLE; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_MT_STOP_ON_ERROR_TypeDef MT_STOP_ON_ERROR; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_MT_RD_ONLY_TypeDef MT_RD_ONLY; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_MT_WR_ONLY_TypeDef MT_WR_ONLY; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_MT_DATA_PATTERN_TypeDef MT_DATA_PATTERN; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_MT_ADDR_PATTERN_TypeDef MT_ADDR_PATTERN; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_MT_DATA_INVERT_TypeDef MT_DATA_INVERT; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_MT_ADDR_BITS_TypeDef MT_ADDR_BITS; /*!< Offset: 0x20 */
+ __I DDR_CSR_APB_MT_ERROR_STS_TypeDef MT_ERROR_STS; /*!< Offset: 0x24 */
+ __I DDR_CSR_APB_MT_DONE_ACK_TypeDef MT_DONE_ACK; /*!< Offset: 0x28 */
+ __I uint32_t UNUSED_SPACE0[34]; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_MT_START_ADDR_0_TypeDef MT_START_ADDR_0; /*!< Offset: 0xb4 */
+ __IO DDR_CSR_APB_MT_START_ADDR_1_TypeDef MT_START_ADDR_1; /*!< Offset: 0xb8 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_0_TypeDef MT_ERROR_MASK_0; /*!< Offset: 0xbc */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_1_TypeDef MT_ERROR_MASK_1; /*!< Offset: 0xc0 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_2_TypeDef MT_ERROR_MASK_2; /*!< Offset: 0xc4 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_3_TypeDef MT_ERROR_MASK_3; /*!< Offset: 0xc8 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_4_TypeDef MT_ERROR_MASK_4; /*!< Offset: 0xcc */
+ __I uint32_t UNUSED_SPACE1[104]; /*!< Offset: 0xd0 */
+ __IO DDR_CSR_APB_MT_USER_DATA_PATTERN_TypeDef MT_USER_DATA_PATTERN; /*!< Offset: 0x270 */
+ __I uint32_t UNUSED_SPACE2[2]; /*!< Offset: 0x274 */
+ __IO DDR_CSR_APB_MT_ALG_AUTO_PCH_TypeDef MT_ALG_AUTO_PCH; /*!< Offset: 0x27c */
+ __I uint32_t UNUSED_SPACE3[2]; /*!< Offset: 0x280 */
+} DDR_CSR_APB_MEM_TEST_TypeDef;
+
+/*------------ MPFE register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P0_TypeDef CFG_STARVE_TIMEOUT_P0; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P1_TypeDef CFG_STARVE_TIMEOUT_P1; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P2_TypeDef CFG_STARVE_TIMEOUT_P2; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P3_TypeDef CFG_STARVE_TIMEOUT_P3; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P4_TypeDef CFG_STARVE_TIMEOUT_P4; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P5_TypeDef CFG_STARVE_TIMEOUT_P5; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P6_TypeDef CFG_STARVE_TIMEOUT_P6; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P7_TypeDef CFG_STARVE_TIMEOUT_P7; /*!< Offset: 0x1c */
+ __I uint32_t UNUSED_SPACE0[33]; /*!< Offset: 0x20 */
+} DDR_CSR_APB_MPFE_TypeDef;
+
+/*------------ REORDER register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_REORDER_EN_TypeDef CFG_REORDER_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_REORDER_QUEUE_EN_TypeDef CFG_REORDER_QUEUE_EN; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_INTRAPORT_REORDER_EN_TypeDef CFG_INTRAPORT_REORDER_EN; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_MAINTAIN_COHERENCY_TypeDef CFG_MAINTAIN_COHERENCY; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_Q_AGE_LIMIT_TypeDef CFG_Q_AGE_LIMIT; /*!< Offset: 0x10 */
+ __I uint32_t UNUSED_SPACE0; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_RO_CLOSED_PAGE_POLICY_TypeDef CFG_RO_CLOSED_PAGE_POLICY; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_REORDER_RW_ONLY_TypeDef CFG_REORDER_RW_ONLY; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_RO_PRIORITY_EN_TypeDef CFG_RO_PRIORITY_EN; /*!< Offset: 0x20 */
+} DDR_CSR_APB_REORDER_TypeDef;
+
+/*------------ RMW register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_DM_EN_TypeDef CFG_DM_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_RMW_EN_TypeDef CFG_RMW_EN; /*!< Offset: 0x4 */
+} DDR_CSR_APB_RMW_TypeDef;
+
+/*------------ ECC register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_ECC_CORRECTION_EN_TypeDef CFG_ECC_CORRECTION_EN; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0[15]; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_ECC_BYPASS_TypeDef CFG_ECC_BYPASS; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_INIT_WRITE_DATA_1B_ECC_ERROR_GEN_TypeDef INIT_WRITE_DATA_1B_ECC_ERROR_GEN; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_INIT_WRITE_DATA_2B_ECC_ERROR_GEN_TypeDef INIT_WRITE_DATA_2B_ECC_ERROR_GEN; /*!< Offset: 0x48 */
+ __I uint32_t UNUSED_SPACE1[4]; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_CFG_ECC_1BIT_INT_THRESH_TypeDef CFG_ECC_1BIT_INT_THRESH; /*!< Offset: 0x5c */
+ __I DDR_CSR_APB_STAT_INT_ECC_1BIT_THRESH_TypeDef STAT_INT_ECC_1BIT_THRESH; /*!< Offset: 0x60 */
+ __I uint32_t UNUSED_SPACE2[2]; /*!< Offset: 0x64 */
+} DDR_CSR_APB_ECC_TypeDef;
+
+/*------------ READ_CAPT register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_INIT_READ_CAPTURE_ADDR_TypeDef INIT_READ_CAPTURE_ADDR; /*!< Offset: 0x0 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_0_TypeDef INIT_READ_CAPTURE_DATA_0; /*!< Offset: 0x4 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_1_TypeDef INIT_READ_CAPTURE_DATA_1; /*!< Offset: 0x8 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_2_TypeDef INIT_READ_CAPTURE_DATA_2; /*!< Offset: 0xc */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_3_TypeDef INIT_READ_CAPTURE_DATA_3; /*!< Offset: 0x10 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_4_TypeDef INIT_READ_CAPTURE_DATA_4; /*!< Offset: 0x14 */
+ __I uint32_t UNUSED_SPACE0[12]; /*!< Offset: 0x18 */
+} DDR_CSR_APB_READ_CAPT_TypeDef;
+
+/*------------ MTA register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_ERROR_GROUP_SEL_TypeDef CFG_ERROR_GROUP_SEL; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_DATA_SEL_TypeDef CFG_DATA_SEL; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_TRIG_MODE_TypeDef CFG_TRIG_MODE; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_POST_TRIG_CYCS_TypeDef CFG_POST_TRIG_CYCS; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_TRIG_MASK_TypeDef CFG_TRIG_MASK; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_EN_MASK_TypeDef CFG_EN_MASK; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_MTC_ACQ_ADDR_TypeDef MTC_ACQ_ADDR; /*!< Offset: 0x18 */
+ __I DDR_CSR_APB_MTC_ACQ_CYCS_STORED_TypeDef MTC_ACQ_CYCS_STORED; /*!< Offset: 0x1c */
+ __I DDR_CSR_APB_MTC_ACQ_TRIG_DETECT_TypeDef MTC_ACQ_TRIG_DETECT; /*!< Offset: 0x20 */
+ __I DDR_CSR_APB_MTC_ACQ_MEM_TRIG_ADDR_TypeDef MTC_ACQ_MEM_TRIG_ADDR; /*!< Offset: 0x24 */
+ __I DDR_CSR_APB_MTC_ACQ_MEM_LAST_ADDR_TypeDef MTC_ACQ_MEM_LAST_ADDR; /*!< Offset: 0x28 */
+ __I DDR_CSR_APB_MTC_ACK_TypeDef MTC_ACK; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_TRIG_MT_ADDR_0_TypeDef CFG_TRIG_MT_ADDR_0; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_TRIG_MT_ADDR_1_TypeDef CFG_TRIG_MT_ADDR_1; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_0_TypeDef CFG_TRIG_ERR_MASK_0; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_1_TypeDef CFG_TRIG_ERR_MASK_1; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_2_TypeDef CFG_TRIG_ERR_MASK_2; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_3_TypeDef CFG_TRIG_ERR_MASK_3; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_4_TypeDef CFG_TRIG_ERR_MASK_4; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_MTC_ACQ_WR_DATA_0_TypeDef MTC_ACQ_WR_DATA_0; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_MTC_ACQ_WR_DATA_1_TypeDef MTC_ACQ_WR_DATA_1; /*!< Offset: 0x50 */
+ __IO DDR_CSR_APB_MTC_ACQ_WR_DATA_2_TypeDef MTC_ACQ_WR_DATA_2; /*!< Offset: 0x54 */
+ __I DDR_CSR_APB_MTC_ACQ_RD_DATA_0_TypeDef MTC_ACQ_RD_DATA_0; /*!< Offset: 0x58 */
+ __I DDR_CSR_APB_MTC_ACQ_RD_DATA_1_TypeDef MTC_ACQ_RD_DATA_1; /*!< Offset: 0x5c */
+ __I DDR_CSR_APB_MTC_ACQ_RD_DATA_2_TypeDef MTC_ACQ_RD_DATA_2; /*!< Offset: 0x60 */
+ __I uint32_t UNUSED_SPACE0[50]; /*!< Offset: 0x64 */
+ __IO DDR_CSR_APB_CFG_PRE_TRIG_CYCS_TypeDef CFG_PRE_TRIG_CYCS; /*!< Offset: 0x12c */
+ __I uint32_t UNUSED_SPACE1[2]; /*!< Offset: 0x130 */
+ __I DDR_CSR_APB_MTC_ACQ_ERROR_CNT_TypeDef MTC_ACQ_ERROR_CNT; /*!< Offset: 0x138 */
+ __I uint32_t UNUSED_SPACE2[2]; /*!< Offset: 0x13c */
+ __I DDR_CSR_APB_MTC_ACQ_ERROR_CNT_OVFL_TypeDef MTC_ACQ_ERROR_CNT_OVFL; /*!< Offset: 0x144 */
+ __I uint32_t UNUSED_SPACE3[2]; /*!< Offset: 0x148 */
+ __IO DDR_CSR_APB_CFG_DATA_SEL_FIRST_ERROR_TypeDef CFG_DATA_SEL_FIRST_ERROR; /*!< Offset: 0x150 */
+ __I uint32_t UNUSED_SPACE4[2]; /*!< Offset: 0x154 */
+} DDR_CSR_APB_MTA_TypeDef;
+
+/*------------ DYN_WIDTH_ADJ register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_DQ_WIDTH_TypeDef CFG_DQ_WIDTH; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_ACTIVE_DQ_SEL_TypeDef CFG_ACTIVE_DQ_SEL; /*!< Offset: 0x4 */
+} DDR_CSR_APB_DYN_WIDTH_ADJ_TypeDef;
+
+/*------------ CA_PAR_ERR register bundle definition -----------*/
+typedef struct
+{
+ __I DDR_CSR_APB_STAT_CA_PARITY_ERROR_TypeDef STAT_CA_PARITY_ERROR; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0[2]; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_REQ_TypeDef INIT_CA_PARITY_ERROR_GEN_REQ; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_CMD_TypeDef INIT_CA_PARITY_ERROR_GEN_CMD; /*!< Offset: 0x10 */
+ __I DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_ACK_TypeDef INIT_CA_PARITY_ERROR_GEN_ACK; /*!< Offset: 0x14 */
+ __I uint32_t UNUSED_SPACE1[2]; /*!< Offset: 0x18 */
+} DDR_CSR_APB_CA_PAR_ERR_TypeDef;
+
+/*------------ DFI register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_DFI_T_RDDATA_EN_TypeDef CFG_DFI_T_RDDATA_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_DFI_T_PHY_RDLAT_TypeDef CFG_DFI_T_PHY_RDLAT; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_DFI_T_PHY_WRLAT_TypeDef CFG_DFI_T_PHY_WRLAT; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_DFI_PHYUPD_EN_TypeDef CFG_DFI_PHYUPD_EN; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_INIT_DFI_LP_DATA_REQ_TypeDef INIT_DFI_LP_DATA_REQ; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_INIT_DFI_LP_CTRL_REQ_TypeDef INIT_DFI_LP_CTRL_REQ; /*!< Offset: 0x14 */
+ __I DDR_CSR_APB_STAT_DFI_LP_ACK_TypeDef STAT_DFI_LP_ACK; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_INIT_DFI_LP_WAKEUP_TypeDef INIT_DFI_LP_WAKEUP; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_INIT_DFI_DRAM_CLK_DISABLE_TypeDef INIT_DFI_DRAM_CLK_DISABLE; /*!< Offset: 0x20 */
+ __I DDR_CSR_APB_STAT_DFI_TRAINING_ERROR_TypeDef STAT_DFI_TRAINING_ERROR; /*!< Offset: 0x24 */
+ __I DDR_CSR_APB_STAT_DFI_ERROR_TypeDef STAT_DFI_ERROR; /*!< Offset: 0x28 */
+ __I DDR_CSR_APB_STAT_DFI_ERROR_INFO_TypeDef STAT_DFI_ERROR_INFO; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_DFI_DATA_BYTE_DISABLE_TypeDef CFG_DFI_DATA_BYTE_DISABLE; /*!< Offset: 0x30 */
+ __I DDR_CSR_APB_STAT_DFI_INIT_COMPLETE_TypeDef STAT_DFI_INIT_COMPLETE; /*!< Offset: 0x34 */
+ __I DDR_CSR_APB_STAT_DFI_TRAINING_COMPLETE_TypeDef STAT_DFI_TRAINING_COMPLETE; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_CFG_DFI_LVL_SEL_TypeDef CFG_DFI_LVL_SEL; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_DFI_LVL_PERIODIC_TypeDef CFG_DFI_LVL_PERIODIC; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_DFI_LVL_PATTERN_TypeDef CFG_DFI_LVL_PATTERN; /*!< Offset: 0x44 */
+ __I uint32_t UNUSED_SPACE0[2]; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_PHY_DFI_INIT_START_TypeDef PHY_DFI_INIT_START; /*!< Offset: 0x50 */
+ __I uint32_t UNUSED_SPACE1; /*!< Offset: 0x54 */
+} DDR_CSR_APB_DFI_TypeDef;
+
+/*------------ AXI_IF register bundle definition -----------*/
+typedef struct
+{
+ __I uint32_t UNUSED_SPACE0[6]; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_0_TypeDef CFG_AXI_START_ADDRESS_AXI1_0; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_1_TypeDef CFG_AXI_START_ADDRESS_AXI1_1; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_0_TypeDef CFG_AXI_START_ADDRESS_AXI2_0; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_1_TypeDef CFG_AXI_START_ADDRESS_AXI2_1; /*!< Offset: 0x24 */
+ __I uint32_t UNUSED_SPACE1[188]; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_0_TypeDef CFG_AXI_END_ADDRESS_AXI1_0; /*!< Offset: 0x318 */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_1_TypeDef CFG_AXI_END_ADDRESS_AXI1_1; /*!< Offset: 0x31c */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_0_TypeDef CFG_AXI_END_ADDRESS_AXI2_0; /*!< Offset: 0x320 */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_1_TypeDef CFG_AXI_END_ADDRESS_AXI2_1; /*!< Offset: 0x324 */
+ __I uint32_t UNUSED_SPACE2[188]; /*!< Offset: 0x328 */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_0_TypeDef CFG_MEM_START_ADDRESS_AXI1_0; /*!< Offset: 0x618 */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_1_TypeDef CFG_MEM_START_ADDRESS_AXI1_1; /*!< Offset: 0x61c */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_0_TypeDef CFG_MEM_START_ADDRESS_AXI2_0; /*!< Offset: 0x620 */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_1_TypeDef CFG_MEM_START_ADDRESS_AXI2_1; /*!< Offset: 0x624 */
+ __I uint32_t UNUSED_SPACE3[187]; /*!< Offset: 0x628 */
+ __IO DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI1_TypeDef CFG_ENABLE_BUS_HOLD_AXI1; /*!< Offset: 0x914 */
+ __IO DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI2_TypeDef CFG_ENABLE_BUS_HOLD_AXI2; /*!< Offset: 0x918 */
+ __I uint32_t UNUSED_SPACE4[93]; /*!< Offset: 0x91c */
+ __IO DDR_CSR_APB_CFG_AXI_AUTO_PCH_TypeDef CFG_AXI_AUTO_PCH; /*!< Offset: 0xa90 */
+} DDR_CSR_APB_AXI_IF_TypeDef;
+
+/*------------ csr_custom register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_PHY_RESET_CONTROL_TypeDef PHY_RESET_CONTROL; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_PHY_PC_RANK_TypeDef PHY_PC_RANK; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_PHY_RANKS_TO_TRAIN_TypeDef PHY_RANKS_TO_TRAIN; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_PHY_WRITE_REQUEST_TypeDef PHY_WRITE_REQUEST; /*!< Offset: 0xc */
+ __I DDR_CSR_APB_PHY_WRITE_REQUEST_DONE_TypeDef PHY_WRITE_REQUEST_DONE; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_PHY_READ_REQUEST_TypeDef PHY_READ_REQUEST; /*!< Offset: 0x14 */
+ __I DDR_CSR_APB_PHY_READ_REQUEST_DONE_TypeDef PHY_READ_REQUEST_DONE; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_PHY_WRITE_LEVEL_DELAY_TypeDef PHY_WRITE_LEVEL_DELAY; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_PHY_GATE_TRAIN_DELAY_TypeDef PHY_GATE_TRAIN_DELAY; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_PHY_EYE_TRAIN_DELAY_TypeDef PHY_EYE_TRAIN_DELAY; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_PHY_EYE_PAT_TypeDef PHY_EYE_PAT; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_PHY_START_RECAL_TypeDef PHY_START_RECAL; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_PHY_CLR_DFI_LVL_PERIODIC_TypeDef PHY_CLR_DFI_LVL_PERIODIC; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_PHY_TRAIN_STEP_ENABLE_TypeDef PHY_TRAIN_STEP_ENABLE; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_PHY_LPDDR_DQ_CAL_PAT_TypeDef PHY_LPDDR_DQ_CAL_PAT; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_PHY_INDPNDT_TRAINING_TypeDef PHY_INDPNDT_TRAINING; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_PHY_ENCODED_QUAD_CS_TypeDef PHY_ENCODED_QUAD_CS; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_PHY_HALF_CLK_DLY_ENABLE_TypeDef PHY_HALF_CLK_DLY_ENABLE; /*!< Offset: 0x44 */
+ __I uint32_t UNUSED_SPACE0[25]; /*!< Offset: 0x48 */
+} DDR_CSR_APB_csr_custom_TypeDef;
+
+/*------------ DDR_CSR_APB definition -----------*/
+typedef struct
+{
+ __I uint32_t UNUSED_SPACE0[2304]; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_ADDR_MAP_TypeDef ADDR_MAP; /*!< Offset: 0x2400 */
+ __I uint32_t UNUSED_SPACE1[242]; /*!< Offset: 0x2438 */
+ __IO DDR_CSR_APB_MC_BASE3_TypeDef MC_BASE3; /*!< Offset: 0x2800 */
+ __I uint32_t UNUSED_SPACE2[1204]; /*!< Offset: 0x2930 */
+ __IO DDR_CSR_APB_MC_BASE1_TypeDef MC_BASE1; /*!< Offset: 0x3c00 */
+ __I uint32_t UNUSED_SPACE3[147]; /*!< Offset: 0x3db4 */
+ __IO DDR_CSR_APB_MC_BASE2_TypeDef MC_BASE2; /*!< Offset: 0x4000 */
+ __IO DDR_CSR_APB_MEM_TEST_TypeDef MEM_TEST; /*!< Offset: 0x4400 */
+ __I uint32_t UNUSED_SPACE4[350]; /*!< Offset: 0x4688 */
+ __IO DDR_CSR_APB_MPFE_TypeDef MPFE; /*!< Offset: 0x4c00 */
+ __I uint32_t UNUSED_SPACE5[215]; /*!< Offset: 0x4ca4 */
+ __IO DDR_CSR_APB_REORDER_TypeDef REORDER; /*!< Offset: 0x5000 */
+ __I uint32_t UNUSED_SPACE6[247]; /*!< Offset: 0x5024 */
+ __IO DDR_CSR_APB_RMW_TypeDef RMW; /*!< Offset: 0x5400 */
+ __I uint32_t UNUSED_SPACE7[254]; /*!< Offset: 0x5408 */
+ __IO DDR_CSR_APB_ECC_TypeDef ECC; /*!< Offset: 0x5800 */
+ __I uint32_t UNUSED_SPACE8[229]; /*!< Offset: 0x586c */
+ __IO DDR_CSR_APB_READ_CAPT_TypeDef READ_CAPT; /*!< Offset: 0x5c00 */
+ __I uint32_t UNUSED_SPACE9[494]; /*!< Offset: 0x5c48 */
+ __IO DDR_CSR_APB_MTA_TypeDef MTA; /*!< Offset: 0x6400 */
+ __I uint32_t UNUSED_SPACE10[1449]; /*!< Offset: 0x655c */
+ __IO DDR_CSR_APB_DYN_WIDTH_ADJ_TypeDef DYN_WIDTH_ADJ; /*!< Offset: 0x7c00 */
+ __I uint32_t UNUSED_SPACE11[254]; /*!< Offset: 0x7c08 */
+ __IO DDR_CSR_APB_CA_PAR_ERR_TypeDef CA_PAR_ERR; /*!< Offset: 0x8000 */
+ __I uint32_t UNUSED_SPACE12[8184]; /*!< Offset: 0x8020 */
+ __IO DDR_CSR_APB_DFI_TypeDef DFI; /*!< Offset: 0x10000 */
+ __I uint32_t UNUSED_SPACE13[2794]; /*!< Offset: 0x10058 */
+ __IO DDR_CSR_APB_AXI_IF_TypeDef AXI_IF; /*!< Offset: 0x12c00 */
+ __I uint32_t UNUSED_SPACE14[41563]; /*!< Offset: 0x13694 */
+ __IO DDR_CSR_APB_csr_custom_TypeDef csr_custom; /*!< Offset: 0x3c000 */
+} DDR_CSR_APB_TypeDef;
+
+
+/*============================== IOSCBCFG definitions ===========================*/
+
+typedef union{ /*!< CONTROL__1 register definition*/
+ __IO uint32_t CONTROL__1;
+ struct
+ {
+ __IO uint32_t INTEN_SCB :1;
+ __IO uint32_t INTEN_ERROR :1;
+ __IO uint32_t INTEN_TIMEOUT :1;
+ __IO uint32_t INTEN_BUSERR :1;
+ __I uint32_t Reserved :4;
+ __IO uint32_t RESET_CYCLE :1;
+ __I uint32_t Reserved1 :7;
+ __IO uint32_t SCBCLOCK_ON :1;
+ __I uint32_t Reserved2 :15;
+ } bitfield;
+} IOSCBCFG_CONTROL__1_TypeDef;
+
+typedef union{ /*!< STATUS register definition*/
+ __I uint32_t STATUS;
+ struct
+ {
+ __I uint32_t SCB_INTERRUPT :1;
+ __I uint32_t SCB_ERROR :1;
+ __I uint32_t TIMEOUT :1;
+ __I uint32_t SCB_BUSERR :1;
+ __I uint32_t Reserved :28;
+ } bitfield;
+} IOSCBCFG_STATUS_TypeDef;
+
+typedef union{ /*!< TIMER register definition*/
+ __IO uint32_t TIMER;
+ struct
+ {
+ __IO uint32_t TIMEOUT :8;
+ __IO uint32_t REQUEST_TIME :8;
+ __I uint32_t Reserved :16;
+ } bitfield;
+} IOSCBCFG_TIMER_TypeDef;
+
+/*------------ IOSCBCFG definition -----------*/
+typedef struct
+{
+ __IO IOSCBCFG_CONTROL__1_TypeDef CONTROL__1; /*!< Offset: 0x0 */
+ __I IOSCBCFG_STATUS_TypeDef STATUS; /*!< Offset: 0x4 */
+ __IO IOSCBCFG_TIMER_TypeDef TIMER; /*!< Offset: 0x8 */
+} IOSCBCFG_TypeDef;
+
+
+/*============================== g5_mss_top_scb_regs definitions ===========================*/
+
+typedef union{ /*!< SOFT_RESET register definition*/
+ __IO uint32_t SOFT_RESET;
+ struct
+ {
+ __O uint32_t NV_MAP :1;
+ __O uint32_t V_MAP :1;
+ __I uint32_t reserved_01 :6;
+ __O uint32_t PERIPH :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t BLOCKID :16;
+ } bitfield;
+} g5_mss_top_scb_regs_SOFT_RESET_TypeDef;
+
+typedef union{ /*!< AXI_WSETUP register definition*/
+ __IO uint32_t AXI_WSETUP;
+ struct
+ {
+ __IO uint32_t ADDR :6;
+ __IO uint32_t BURST :2;
+ __IO uint32_t LENGTH :8;
+ __IO uint32_t SIZE :3;
+ __IO uint32_t LOCK :1;
+ __IO uint32_t CACHE :4;
+ __IO uint32_t PROT :3;
+ __IO uint32_t QOS :4;
+ __IO uint32_t SYSTEM :1;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_WSETUP_TypeDef;
+
+typedef union{ /*!< AXI_WADDR register definition*/
+ __IO uint32_t AXI_WADDR;
+ struct
+ {
+ __IO uint32_t ADDR :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_WADDR_TypeDef;
+
+typedef union{ /*!< AXI_WDATA register definition*/
+ __IO uint32_t AXI_WDATA;
+ struct
+ {
+ __IO uint32_t DATA :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_WDATA_TypeDef;
+
+typedef union{ /*!< AXI_RSETUP register definition*/
+ __IO uint32_t AXI_RSETUP;
+ struct
+ {
+ __IO uint32_t ADDR :6;
+ __IO uint32_t BURST :2;
+ __IO uint32_t LENGTH :8;
+ __IO uint32_t SIZE :3;
+ __IO uint32_t LOCK :1;
+ __IO uint32_t CACHE :4;
+ __IO uint32_t PROT :3;
+ __IO uint32_t QOS :4;
+ __IO uint32_t SYSTEM :1;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_RSETUP_TypeDef;
+
+typedef union{ /*!< AXI_RADDR register definition*/
+ __IO uint32_t AXI_RADDR;
+ struct
+ {
+ __IO uint32_t ADDR :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_RADDR_TypeDef;
+
+typedef union{ /*!< AXI_RDATA register definition*/
+ __IO uint32_t AXI_RDATA;
+ struct
+ {
+ __IO uint32_t DATA :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_RDATA_TypeDef;
+
+typedef union{ /*!< AXI_STATUS register definition*/
+ __IO uint32_t AXI_STATUS;
+ struct
+ {
+ __IO uint32_t WRITE_BUSY :1;
+ __IO uint32_t READ_BUSY :1;
+ __IO uint32_t WRITE_ERROR :1;
+ __IO uint32_t READ_ERROR :1;
+ __IO uint32_t WRITE_COUNT :5;
+ __IO uint32_t READ_COUNT :5;
+ __IO uint32_t READ_OVERRUN :1;
+ __IO uint32_t WRITE_OVERRUN :1;
+ __IO uint32_t WRITE_RESPONSE :2;
+ __IO uint32_t READ_RESPONSE :2;
+ __IO uint32_t MSS_RESET :1;
+ __I uint32_t reserved_01 :3;
+ __IO uint32_t INT_ENABLE_READ_ORUN :1;
+ __IO uint32_t INT_ENABLE_WRITE_ORUN :1;
+ __IO uint32_t INT_ENABLE_RRESP :1;
+ __IO uint32_t INT_ENABLE_WRESP :1;
+ __IO uint32_t INT_ENABLE_SYSREG :1;
+ __I uint32_t reserved_02 :3;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_STATUS_TypeDef;
+
+typedef union{ /*!< AXI_CONTROL register definition*/
+ __IO uint32_t AXI_CONTROL;
+ struct
+ {
+ __IO uint32_t ABORT :1;
+ __I uint32_t reserved_01 :7;
+ __IO uint32_t STALL_WRITE :1;
+ __I uint32_t reserved_02 :7;
+ __IO uint32_t START_WRITE :1;
+ __I uint32_t reserved_03 :15;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_CONTROL_TypeDef;
+
+typedef union{ /*!< REDUNDANCY register definition*/
+ __IO uint32_t REDUNDANCY;
+ struct
+ {
+ __IO uint32_t RESET :1;
+ __IO uint32_t ISOLATE :1;
+ __IO uint32_t NOCLOCK :1;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} g5_mss_top_scb_regs_REDUNDANCY_TypeDef;
+
+typedef union{ /*!< BIST_CONFIG register definition*/
+ __IO uint32_t BIST_CONFIG;
+ struct
+ {
+ __I uint32_t enabled :1;
+ __IO uint32_t enable :1;
+ __IO uint32_t reset :1;
+ __IO uint32_t diag_select :1;
+ __I uint32_t reserved_01 :4;
+ __IO uint32_t select :5;
+ __I uint32_t reserved_02 :3;
+ __IO uint32_t margin :3;
+ __I uint32_t reserved_03 :13;
+ } bitfield;
+} g5_mss_top_scb_regs_BIST_CONFIG_TypeDef;
+
+typedef union{ /*!< BIST_DATA register definition*/
+ __IO uint32_t BIST_DATA;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BIST_DATA_TypeDef;
+
+typedef union{ /*!< BIST_COMMAND register definition*/
+ __IO uint32_t BIST_COMMAND;
+ struct
+ {
+ __IO uint32_t update :1;
+ __IO uint32_t capture :1;
+ __IO uint32_t shift :1;
+ __I uint32_t busy :1;
+ __I uint32_t reserved_01 :4;
+ __IO uint32_t length :7;
+ __I uint32_t reserved_02 :17;
+ } bitfield;
+} g5_mss_top_scb_regs_BIST_COMMAND_TypeDef;
+
+typedef union{ /*!< MSS_RESET_CR register definition*/
+ __IO uint32_t MSS_RESET_CR;
+ struct
+ {
+ __IO uint32_t CPU :1;
+ __IO uint32_t MSS :1;
+ __I uint32_t CPUINRESET :1;
+ __IO uint32_t REBOOT_REQUEST :1;
+ __I uint32_t reserved_01 :4;
+ __IO uint32_t SGMII :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t REASON :9;
+ __I uint32_t reserved_03 :7;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_RESET_CR_TypeDef;
+
+typedef union{ /*!< MSS_STATUS register definition*/
+ __IO uint32_t MSS_STATUS;
+ struct
+ {
+ __IO uint32_t boot_status :4;
+ __I uint32_t watchdog :5;
+ __I uint32_t debug_active :1;
+ __I uint32_t halt_cpu0 :1;
+ __I uint32_t halt_cpu1 :1;
+ __I uint32_t halt_cpu2 :1;
+ __I uint32_t halt_cpu3 :1;
+ __I uint32_t halt_cpu4 :1;
+ __I uint32_t ecc_error_l2 :1;
+ __I uint32_t ecc_error_other :1;
+ __I uint32_t reserved_01 :15;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_STATUS_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR0 register definition*/
+ __IO uint32_t BOOT_ADDR0;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR0_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR1 register definition*/
+ __IO uint32_t BOOT_ADDR1;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR1_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR2 register definition*/
+ __IO uint32_t BOOT_ADDR2;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR2_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR3 register definition*/
+ __IO uint32_t BOOT_ADDR3;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR3_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR4 register definition*/
+ __IO uint32_t BOOT_ADDR4;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR4_TypeDef;
+
+typedef union{ /*!< BOOT_ROM0 register definition*/
+ __IO uint32_t BOOT_ROM0;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM0_TypeDef;
+
+typedef union{ /*!< BOOT_ROM1 register definition*/
+ __IO uint32_t BOOT_ROM1;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM1_TypeDef;
+
+typedef union{ /*!< BOOT_ROM2 register definition*/
+ __IO uint32_t BOOT_ROM2;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM2_TypeDef;
+
+typedef union{ /*!< BOOT_ROM3 register definition*/
+ __IO uint32_t BOOT_ROM3;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM3_TypeDef;
+
+typedef union{ /*!< BOOT_ROM4 register definition*/
+ __IO uint32_t BOOT_ROM4;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM4_TypeDef;
+
+typedef union{ /*!< BOOT_ROM5 register definition*/
+ __IO uint32_t BOOT_ROM5;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM5_TypeDef;
+
+typedef union{ /*!< BOOT_ROM6 register definition*/
+ __IO uint32_t BOOT_ROM6;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM6_TypeDef;
+
+typedef union{ /*!< BOOT_ROM7 register definition*/
+ __IO uint32_t BOOT_ROM7;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM7_TypeDef;
+
+typedef union{ /*!< FLASH_FREEZE register definition*/
+ __IO uint32_t FLASH_FREEZE;
+ struct
+ {
+ __IO uint32_t in_progress :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_FLASH_FREEZE_TypeDef;
+
+typedef union{ /*!< G5CIO register definition*/
+ __IO uint32_t G5CIO;
+ struct
+ {
+ __IO uint32_t ioout :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_G5CIO_TypeDef;
+
+typedef union{ /*!< DEVICE_ID register definition*/
+ __IO uint32_t DEVICE_ID;
+ struct
+ {
+ __IO uint32_t idp :16;
+ __IO uint32_t idv :4;
+ __I uint32_t reserved_01 :12;
+ } bitfield;
+} g5_mss_top_scb_regs_DEVICE_ID_TypeDef;
+
+typedef union{ /*!< MESSAGE_INT register definition*/
+ __IO uint32_t MESSAGE_INT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_MESSAGE_INT_TypeDef;
+
+typedef union{ /*!< MESSAGE register definition*/
+ __IO uint32_t MESSAGE;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_MESSAGE_TypeDef;
+
+typedef union{ /*!< DEVRST_INT register definition*/
+ __IO uint32_t DEVRST_INT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_DEVRST_INT_TypeDef;
+
+typedef union{ /*!< SCB_INTERRUPT register definition*/
+ __IO uint32_t SCB_INTERRUPT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_SCB_INTERRUPT_TypeDef;
+
+typedef union{ /*!< MSS_INTERRUPT register definition*/
+ __IO uint32_t MSS_INTERRUPT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_INTERRUPT_TypeDef;
+
+typedef union{ /*!< DEVICE_CONFIG_CR register definition*/
+ __IO uint32_t DEVICE_CONFIG_CR;
+ struct
+ {
+ __IO uint32_t FACTORY_TEST_MODE :1;
+ __I uint32_t RESERVED :1;
+ __IO uint32_t CRYPTO_DISABLE :1;
+ __IO uint32_t CAN_ALLOWED :1;
+ __IO uint32_t CPU_ALLOWED :1;
+ __IO uint32_t CPU_DISABLE :1;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t CPU_BIST_DISABLE :1;
+ __I uint32_t reserved_02 :7;
+ __IO uint32_t DISABLE_XIP :1;
+ __I uint32_t reserved_03 :15;
+ } bitfield;
+} g5_mss_top_scb_regs_DEVICE_CONFIG_CR_TypeDef;
+
+typedef union{ /*!< ATHENA_CR register definition*/
+ __IO uint32_t ATHENA_CR;
+ struct
+ {
+ __IO uint32_t mss_mode :3;
+ __I uint32_t reserved_01 :1;
+ __IO uint32_t stream_enable :1;
+ __I uint32_t reserved_02 :27;
+ } bitfield;
+} g5_mss_top_scb_regs_ATHENA_CR_TypeDef;
+
+typedef union{ /*!< ENVM_CR register definition*/
+ __IO uint32_t ENVM_CR;
+ struct
+ {
+ __IO uint32_t clock_period :6;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t clock_continuous :1;
+ __IO uint32_t clock_suppress :1;
+ __I uint32_t reserved_02 :6;
+ __IO uint32_t readahead :1;
+ __IO uint32_t slowread :1;
+ __IO uint32_t interrupt_enable :1;
+ __I uint32_t reserved_03 :5;
+ __IO uint32_t timer :8;
+ } bitfield;
+} g5_mss_top_scb_regs_ENVM_CR_TypeDef;
+
+typedef union{ /*!< ENVM_POWER_CR register definition*/
+ __IO uint32_t ENVM_POWER_CR;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t pd1 :1;
+ __IO uint32_t pd2 :1;
+ __IO uint32_t pd3 :1;
+ __IO uint32_t pd4 :1;
+ __IO uint32_t iso :1;
+ __IO uint32_t sleep :1;
+ __I uint32_t reserved_01 :1;
+ __IO uint32_t override :1;
+ __I uint32_t reserved_02 :23;
+ } bitfield;
+} g5_mss_top_scb_regs_ENVM_POWER_CR_TypeDef;
+
+typedef union{ /*!< RAM_SHUTDOWN_CR register definition*/
+ __IO uint32_t RAM_SHUTDOWN_CR;
+ struct
+ {
+ __IO uint32_t can0 :1;
+ __IO uint32_t can1 :1;
+ __IO uint32_t usb :1;
+ __IO uint32_t gem0 :1;
+ __IO uint32_t gem1 :1;
+ __IO uint32_t mmc :1;
+ __IO uint32_t athena :1;
+ __IO uint32_t ddrc :1;
+ __IO uint32_t e51 :1;
+ __IO uint32_t u54_1 :1;
+ __IO uint32_t u54_2 :1;
+ __IO uint32_t u54_3 :1;
+ __IO uint32_t u54_4 :1;
+ __IO uint32_t l2 :1;
+ __I uint32_t reserved_01 :18;
+ } bitfield;
+} g5_mss_top_scb_regs_RAM_SHUTDOWN_CR_TypeDef;
+
+typedef union{ /*!< RAM_MARGIN_CR register definition*/
+ __IO uint32_t RAM_MARGIN_CR;
+ struct
+ {
+ __IO uint32_t enable :1;
+ __IO uint32_t can0 :2;
+ __IO uint32_t can1 :2;
+ __IO uint32_t usb :2;
+ __IO uint32_t gem0 :2;
+ __IO uint32_t gem1 :2;
+ __IO uint32_t mmc :2;
+ __IO uint32_t ddrc :2;
+ __IO uint32_t e51 :2;
+ __IO uint32_t u54_1 :2;
+ __IO uint32_t u54_2 :2;
+ __IO uint32_t u54_3 :2;
+ __IO uint32_t u54_4 :2;
+ __IO uint32_t l2 :2;
+ __I uint32_t reserved_01 :5;
+ } bitfield;
+} g5_mss_top_scb_regs_RAM_MARGIN_CR_TypeDef;
+
+typedef union{ /*!< TRACE_CR register definition*/
+ __IO uint32_t TRACE_CR;
+ struct
+ {
+ __IO uint32_t CPU_DEBUG_DISABLE :1;
+ __IO uint32_t ULTRASOC_DISABLE_JTAG :1;
+ __IO uint32_t ULTRASOC_DISABLE_AXI :1;
+ __I uint32_t reserved_01 :5;
+ __IO uint32_t ULTRASOC_FABRIC :1;
+ __I uint32_t reserved_02 :23;
+ } bitfield;
+} g5_mss_top_scb_regs_TRACE_CR_TypeDef;
+
+typedef union{ /*!< MSSIO_CONTROL_CR register definition*/
+ __IO uint32_t MSSIO_CONTROL_CR;
+ struct
+ {
+ __IO uint32_t lp_state_mss :1;
+ __IO uint32_t lp_state_ip_mss :1;
+ __IO uint32_t lp_state_op_mss :1;
+ __IO uint32_t lp_state_persist_mss :1;
+ __IO uint32_t lp_state_bypass_mss :1;
+ __IO uint32_t lp_pll_locked_mss :1;
+ __IO uint32_t lp_stop_clocks_out_mss :1;
+ __I uint32_t lp_stop_clocks_done_mss :1;
+ __IO uint32_t mss_dce :3;
+ __IO uint32_t mss_core_up :1;
+ __IO uint32_t mss_flash_valid :1;
+ __IO uint32_t mss_io_en :1;
+ __IO uint32_t mss_sel_hw_dyn :1;
+ __IO uint32_t mss_sel_hw_def :1;
+ __I uint32_t reserved_01 :16;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_CONTROL_CR_TypeDef;
+
+typedef union{ /*!< MSS_IO_LOCKDOWN_CR register definition*/
+ __I uint32_t MSS_IO_LOCKDOWN_CR;
+ struct
+ {
+ __I uint32_t mssio_b2_lockdn_en :1;
+ __I uint32_t mssio_b4_lockdn_en :1;
+ __I uint32_t sgmii_io_lockdn_en :1;
+ __I uint32_t ddr_io_lockdn_en :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_IO_LOCKDOWN_CR_TypeDef;
+
+typedef union{ /*!< MSSIO_BANK2_CFG_CR register definition*/
+ __IO uint32_t MSSIO_BANK2_CFG_CR;
+ struct
+ {
+ __IO uint32_t bank_pcode :6;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t bank_ncode :6;
+ __I uint32_t reserved_02 :2;
+ __IO uint32_t vs :4;
+ __I uint32_t reserved_03 :12;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_BANK2_CFG_CR_TypeDef;
+
+typedef union{ /*!< MSSIO_BANK4_CFG_CR register definition*/
+ __IO uint32_t MSSIO_BANK4_CFG_CR;
+ struct
+ {
+ __IO uint32_t bank_pcode :6;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t bank_ncode :6;
+ __I uint32_t reserved_02 :2;
+ __IO uint32_t vs :4;
+ __I uint32_t reserved_03 :12;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_BANK4_CFG_CR_TypeDef;
+
+typedef union{ /*!< DLL0_CTRL0 register definition*/
+ __IO uint32_t DLL0_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL0_CTRL1 register definition*/
+ __IO uint32_t DLL0_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL0_STAT0 register definition*/
+ __IO uint32_t DLL0_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_STAT0_TypeDef;
+
+typedef union{ /*!< DLL0_STAT1 register definition*/
+ __I uint32_t DLL0_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_STAT1_TypeDef;
+
+typedef union{ /*!< DLL0_STAT2 register definition*/
+ __I uint32_t DLL0_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_STAT2_TypeDef;
+
+typedef union{ /*!< DLL0_TEST register definition*/
+ __IO uint32_t DLL0_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_TEST_TypeDef;
+
+typedef union{ /*!< DLL1_CTRL0 register definition*/
+ __IO uint32_t DLL1_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL1_CTRL1 register definition*/
+ __IO uint32_t DLL1_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL1_STAT0 register definition*/
+ __IO uint32_t DLL1_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_STAT0_TypeDef;
+
+typedef union{ /*!< DLL1_STAT1 register definition*/
+ __I uint32_t DLL1_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_STAT1_TypeDef;
+
+typedef union{ /*!< DLL1_STAT2 register definition*/
+ __I uint32_t DLL1_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_STAT2_TypeDef;
+
+typedef union{ /*!< DLL1_TEST register definition*/
+ __IO uint32_t DLL1_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_TEST_TypeDef;
+
+typedef union{ /*!< DLL2_CTRL0 register definition*/
+ __IO uint32_t DLL2_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL2_CTRL1 register definition*/
+ __IO uint32_t DLL2_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL2_STAT0 register definition*/
+ __IO uint32_t DLL2_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_STAT0_TypeDef;
+
+typedef union{ /*!< DLL2_STAT1 register definition*/
+ __I uint32_t DLL2_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_STAT1_TypeDef;
+
+typedef union{ /*!< DLL2_STAT2 register definition*/
+ __I uint32_t DLL2_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_STAT2_TypeDef;
+
+typedef union{ /*!< DLL2_TEST register definition*/
+ __IO uint32_t DLL2_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_TEST_TypeDef;
+
+typedef union{ /*!< DLL3_CTRL0 register definition*/
+ __IO uint32_t DLL3_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL3_CTRL1 register definition*/
+ __IO uint32_t DLL3_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL3_STAT0 register definition*/
+ __IO uint32_t DLL3_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_STAT0_TypeDef;
+
+typedef union{ /*!< DLL3_STAT1 register definition*/
+ __I uint32_t DLL3_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_STAT1_TypeDef;
+
+typedef union{ /*!< DLL3_STAT2 register definition*/
+ __I uint32_t DLL3_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_STAT2_TypeDef;
+
+typedef union{ /*!< DLL3_TEST register definition*/
+ __IO uint32_t DLL3_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_TEST_TypeDef;
+
+typedef union{ /*!< MSSIO_VB2_CFG register definition*/
+ __IO uint32_t MSSIO_VB2_CFG;
+ struct
+ {
+ __IO uint32_t dpc_io_cfg_ibufmd_0 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_1 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_0 :1;
+ __IO uint32_t dpc_io_cfg_drv_1 :1;
+ __IO uint32_t dpc_io_cfg_drv_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_3 :1;
+ __IO uint32_t dpc_io_cfg_clamp :1;
+ __IO uint32_t dpc_io_cfg_enhyst :1;
+ __IO uint32_t dpc_io_cfg_lockdn_en :1;
+ __IO uint32_t dpc_io_cfg_wpd :1;
+ __IO uint32_t dpc_io_cfg_wpu :1;
+ __IO uint32_t dpc_io_cfg_atp_en :1;
+ __IO uint32_t dpc_io_cfg_lp_persist_en :1;
+ __IO uint32_t dpc_io_cfg_lp_bypass_en :1;
+ __I uint32_t reserved_01 :17;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_VB2_CFG_TypeDef;
+
+typedef union{ /*!< MSSIO_VB4_CFG register definition*/
+ __IO uint32_t MSSIO_VB4_CFG;
+ struct
+ {
+ __IO uint32_t dpc_io_cfg_ibufmd_0 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_1 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_0 :1;
+ __IO uint32_t dpc_io_cfg_drv_1 :1;
+ __IO uint32_t dpc_io_cfg_drv_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_3 :1;
+ __IO uint32_t dpc_io_cfg_clamp :1;
+ __IO uint32_t dpc_io_cfg_enhyst :1;
+ __IO uint32_t dpc_io_cfg_lockdn_en :1;
+ __IO uint32_t dpc_io_cfg_wpd :1;
+ __IO uint32_t dpc_io_cfg_wpu :1;
+ __IO uint32_t dpc_io_cfg_atp_en :1;
+ __IO uint32_t dpc_io_cfg_lp_persist_en :1;
+ __IO uint32_t dpc_io_cfg_lp_bypass_en :1;
+ __I uint32_t reserved_01 :17;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_VB4_CFG_TypeDef;
+
+/*------------ g5_mss_top_scb_regs definition -----------*/
+typedef struct
+{
+ __IO g5_mss_top_scb_regs_SOFT_RESET_TypeDef SOFT_RESET; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0[3]; /*!< Offset: 0x4 */
+ __IO g5_mss_top_scb_regs_AXI_WSETUP_TypeDef AXI_WSETUP; /*!< Offset: 0x10 */
+ __IO g5_mss_top_scb_regs_AXI_WADDR_TypeDef AXI_WADDR; /*!< Offset: 0x14 */
+ __IO g5_mss_top_scb_regs_AXI_WDATA_TypeDef AXI_WDATA; /*!< Offset: 0x18 */
+ __IO g5_mss_top_scb_regs_AXI_RSETUP_TypeDef AXI_RSETUP; /*!< Offset: 0x1c */
+ __IO g5_mss_top_scb_regs_AXI_RADDR_TypeDef AXI_RADDR; /*!< Offset: 0x20 */
+ __IO g5_mss_top_scb_regs_AXI_RDATA_TypeDef AXI_RDATA; /*!< Offset: 0x24 */
+ __IO g5_mss_top_scb_regs_AXI_STATUS_TypeDef AXI_STATUS; /*!< Offset: 0x28 */
+ __IO g5_mss_top_scb_regs_AXI_CONTROL_TypeDef AXI_CONTROL; /*!< Offset: 0x2c */
+ __IO g5_mss_top_scb_regs_REDUNDANCY_TypeDef REDUNDANCY; /*!< Offset: 0x30 */
+ __I uint32_t UNUSED_SPACE1[7]; /*!< Offset: 0x34 */
+ __IO g5_mss_top_scb_regs_BIST_CONFIG_TypeDef BIST_CONFIG; /*!< Offset: 0x50 */
+ __IO g5_mss_top_scb_regs_BIST_DATA_TypeDef BIST_DATA; /*!< Offset: 0x54 */
+ __IO g5_mss_top_scb_regs_BIST_COMMAND_TypeDef BIST_COMMAND; /*!< Offset: 0x58 */
+ __I uint32_t UNUSED_SPACE2[41]; /*!< Offset: 0x5c */
+ __IO g5_mss_top_scb_regs_MSS_RESET_CR_TypeDef MSS_RESET_CR; /*!< Offset: 0x100 */
+ __IO g5_mss_top_scb_regs_MSS_STATUS_TypeDef MSS_STATUS; /*!< Offset: 0x104 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR0_TypeDef BOOT_ADDR0; /*!< Offset: 0x108 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR1_TypeDef BOOT_ADDR1; /*!< Offset: 0x10c */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR2_TypeDef BOOT_ADDR2; /*!< Offset: 0x110 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR3_TypeDef BOOT_ADDR3; /*!< Offset: 0x114 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR4_TypeDef BOOT_ADDR4; /*!< Offset: 0x118 */
+ __I uint32_t UNUSED_SPACE3; /*!< Offset: 0x11c */
+ __IO g5_mss_top_scb_regs_BOOT_ROM0_TypeDef BOOT_ROM0; /*!< Offset: 0x120 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM1_TypeDef BOOT_ROM1; /*!< Offset: 0x124 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM2_TypeDef BOOT_ROM2; /*!< Offset: 0x128 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM3_TypeDef BOOT_ROM3; /*!< Offset: 0x12c */
+ __IO g5_mss_top_scb_regs_BOOT_ROM4_TypeDef BOOT_ROM4; /*!< Offset: 0x130 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM5_TypeDef BOOT_ROM5; /*!< Offset: 0x134 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM6_TypeDef BOOT_ROM6; /*!< Offset: 0x138 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM7_TypeDef BOOT_ROM7; /*!< Offset: 0x13c */
+ __I uint32_t UNUSED_SPACE4[16]; /*!< Offset: 0x140 */
+ __IO g5_mss_top_scb_regs_FLASH_FREEZE_TypeDef FLASH_FREEZE; /*!< Offset: 0x180 */
+ __IO g5_mss_top_scb_regs_G5CIO_TypeDef G5CIO; /*!< Offset: 0x184 */
+ __IO g5_mss_top_scb_regs_DEVICE_ID_TypeDef DEVICE_ID; /*!< Offset: 0x188 */
+ __IO g5_mss_top_scb_regs_MESSAGE_INT_TypeDef MESSAGE_INT; /*!< Offset: 0x18c */
+ __IO g5_mss_top_scb_regs_MESSAGE_TypeDef MESSAGE; /*!< Offset: 0x190 */
+ __IO g5_mss_top_scb_regs_DEVRST_INT_TypeDef DEVRST_INT; /*!< Offset: 0x194 */
+ __IO g5_mss_top_scb_regs_SCB_INTERRUPT_TypeDef SCB_INTERRUPT; /*!< Offset: 0x198 */
+ __IO g5_mss_top_scb_regs_MSS_INTERRUPT_TypeDef MSS_INTERRUPT; /*!< Offset: 0x19c */
+ __IO g5_mss_top_scb_regs_DEVICE_CONFIG_CR_TypeDef DEVICE_CONFIG_CR; /*!< Offset: 0x1a0 */
+ __IO g5_mss_top_scb_regs_ATHENA_CR_TypeDef ATHENA_CR; /*!< Offset: 0x1a4 */
+ __IO g5_mss_top_scb_regs_ENVM_CR_TypeDef ENVM_CR; /*!< Offset: 0x1a8 */
+ __IO g5_mss_top_scb_regs_ENVM_POWER_CR_TypeDef ENVM_POWER_CR; /*!< Offset: 0x1ac */
+ __IO g5_mss_top_scb_regs_RAM_SHUTDOWN_CR_TypeDef RAM_SHUTDOWN_CR; /*!< Offset: 0x1b0 */
+ __IO g5_mss_top_scb_regs_RAM_MARGIN_CR_TypeDef RAM_MARGIN_CR; /*!< Offset: 0x1b4 */
+ __IO g5_mss_top_scb_regs_TRACE_CR_TypeDef TRACE_CR; /*!< Offset: 0x1b8 */
+ __IO g5_mss_top_scb_regs_MSSIO_CONTROL_CR_TypeDef MSSIO_CONTROL_CR; /*!< Offset: 0x1bc */
+ __I g5_mss_top_scb_regs_MSS_IO_LOCKDOWN_CR_TypeDef MSS_IO_LOCKDOWN_CR; /*!< Offset: 0x1c0 */
+ __IO g5_mss_top_scb_regs_MSSIO_BANK2_CFG_CR_TypeDef MSSIO_BANK2_CFG_CR; /*!< Offset: 0x1c4 */
+ __IO g5_mss_top_scb_regs_MSSIO_BANK4_CFG_CR_TypeDef MSSIO_BANK4_CFG_CR; /*!< Offset: 0x1c8 */
+ __I uint32_t UNUSED_SPACE5[13]; /*!< Offset: 0x1cc */
+ __IO g5_mss_top_scb_regs_DLL0_CTRL0_TypeDef DLL0_CTRL0; /*!< Offset: 0x200 */
+ __IO g5_mss_top_scb_regs_DLL0_CTRL1_TypeDef DLL0_CTRL1; /*!< Offset: 0x204 */
+ __IO g5_mss_top_scb_regs_DLL0_STAT0_TypeDef DLL0_STAT0; /*!< Offset: 0x208 */
+ __I g5_mss_top_scb_regs_DLL0_STAT1_TypeDef DLL0_STAT1; /*!< Offset: 0x20c */
+ __I g5_mss_top_scb_regs_DLL0_STAT2_TypeDef DLL0_STAT2; /*!< Offset: 0x210 */
+ __IO g5_mss_top_scb_regs_DLL0_TEST_TypeDef DLL0_TEST; /*!< Offset: 0x214 */
+ __I uint32_t UNUSED_SPACE6[2]; /*!< Offset: 0x218 */
+ __IO g5_mss_top_scb_regs_DLL1_CTRL0_TypeDef DLL1_CTRL0; /*!< Offset: 0x220 */
+ __IO g5_mss_top_scb_regs_DLL1_CTRL1_TypeDef DLL1_CTRL1; /*!< Offset: 0x224 */
+ __IO g5_mss_top_scb_regs_DLL1_STAT0_TypeDef DLL1_STAT0; /*!< Offset: 0x228 */
+ __I g5_mss_top_scb_regs_DLL1_STAT1_TypeDef DLL1_STAT1; /*!< Offset: 0x22c */
+ __I g5_mss_top_scb_regs_DLL1_STAT2_TypeDef DLL1_STAT2; /*!< Offset: 0x230 */
+ __IO g5_mss_top_scb_regs_DLL1_TEST_TypeDef DLL1_TEST; /*!< Offset: 0x234 */
+ __I uint32_t UNUSED_SPACE7[2]; /*!< Offset: 0x238 */
+ __IO g5_mss_top_scb_regs_DLL2_CTRL0_TypeDef DLL2_CTRL0; /*!< Offset: 0x240 */
+ __IO g5_mss_top_scb_regs_DLL2_CTRL1_TypeDef DLL2_CTRL1; /*!< Offset: 0x244 */
+ __IO g5_mss_top_scb_regs_DLL2_STAT0_TypeDef DLL2_STAT0; /*!< Offset: 0x248 */
+ __I g5_mss_top_scb_regs_DLL2_STAT1_TypeDef DLL2_STAT1; /*!< Offset: 0x24c */
+ __I g5_mss_top_scb_regs_DLL2_STAT2_TypeDef DLL2_STAT2; /*!< Offset: 0x250 */
+ __IO g5_mss_top_scb_regs_DLL2_TEST_TypeDef DLL2_TEST; /*!< Offset: 0x254 */
+ __I uint32_t UNUSED_SPACE8[2]; /*!< Offset: 0x258 */
+ __IO g5_mss_top_scb_regs_DLL3_CTRL0_TypeDef DLL3_CTRL0; /*!< Offset: 0x260 */
+ __IO g5_mss_top_scb_regs_DLL3_CTRL1_TypeDef DLL3_CTRL1; /*!< Offset: 0x264 */
+ __IO g5_mss_top_scb_regs_DLL3_STAT0_TypeDef DLL3_STAT0; /*!< Offset: 0x268 */
+ __I g5_mss_top_scb_regs_DLL3_STAT1_TypeDef DLL3_STAT1; /*!< Offset: 0x26c */
+ __I g5_mss_top_scb_regs_DLL3_STAT2_TypeDef DLL3_STAT2; /*!< Offset: 0x270 */
+ __IO g5_mss_top_scb_regs_DLL3_TEST_TypeDef DLL3_TEST; /*!< Offset: 0x274 */
+ __IO g5_mss_top_scb_regs_MSSIO_VB2_CFG_TypeDef MSSIO_VB2_CFG; /*!< Offset: 0x278 */
+ __IO g5_mss_top_scb_regs_MSSIO_VB4_CFG_TypeDef MSSIO_VB4_CFG; /*!< Offset: 0x27c */
+} g5_mss_top_scb_regs_TypeDef;
+
+
+#define CFG_DDR_SGMII_PHY_BASE (0x20007000) /*!< ( CFG_DDR_SGMII_PHY ) Base Address */
+#define DDRCFG_BASE (0x20080000) /*!< ( DDRCFG ) Base Address */
+
+#define SYSREGSCB_BASE (0x20003000) /*!< ( SYSREGSCB ) Base Address */
+#define IOSCBCFG_BASE (0x37080000) /*!< ( IOSCBCFG ) Base Address */
+
+extern CFG_DDR_SGMII_PHY_TypeDef * const CFG_DDR_SGMII_PHY ;
+extern DDR_CSR_APB_TypeDef * const DDRCFG ;
+extern IOSCBCFG_TypeDef * const SCBCFG_REGS ;
+extern g5_mss_top_scb_regs_TypeDef * const SCB_REGS ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_REGS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_test_pattern.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_test_pattern.c
new file mode 100644
index 00000000..c125b72f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_ddr_test_pattern.c
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+#include
+
+const uint32_t ddr_test_pattern[768] =
+{
+ 0x48b301bc, 0x79330115, 0xf5330139, 0x693301bc,
+ 0x893b00a9, 0x093b0128, 0x0d3b00c9, 0x551b00cd,
+ 0x161b0077, 0x8d510197, 0x0127581b, 0x00e7161b,
+ 0x01066633, 0x561b8d31, 0x8d310037, 0x8f3b9da9,
+ 0xd61b01e5, 0x959b0112, 0xd51b00f2, 0x8e4d0132,
+ 0x00d2959b, 0x8e2d8dc9, 0x00a2d29b, 0x005642b3,
+ 0xa4507637, 0x005f0f3b, 0x00dac5b3, 0xceb6061b,
+ 0x00cf063b, 0x01a5f5b3, 0x0155c5b3, 0x01460a3b,
+ 0x00ba0a3b, 0x01ad161b, 0x006d559b, 0x015d151b,
+ 0x561b8dd1, 0x8e4900bd, 0x551b8db1, 0x161b019d,
+ 0x8e49007d, 0x05bb8db1, 0x161b00ba, 0x5a1b01e9,
+ 0x151b0029, 0x6a330139, 0x561b00ca, 0x8e4900d9,
+ 0x00ca4a33, 0x0169551b, 0x00a9161b, 0x4a338e49,
+ 0xe63300ca, 0xf533012d, 0x7633012d, 0x8e490196,
+ 0x00ca0a3b, 0x0077d51b, 0x0197961b, 0x00ba0a3b,
+ 0x00b989bb, 0x959b8d51, 0xd61b00e7, 0x8e4d0127,
+ 0xd59b8e29, 0x8e2d0037, 0xbef9a5b7, 0x3f75859b,
+ 0x9f319f2d, 0x01770bbb, 0x011fd61b, 0x00ff971b,
+ 0x013fd59b, 0x961b8f51, 0x8e4d00df, 0xdf9b8f31,
+ 0x4fb300af, 0xc73301f7, 0x8fbb01a6, 0x773301fb,
+ 0x8f350137, 0x015f8abb, 0x00ea8abb, 0x01a9961b,
+ 0x0069d71b, 0x0159959b, 0xd61b8f51, 0x8e4d00b9,
+ 0xd59b8f31, 0x961b0199, 0x8e4d0079, 0x873b8f31,
+ 0x161b00ea, 0x5a9b01ea, 0x159b002a, 0xeab3013a,
+ 0x561b00ca, 0x8e4d00da, 0x00cacab3, 0x016a559b,
+ 0x00aa161b, 0xcab38e4d, 0x663300ca, 0x75b30149,
+ 0x76330149, 0x8e4d01b6, 0x00ca8abb, 0x00ea8abb,
+ 0x00ec8cbb, 0x019b161b, 0x007b571b, 0x559b8f51,
+ 0x161b012b, 0x8e4d00eb, 0x5b1b8f31, 0x4b33003b,
+ 0x87370167, 0x071bc671, 0x9fb98f27, 0x016787bb,
+ 0x171b9cbd, 0x579b00ff, 0x561b011f, 0x8f5d013f,
+ 0x00df179b, 0x8f3d8fd1, 0x00af5f1b, 0x01e74f33,
+ 0x013d4733, 0x01e48f3b, 0x01977733, 0x01a74733,
+ 0x00df06bb, 0xd79b9eb9, 0x971b006c, 0x961b01ac,
+ 0x8fd9015c, 0x00bcd71b, 0x8fb98f51, 0x019cd61b,
+ 0x007c971b, 0x8fb98f51, 0x971b9ebd, 0xd79b01ea,
+ 0x961b002a, 0x8fd9013a, 0x00dad71b, 0x8fb98f51,
+ 0x016ad61b, 0x00aa971b, 0x8fb98f51, 0x015a6733,
+ 0x015a7633, 0x01277733, 0x9fb98f51, 0x9fb96722,
+ 0x9fb56702, 0x67e2c71c, 0x01578abb, 0x262377c2,
+ 0x8a3b0157, 0x77e20147, 0x01472823, 0x0127893b,
+ 0x2a2367c2, 0x8dbb0127, 0x778201b7, 0x00dd86bb,
+ 0x8cbbcf14, 0x77a20197, 0x01972e23, 0x013789bb,
+ 0x20236786, 0x8d3b0337, 0x222301a7, 0x742a03a7,
+ 0x696a748a, 0x6a2a69ca, 0x7b666a8a, 0x7c267bc6,
+ 0x6d667c86, 0x614d6dc6, 0xe7b78082, 0x87936a09,
+ 0xc51c6677, 0xbb67b7b7, 0xe8578793, 0xf7b7c55c,
+ 0x87933c6e, 0xc91c3727, 0xa54ff7b7, 0x53a78793,
+ 0x57b7c95c, 0x8793510e, 0xcd1c27f7, 0x9b0577b7,
+ 0x88c78793, 0xe7b7cd5c, 0x87931f83, 0xd11c9ab7,
+ 0x5be0d7b7, 0xd1978793, 0x00052023, 0x00052223,
+ 0x8082d15c, 0x7139ce79, 0xf426f822, 0xe852f04a,
+ 0xec4efc06, 0xe05ae456, 0x84aa411c, 0x073b892e,
+ 0xc11800f6, 0xfa138432, 0x756303f7, 0x415c00c7,
+ 0xc15c2785, 0x020a0f63, 0x04000993, 0x414989bb,
+ 0x0009879b, 0x02f46763, 0x8a931982, 0xd9930284,
+ 0x85ca0209, 0x8533864e, 0x50ef014a, 0x043b4b00,
+ 0x85d60144, 0xc0ef8526, 0x041bf7cf, 0x994efc04,
+ 0x89ca4a01, 0x00890b3b, 0x03f00a93, 0x85cea039,
+ 0xc0ef8526, 0x8993f60f, 0x07bb0409, 0xe8e3413b,
+ 0x579bfefa, 0x06130064, 0x063bfc00, 0x559b02f6,
+ 0x059a0064, 0x9e2195ca, 0x0006079b, 0x7442c38d,
+ 0x02848513, 0x74a270e2, 0x69e27902, 0x6b026aa2,
+ 0x6a429552, 0x92011602, 0x506f6121, 0x70e24400,
+ 0x74a27442, 0x69e27902, 0x6aa26a42, 0x61216b02,
+ 0x80828082, 0xf0227179, 0xf406ec26, 0x41544110,
+ 0x579b84ae, 0x969b01d6, 0x8fd50036, 0x0186d59b,
+ 0x0106d69b, 0x00d104a3, 0x0087d693, 0x0ff6f693,
+ 0x171b07a2, 0x8fd50036, 0x00f11523, 0x0187579b,
+ 0x00f10623, 0x0107579b, 0x06a38321, 0x771300f1,
+ 0x17930ff7, 0x8f5d00b6, 0x00b10423, 0x00e11723,
+ 0x03f67613, 0x03700793, 0xe763842a, 0x079312c7,
+ 0x863b0380, 0x852240c7, 0x00025597, 0x19858593,
+ 0xea5ff0ef, 0x8522002c, 0xf0ef4621, 0x4783e9bf,
+ 0x802300b4, 0x578300f4, 0x80a300a4, 0x441c00f4,
+ 0x0087d79b, 0x00f48123, 0x81a3441c, 0x478300f4,
+ 0x822300f4, 0x578300f4, 0x82a300e4, 0x445c00f4,
+ 0x0087d79b, 0x00f48323, 0x83a3445c, 0x478300f4,
+ 0x84230134, 0x578300f4, 0x84a30124, 0x481c00f4,
+ 0x0087d79b, 0x00f48523, 0x85a3481c, 0x478300f4,
+ 0xb303679c, 0x04e30407, 0x8522fe03, 0x60a26402,
+ 0x83020141, 0xe0221141, 0x7d1ce406, 0xef89842a,
+ 0x4501643c, 0xb303679c, 0x0d630287, 0x85220003,
+ 0x60a26402, 0x83020141, 0x679c67bc, 0xd3ed67bc,
+ 0xdd799782, 0x640260a2, 0x80820141, 0x679c653c,
+ 0x0307b303, 0x00030363, 0x45018302, 0x711d8082,
+ 0x102cf42e, 0xf832ec06, 0xe0bafc36, 0xe8c2e4be,
+ 0xe42eecc6, 0x261240ef, 0x612560e2, 0x11418082,
+ 0xe406e022, 0x842a611c, 0xc7914fbc, 0x70ef6128,
+ 0x30239d6f, 0x643c0404, 0x53fc679c, 0x6828c791,
+ 0x9c4f70ef, 0x04043823, 0xcf897c1c, 0x53386398,
+ 0x67bce709, 0x57fc679c, 0x6c28c791, 0x9a8f70ef,
+ 0x04043c23, 0x09042783, 0x177d777d, 0x60a28ff9,
+ 0x08f42823, 0x01416402, 0x71798082, 0xf406f022,
+ 0xe84aec26, 0xe052e44e, 0xc9795429, 0x09052783,
+ 0x440184aa, 0xc7e98b85, 0x00053983, 0xf0ef892e,
+ 0x842af4ff, 0x864aed55, 0x85264581, 0x0c6000ef,
+ 0xed0d842a, 0x0289b703, 0x00197a13, 0xa783cb29,
+ 0x77b30709, 0xf79300f9, 0xe7b36007, 0xc3a10147,
+ 0x97028526, 0x6490cd0d, 0x00029597, 0x43058593,
+ 0x0002c517, 0xb7850513, 0xf17ff0ef, 0xf0ef8526,
+ 0x842aec7f, 0x6490c535, 0x00029597, 0x41058593,
+ 0x0002c517, 0xbc850513, 0xef7ff0ef, 0x7c9ca891,
+ 0x639cc39d, 0xc3856bbc, 0x97828526, 0xcd01842a,
+ 0x95976490, 0x85930002, 0xc5173e65, 0x05130002,
+ 0xf0efb6e5, 0xa583ecdf, 0x79330709, 0x791300b9,
+ 0x69336009, 0x0d630149, 0x85260009, 0xed3ff0ef,
+ 0xac2357fd, 0xa78308f4, 0x9bf90904, 0x08f4a823,
+ 0x852270a2, 0x64e27402, 0x69a26942, 0x61456a02,
+ 0x71798082, 0xe84af022, 0xf406e44e, 0x7938ec26,
+ 0x892e87aa, 0x89b26304, 0xf8070513, 0xf8048493,
+ 0x07078413, 0x08050793, 0x00879463, 0xa8394501,
+ 0x00090a63, 0x8763611c, 0x60dc0127, 0x84938526,
+ 0xb7cdf807, 0xf0ef85ce, 0xd965ec5f, 0x740270a2,
+ 0x694264e2, 0x614569a2, 0x11018082, 0xec06e822,
+ 0x7508842a, 0x860a468d, 0x0002f597, 0x73858593,
+ 0x488000ef, 0x8522e911, 0x800ff0ef, 0xc11c4782,
+ 0xc51c4792, 0xc15c47a2, 0xf0ef8522, 0x60e2eb2f,
+ 0x61056442, 0x715d8082, 0xf84ae0a2, 0xe486f44e,
+ 0xf052fc26, 0xe85aec56, 0x653ce45e, 0x458189ae,
+ 0x842a679c, 0x63848932, 0x867ff0ef, 0x09042783,
+ 0x0693862a, 0x8b850200, 0x0693c399, 0x601c02b0,
+ 0x451785a6, 0x05130003, 0x63980265, 0x4a1784ce,
+ 0x0a130003, 0x40ef05aa, 0x4a977e02, 0x8a930003,
+ 0x4b17046a, 0x0b130003, 0x4b97036b, 0x8b930003,
+ 0xd063026b, 0x640c0404, 0x0002d517, 0xe6850513,
+ 0x0019191b, 0x7b2240ef, 0x29857824, 0x07040413,
+ 0xf8048493, 0x08048793, 0x02f41c63, 0x640660a6,
+ 0x85a64601, 0xb0ef8522, 0x86aa54f1, 0x85d2864e,
+ 0xa0ef855a, 0x8b9b4852, 0x86520019, 0x852285a6,
+ 0xa95ff0ef, 0x85a689de, 0x8522864a, 0x7601b0ef,
+ 0xbb7d84aa, 0x854e75a2, 0x45f2a0ef, 0x85d2bd69,
+ 0xa0ef854e, 0xb5e14552, 0x651785ee, 0x05130003,
+ 0x83635765, 0x855a000a, 0x43f2a0ef, 0x854e85d2,
+ 0x4372a0ef, 0xb7192a85, 0x856685ee, 0x000a8363,
+ 0xa0ef855a, 0x85d24252, 0xa0ef854e, 0x2a8541d2,
+ 0x9863bf25, 0x86560147, 0xe42e8522, 0x99fff0ef,
+ 0x865e65a2, 0xb0ef8522, 0x85aa6f61, 0x4158b799,
+ 0x00ff0637, 0x0187569b, 0x0187179b, 0x169b8fd5,
+ 0x8ef10087, 0x66c18fd5, 0xf0068693, 0x0087571b,
+ 0x8fd98f75, 0x93811782, 0x8082953e, 0xec4e7139,
+ 0x89aae852, 0x85328a2e, 0x00034597, 0xac058593,
+ 0xf04af426, 0xfc06e456, 0x8ab2f822, 0x84ba8936,
+ 0x00f290ef, 0x66c1e539, 0x85ce8652, 0x80ef842a,
+ 0x571b0132, 0x179b0185, 0x8fd90185, 0x00ff06b7,
+ 0x0085171b, 0x8fd98f75, 0x551b6741, 0x07130085,
+ 0x8d79f007, 0x20238d5d, 0x479100a9, 0x70e2c09c,
+ 0x74428522, 0x790274a2, 0x6a4269e2, 0x61216aa2,
+ 0xe5978082, 0x85930003, 0x855657e5, 0x7b2290ef,
+ 0xe909842a, 0x864a66c1, 0x854e85d2, 0x37d200ef,
+ 0xb7e947d1, 0x0003e597, 0x56458593, 0x90ef8556,
+ 0x842a7902, 0x66c1e911, 0x85d2864a, 0x40ef854e,
+ 0x07936302, 0xb75d0200, 0x00030597, 0x5b058593,
+ 0x90ef8556, 0x842a76c2, 0x66c1e909, 0x85d2864a,
+ 0xf0ef854e, 0x47c112c1, 0x547db751, 0x7131b749,
+ 0xf526f922, 0xed4ef14a, 0xe556e952, 0xfcdee15a,
+ 0xf4e6f8e2, 0xeceef0ea, 0xfd068936, 0x89ae84aa,
+ 0xb0ef8a32, 0x842a64e1, 0x00036b17, 0x168b0b13,
+ 0x02010b93, 0x00033c17, 0xb64c0c13, 0x03010a93,
+ 0x01c10c93, 0x02810d13, 0x01810d93, 0x5e632901,
+ 0x57e10004, 0x00f40663, 0x450557d5, 0x0ef41563,
+ 0x00036917, 0x1b090913, 0x4601a855, 0x852685a2,
+ 0x3351b0ef, 0x855ae42a, 0x740290ef, 0x862a67a2,
+ 0x853e85da, 0x6ea290ef, 0x865ee921, 0x852685a2,
+ 0xe5aff0ef, 0x0e051763, 0x85627582, 0x24b2a0ef,
+ 0x661786d6, 0x06130003, 0x85a22166, 0xb0ef8526,
+ 0xc90d75b1, 0x47915742, 0x02f71663, 0xc39d411c,
+ 0x00036517, 0x20850513, 0x21f2a0ef, 0x00036517,
+ 0x20c50513, 0xdf3fc0ef, 0x852685a2, 0x5b41b0ef,
+ 0xb7b5842a, 0x866a86e6, 0x852685a2, 0xe26ff0ef,
+ 0x7602e541, 0x86d6876e, 0x855285ca, 0xe21ff0ef,
+ 0x47e2e53d, 0x1f634672, 0x75a204f6, 0x90ef8556,
+ 0xdd4d0172, 0x00036917, 0x15c90913, 0x460185a2,
+ 0xb0ef8526, 0x842a2831, 0x85ce4601, 0xb0ef8526,
+ 0x86aa2771, 0x85ca8622, 0x00036517, 0x1a850513,
+ 0x1a72a0ef, 0x70ea4501, 0x74aa744a, 0x69ea790a,
+ 0x6aaa6a4a, 0x7be66b0a, 0x7ca67c46, 0x6de67d06,
+ 0x80826129, 0x00036917, 0x11c90913, 0x6917bf45,
+ 0x09130003, 0xb75d12a9, 0x00036917, 0x0d890913,
+ 0x6917bf71, 0x09130003, 0xbf490ae9, 0x00347179,
+ 0xf022860a, 0xf406ec26, 0x842ae84a, 0xf0ef84ae,
+ 0xcd1dcbef, 0x45814601, 0xb0ef8522, 0x892a1fb1,
+ 0x85a64601, 0xb0ef8522, 0x86aa1ef1, 0x6597864a,
+ 0x85930003, 0x6517ffa5, 0x05130003, 0xa0ef0125,
+ 0x45011192, 0x740270a2, 0x694264e2, 0x80826145,
+ 0x660266a2, 0x852285a6, 0xe17ff0ef, 0x715db7e5,
+ 0x00037597, 0xe5858593, 0xe486fc26, 0xf84ae0a2,
+ 0xf052f44e, 0xe85aec56, 0xc0ef84aa, 0x5a6301c1,
+ 0xc0ef0205, 0x862a3421, 0x00037597, 0xe3058593,
+ 0x00036517, 0x11050513, 0x0bf2a0ef, 0x60a64501,
+ 0x74e26406, 0x79a27942, 0x6ae27a02, 0x61616b42,
+ 0x842a8082, 0x651785a6, 0x05130003, 0xa0efa325
+};
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_io.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_io.c
new file mode 100644
index 00000000..08a1fb77
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_io.c
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_io.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MSS IO related code
+ *
+ */
+#include
+#include
+
+#include "mpfs_hal/mss_hal.h"
+
+/*******************************************************************************
+ * external functions
+ */
+
+
+/*
+ * IOMUX values from Libero
+ */
+IOMUX_CONFIG iomux_config_values = {
+ LIBERO_SETTING_IOMUX0_CR, /* Selects whether the peripheral is connected to
+ the Fabric or IOMUX structure. */
+ LIBERO_SETTING_IOMUX1_CR, /* BNK4 SDV PAD 0 to 7, each IO has 4 bits */
+ LIBERO_SETTING_IOMUX2_CR, /* BNK4 SDV PAD 8 to 13 */
+ LIBERO_SETTING_IOMUX3_CR, /* BNK2 SDV PAD 14 to 21 */
+ LIBERO_SETTING_IOMUX4_CR, /* BNK2 SDV PAD 22 to 29 */
+ LIBERO_SETTING_IOMUX5_CR, /* BNK2 PAD 30 to 37 */
+ LIBERO_SETTING_IOMUX6_CR /* Sets whether the MMC/SD Voltage select lines
+ are inverted on entry to the IOMUX structure */
+};
+
+/*
+ * Bank 4 and 2 settings, the 38 MSSIO.
+ */
+MSSIO_BANK4_CONFIG mssio_bank4_io_config = {
+ /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
+ x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_0_1_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_2_3_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_4_5_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_6_7_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_8_9_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_10_11_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_12_13_CR,
+};
+
+/*
+ * Bank 4 and 2 settings, the 38 MSSIO.
+ */
+MSSIO_BANK2_CONFIG mssio_bank2_io_config = {
+ /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
+ x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_0_1_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_2_3_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_4_5_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_6_7_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_8_9_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_10_11_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_12_13_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_14_15_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_16_17_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_18_19_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_20_21_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_22_23_CR
+};
+
+/*******************************************************************************
+ * Local functions
+ */
+static uint8_t io_mux_and_bank_config(void);
+
+/***************************************************************************//**
+ * MSSIO OFF Mode
+ *
+ * The following settings are applied if MMSIO unused/off
+ *
+ * The IO Buffers are disabled.
+ * Output drivers are disabled (set the drv<3:0> bits to 0000, output
+ * enable "mss_oe" bit to 0)
+ * Disable the WPU bit set to 0 and enable the WPD bit set to 1.
+ * Receivers are disabled. (Ibufmd<2:0> set to 7)
+ *
+ * MSS can enable OFF mode through configurator bit for selective MSSIO
+ * from Bank2/Bank4 by making drv<3:0>/mss_oe bit to "0" for that
+ * particular MSSIO making Output driver disabled and ibufmd <2:0> bit to
+ * "7" for that particular MSSIO making input receiver disabled.
+ *
+ */
+
+/***************************************************************************//**
+ * mssio_setup()
+ *
+ * Setup the IOMUX and IO bank 2 and 4.
+ *
+ * To setup bank 2 and 4, ncode and pcode scb registers in system
+ * register block are set as per Libero supplied values.
+ * These need to be transferred to I/0
+ *
+ * @return 0 => pass
+ */
+uint8_t mssio_setup(void)
+{
+ uint8_t ret_status = 0U;
+ ret_status = io_mux_and_bank_config();
+ set_bank2_and_bank4_volts();
+ return (ret_status);
+}
+
+/***************************************************************************//**
+ * io_mux_and_bank_config(void)
+ * sets up the IOMUX and bank 2 and 4 pcodes and n codes
+ * @return 0 => OK
+ */
+static uint8_t io_mux_and_bank_config(void)
+{
+ /* Configure IO mux's
+ *
+ * IOMUX1_CR - IOMUX5_CR, five 32-bit registers, with four bits four bits
+ * for each I/O determine what is connected to each pad
+ *
+ * All internal peripherals are also connected to the fabric (apart from
+ * MMC/SDIO/GPIO/USB). The IOMUX0 register configures whether the IO
+ * function is connected to the fabric or the IOMUX.
+ *
+ * IOMUX6_CR Sets whether the MMC/SD Voltage select lines are inverted on
+ * entry to the IOMUX structure
+ *
+ * */
+ config_32_copy((void *)(&(SYSREG->IOMUX0_CR)),
+ &(iomux_config_values),
+ sizeof(IOMUX_CONFIG));
+
+ /*
+ * Configure MSS IO banks
+ * sets pcode and ncode using (mssio_bank2_cfg_cr/mssio_bank4_cfg_cr)
+ *
+ * The MSS IO pad configuration is provided by nineteen system registers
+ * each configuring two IO's using 15-bits per IO
+ * - (mssio_bank*_io_cfg_*_*_cr).
+
+ | mssio_bank*_io_cfg_*_*_cr | offset | info |
+ | field | offset | info |
+ |:-------------------------:|:-------------:|:-----|
+ | io_cfg_ibufmd_0 |0 | |
+ | io_cfg_ibufmd_1 |1 | |
+ | io_cfg_ibufmd_2 |2 | |
+ | io_cfg_drv_0 |3 | |
+ | Io_cfg_drv_1 |4 | |
+ | Io_cfg_drv_2 |5 | |
+ | io_cfg_drv_3 |6 | |
+ | io_cfg_clamp |7 | |
+ | io_cfg_enhyst |8 | |
+ | io_cfg_lockdn_en |9 | |
+ | io_cfg_wpd |10 | |
+ | io_cfg_wpu |11 | |
+ | io_cfg_atp_en |12 | |
+ | io_cfg_lp_persist_en |13 | |
+ | io_cfg_lp_bypass_en |14 | |
+ * */
+
+ config_32_copy((void *)(&(SYSREG->MSSIO_BANK4_IO_CFG_0_1_CR)),
+ &(mssio_bank4_io_config),
+ sizeof(MSSIO_BANK4_CONFIG));
+
+ config_32_copy((void *)(&(SYSREG->MSSIO_BANK2_IO_CFG_0_1_CR)),
+ &(mssio_bank2_io_config),
+ sizeof(MSSIO_BANK2_CONFIG));
+
+ set_bank2_and_bank4_volts();
+
+ return(0L);
+}
+
+/**
+ * set_bank2_and_bank4_volts(void)
+ * sets bank voltage parameters
+ * bank_pcode
+ * bank_ncode
+ * vs
+ * @return
+ */
+void set_bank2_and_bank4_volts(void)
+{
+
+ SCB_REGS->MSSIO_BANK2_CFG_CR.MSSIO_BANK2_CFG_CR =\
+ (uint32_t)LIBERO_SETTING_MSSIO_BANK2_CFG_CR;
+ SCB_REGS->MSSIO_BANK4_CFG_CR.MSSIO_BANK4_CFG_CR =\
+ (uint32_t)LIBERO_SETTING_MSSIO_BANK4_CFG_CR;
+
+ return;
+}
+
+#ifdef EXAMPLE_MSSIO_APP_CODE
+#include "drivers/mss_gpio/mss_gpio.h"
+/**
+ *
+ * @return 0 => OK
+ */
+int32_t gpio_toggle_test(void)
+{
+ SYSREG->TEMP0 = 0x11111111;
+
+ for (int l = 0 ; l < 14 ; l++)
+ {
+ for (int i = 0 ; i < 14 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO0_LO, i, 0x0);
+ }
+ for (int i = 0 ; i < 24 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO1_LO, i, 0x0);
+ }
+ SYSREG->TEMP0 = 0xFFFFFFFFUL;
+ for (int i = 0 ; i < 14 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO0_LO, i, 0x1);
+ }
+ for (int i = 0 ; i < 24 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO1_LO, i, 0x1);
+ }
+ }
+ return(0UL);
+}
+
+
+/**
+ *
+ * @return 0 => OK
+ */
+int32_t gpio_set_config(void)
+{
+ SYSREG->SOFT_RESET_CR &= ~((1U<<20U)|(1U<<21U)|(1U<<22U));
+ SYSREG->SUBBLK_CLOCK_CR |= ((1U<<20U)|(1U<<21U)|(1U<<22U));
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_init(GPIO1_LO);
+ for (int i = 0 ; i < 14 ; i++)
+ {
+ MSS_GPIO_config(GPIO0_LO, i, MSS_GPIO_OUTPUT_MODE);
+ }
+ for (int i = 0 ; i < 24 ; i++)
+ {
+ MSS_GPIO_config(GPIO1_LO, i, MSS_GPIO_OUTPUT_MODE);
+ }
+ return(0UL);
+}
+#endif
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_io_config.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_io_config.h
new file mode 100644
index 00000000..0feebdfc
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_io_config.h
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_io_config.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MSS IO related code
+ *
+ */
+
+#ifndef xUSER_CONFIG_MSS_DDRC_MSS_IO_CONFIG_H_
+#define xUSER_CONFIG_MSS_DDRC_MSS_IO_CONFIG_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * There are 38 general purpose IO pads, referred to as MSSIO, to support
+ * peripheral devices. System registers will select which signals are connected
+ * to the IO pads. These are in addition to the SGMII IO for the Ethernet MACs,
+ * DDR I/O and two IOs to allow interfacing to an external 32kHz crystal. All
+ * of these MSSIOs are bonded out to pins in all packages. The MSSIOs may be
+ * configured as the IOs of any of the MSS peripherals listed in the table
+ * below.
+ */
+
+/*
+ - MUX -> PAD options set by Libero, register iomux1_cr to iomux5_cr
+ | option | value | Info |
+ |:-------------:|:-------------:|:-----:|
+ | SD_SDIO | 0x0 | |
+ | EMMC | 0x1 | |
+ | QSPI | 0x2 | |
+ | SPI | 0x3 | |
+ | USB | 0x4 | |
+ | MMUART | 0x5 | |
+ | I2C | 0x6 | |
+ | CAN | 0x7 | |
+ | MDIO | 0x8 | |
+ | Miscellaneous | 0x9 | |
+ | Reservedx | 0xA | |
+ | GPIO_PAD | 0xB | |
+ | Fabric_test | 0xC | |
+ | Logic_0 | 0xD | |
+ | Logic_1 | 0xE | |
+ | Tristate | 0xF |Default|
+ */
+
+/**
+ * \brief IOMUX configuration
+ */
+typedef struct IOMUX_CONFIG_ {
+ __IO uint32_t iomux0_cr; /* peripheral is connected to the Fabric or
+ IOMUX structure */
+ __IO uint32_t iomux1_cr; /* BNK4 SDV PAD 0 to 7 */
+ __IO uint32_t iomux2_cr; /* BNK4 SDV PAD 8 to 13 */
+ __IO uint32_t iomux3_cr; /* BNK2 SDV PAD 14 to 21 */
+ __IO uint32_t iomux4_cr; /* BNK2 SDV PAD 22 to 29 */
+ __IO uint32_t iomux5_cr; /* BNK2 PAD 30 to 37 */
+ __IO uint32_t iomux6_cr; /* MMC/SD Voltage select lines are inverted on
+ entry to the IOMUX structure */
+} IOMUX_CONFIG;
+
+
+
+/*
+ pcode, ncode and drive strength for each bank is set using direct writes to
+ the SCB registers
+
+ The MSS IO pad configuration is provided by nineteen system registers
+ each configuring two IO's using 15-bits per IO
+ Theses registers are located in the MSS sysreg.
+
+ - (mssio_bank*_io_cfg_*_*_cr).
+
+ | mssio_bank*_io_cfg_*_*_cr | offset | info |
+ | field | | info |
+ |:-------------------------:|:-------------:|:-----|
+ | io_cfg_ibufmd_0 |0 | |
+ | io_cfg_ibufmd_1 |1 | |
+ | io_cfg_ibufmd_2 |2 | |
+ | io_cfg_drv_0 |3 | |
+ | Io_cfg_drv_1 |4 | |
+ | Io_cfg_drv_2 |5 | |
+ | io_cfg_drv_3 |6 | |
+ | io_cfg_clamp |7 | |
+ | io_cfg_enhyst |8 | |
+ | io_cfg_lockdn_en |9 | |
+ | io_cfg_wpd |10 | |
+ | io_cfg_wpu |11 | |
+ | io_cfg_atp_en |12 | |
+ | io_cfg_lp_persist_en |13 | |
+ | io_cfg_lp_bypass_en |14 | |
+
+*/
+
+/**
+ * \brief Bank 2 and 4 voltage settings
+ *
+ */
+typedef struct HSS_MSSIO_Bank_Config_ {
+ __IO uint32_t mssio_bank4_pcode_ncode_vs; /* bank 4- set pcode, ncode and
+ drive strength */
+ __IO uint32_t mssio_bank2_pcode_ncode_vs; /* bank 2- set pcode, ncode and
+ drive strength */
+}MSSIO_BANK_CONFIG;
+
+/**
+ * \brief MSS IO Bank 4 configuration
+ */
+typedef struct MSSIO_Bank4_IO_Config_ {
+ __IO uint32_t mssio_bank4_io_cfg_0_cr; /* x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ __IO uint32_t mssio_bank4_io_cfg_1_cr;
+ __IO uint32_t mssio_bank4_io_cfg_2_cr;
+ __IO uint32_t mssio_bank4_io_cfg_3_cr;
+ __IO uint32_t mssio_bank4_io_cfg_4_cr;
+ __IO uint32_t mssio_bank4_io_cfg_5_cr;
+ __IO uint32_t mssio_bank4_io_cfg_6_cr;
+
+}MSSIO_BANK4_CONFIG;
+
+/**
+ * \brief MSS IO Bank 2 configuration
+ */
+typedef struct MSSIO_Bank2_IO_Config_ {
+ __IO uint32_t mssio_bank2_io_cfg_0_cr; /* x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ __IO uint32_t mssio_bank2_io_cfg_1_cr;
+ __IO uint32_t mssio_bank2_io_cfg_2_cr;
+ __IO uint32_t mssio_bank2_io_cfg_3_cr;
+ __IO uint32_t mssio_bank2_io_cfg_4_cr;
+ __IO uint32_t mssio_bank2_io_cfg_5_cr;
+ __IO uint32_t mssio_bank2_io_cfg_6_cr;
+ __IO uint32_t mssio_bank2_io_cfg_7_cr;
+ __IO uint32_t mssio_bank2_io_cfg_8_cr;
+ __IO uint32_t mssio_bank2_io_cfg_9_cr;
+ __IO uint32_t mssio_bank2_io_cfg_10_cr;
+ __IO uint32_t mssio_bank2_io_cfg_11_cr;
+}MSSIO_BANK2_CONFIG;
+
+
+/***************************************************************************//**
+ The int32_t mssio_setup(void)()
+
+ Setup the IOMUX and IO bank 2 and 4.
+ The values used in this function are set by Libero.
+ It configures the I/O mux, which detemines what peripherals are connected to
+ what pins, and the electrical properties of each bank and each I/O.
+
+ @return
+ This function returns status, 0 => OK
+
+ Example:
+ @code
+
+ error |= mssio_setup();
+
+ @endcode
+
+ */
+uint8_t
+mssio_setup
+(
+ void
+);
+
+
+/***************************************************************************//**
+ The gpio_toggle_test(void)()
+
+ Toggle a GPIO PIN on start-up
+
+ @return
+ This function returns status, 0 => OK
+
+ Example:
+ @code
+
+ error |= mssio_setup();
+
+ @endcode
+
+ */
+int32_t
+gpio_toggle_test
+(
+ void
+);
+
+/***************************************************************************//**
+ set_bank2_and_bank4_volts()
+ Sets bank 2 and 4 voltages, with Values coming from Libero
+
+ Example:
+
+ @code
+
+ set_bank2_and_bank4_volts();
+
+ @endcode
+
+ *
+ */
+void
+set_bank2_and_bank4_volts
+(
+ void
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USER_CONFIG_MSS_DDRC_MSS_IO_CONFIG_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c
new file mode 100644
index 00000000..698cceff
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_nwc_init.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief north west corner, calls required startup code
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "mss_nwc_init.h"
+#include "simulation.h"
+
+#ifdef DEBUG_DDR_INIT
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+extern mss_uart_instance_t *g_debug_uart ;
+uint32_t setup_ddr_debug_port(mss_uart_instance_t * uart);
+#endif
+
+/*******************************************************************************
+ * Local Defines
+ */
+CFG_DDR_SGMII_PHY_TypeDef * const CFG_DDR_SGMII_PHY = ((CFG_DDR_SGMII_PHY_TypeDef *) CFG_DDR_SGMII_PHY_BASE);
+DDR_CSR_APB_TypeDef * const DDRCFG = ((DDR_CSR_APB_TypeDef *) DDRCFG_BASE);
+IOSCBCFG_TypeDef * const SCBCFG_REGS = (IOSCBCFG_TypeDef *)IOSCBCFG_BASE ;
+g5_mss_top_scb_regs_TypeDef * const SCB_REGS = (g5_mss_top_scb_regs_TypeDef *) SYSREGSCB_BASE;
+
+/*******************************************************************************
+ * Local functions
+ */
+void delay(uint32_t n);
+
+/*******************************************************************************
+ * extern defined functions
+ */
+#ifdef DEBUG_DDR_INIT
+uint32_t setup_ddr_debug_port(mss_uart_instance_t * uart);
+#endif
+
+/******************************************************************************
+ * Public Functions - API
+ ******************************************************************************/
+
+/**
+ * MSS_DDR_init_simulation(void)
+ * Flow when running through full chip simulation
+ *
+ * @return
+ */
+uint8_t mss_nwc_init(void)
+{
+ uint8_t error = 0U;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+#ifdef SIMULATION_TEST_FEEDBACK
+ /*
+ * set the test version- this is read in Simulation environment
+ * x.y.z
+ * byte[0] = z
+ * byte[1] = y
+ * byte[2] = x
+ */
+ SIM_FEEDBACK0(0x33333333);
+ SYSREG->TEMP0 = (0U << 16U) | (3U << 8U) | 3U;
+ SYSREG->TEMP0 = 0x44444444U;
+ SIM_FEEDBACK0(1);
+ SIM_FEEDBACK0(0x55555555);
+ SIM_FEEDBACK0(1);
+#endif
+ /*
+ * Assumptions:
+ * 1. We enter here shortly after start-up of E51 code by the system
+ * controller.
+ * 2. We are running on the E51 and all other cores are in wfi.
+ * 3. The MSS PLL will be set to use default internal clock of 80MH
+ * 4. MSS peripherals including the I/O are in the default power on state
+ *
+ *
+ * The following implements setting of
+ * external clock reference
+ * MSS PLL, SHMII PLL, SGMII PLL, MSS Mux's
+ * IO settings and IO MUX
+ * HSIO IO calibration options
+ * SGMII configuration
+ * DDR configuration
+ * Including SEG regs
+ * MPU setup
+ * PMP setup
+ * ABP Peripheral address setup (High/Low)
+ *
+ */
+
+ /*
+ * Set based on reference clock
+ */
+ set_RTC_divisor();
+
+ /*
+ * SCB access settings
+ * Bits 15:8 Sets how long SCB request is held active after SCB bus granted.
+ * Allows SCB bus master-ship to maintained across multiple SCB access
+ * cycles
+ * Bits 7:0 Set the timeout for an SCB access in CPU cycles.
+ */
+ SCBCFG_REGS->TIMER.TIMER = MSS_SCB_ACCESS_CONFIG;
+
+ /*
+ * Release APB reset & turn on dfi clock
+ *
+ * reserved bit 31:2
+ * reset bit 1 Asserts the APB reset to the MSS corner, is asserted at
+ * MSS reset.
+ * clock_on bit 0 Turns on the APB clock to the MSS Corner, is off at
+ * reset. Once corner blocks is configured the firmware
+ * may turn off the clock, but periodically should turn
+ * back on to allow refresh of TMR registers inside
+ * the corner block.
+ *
+ */
+ SYSREG->DFIAPB_CR = 0x00000001U;
+
+ /*
+ * Dynamic APB enables for slaves
+ * APB dynamic enables determine if we can write to the associated APB
+ * registers.
+ * ACB dynamic enables determine if we can write to the associated SCB
+ * registers.
+ *
+ * bit 31:22 Reserved
+ * bit 21 DYNEN_APB_DECODER_PRESETS
+ * bit 20 DYNEN_APB_BANKCNTL
+ * bit 19 DYNEN_APB_IO_CALIB
+ * bit 18 DYNEN_APB_CFM
+ * bit 17 DYNEN_APB_PLL1
+ * bit 16 DYNEN_APB_PLL0
+ * bit 15:13 Reserved
+ * bit 12 DYNEN_SCB_BANKCNTL
+ * bit 11 DYNEN_SCB_IO_CALIB
+ * bit 10 DYNEN_SCB_CFM
+ * bit 9 DYNEN_SCB_PLL1
+ * bit 8 DYNEN_SCB_PLL0
+ * bit 7:5 Reserved
+ * bit 4 Persist_DATA
+ * bit 3 CLKOUT
+ * bit 2 PERSIST_ADD_CMD
+ * bit 1 DATA_Lockdn
+ * bit 0 ADD_CMD_Lockdn
+ */
+ CFG_DDR_SGMII_PHY->DDRPHY_STARTUP.DDRPHY_STARTUP =\
+ (0x3FU << 16U) | (0x1FU << 8U);
+ /* Enable all dynamic enables
+ When in dynamic enable more, this allows:
+ 1. writing directly using SCB
+ 2. setting using RPC on a soft reset
+ */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x01U<< 10U) | (0x7FU<<0U);
+
+ /*
+ * Configure IOMUX and I/O settings for bank 2 and 4
+ */
+ {
+#ifdef MSSIO_SUPPORT
+ error |= mssio_setup();
+#endif
+ }
+
+ /*************************************************************************/
+
+ /*
+ *
+ * In this step we enter Dynamic Enable mode.
+ * This is done by using the following sequence:
+ *
+ * Please note all dynamic enables must be enabled.
+ * If dynamic enables are not enabled, when flash valid is asserted, value
+ * of SCB registers will be immediately written to with default values
+ * rather than the RPC values.
+ *
+ * Dynamic Enable mode:
+ * Step 1:
+ * Make sure SCB dynamic enable bit is high
+ * step 2: Assert MSS core_up
+ * followed by delay
+ * step 3: Change dce[0,1,2] to 0x00
+ * followed by delay
+ * step 4: Assert flash valid
+ * followed by delay
+ * step 5: make sure all RPC registers are set to desired values
+ * (using mode and direct RPC writes to RPC)
+ * step 6: soft reset IP so SCB registers are written with RPC values.
+ * note: We will carry out step 5/6 later, once we have modified any
+ * RPC registers directly that may need tweaking or are not
+ * included in the mode write state machine, carried out in a
+ * previous step.
+ *
+ * Note 1: The SCB bus can be used to update/write new values to
+ * the SCB registers through the SCB bus interface while in Dynamic
+ * enable mode
+ * Note 2: The MSS top block assertion of core_up and flash_valid
+ * have no effect in themselves if MSS custom SCB register values
+ * if the custom SCB slaves are not being reset at the same time.
+ * If the custom SCB slaves are reset whilst core_up and
+ * flash_valid are high, then the SCB registers get asynchronously
+ * loaded with the values of their corresponding RPC bits. These
+ * values remain even after negation of reset but may be
+ * subsequently overwritten by SCB writes.
+ *
+ * reg MSS_LOW_POWER_CR
+ *
+ * bit 12 flash_valid Sets the value driven out on
+ * mss_flash_valid_out
+ * bit 11 core_up Sets the value driven out on
+ * mss_core_up_out
+ * bit 10:8 dce S Sets the value driven out on mss_dce_out
+ * unless G5C asserts its overrides
+ * bit 7 lp_stop_clocks_in Read back of lp_stop_clocks input
+ * bit 6 lp_stop_clocks_out Direct control of MSS Corner LP state
+ * control
+ * bit 5 p_pll_locked Direct control of MSS Corner
+ * LP state control
+ * bit 4 lp_state_bypass Direct control of MSS Corner LP
+ * state control
+ * bit 3 lp_state_persist
+ * bit 2 lp_state_op
+ * bit 1 lp_state_ip
+ * bit 0 lp_state_mss
+ *
+ * In order to re-flash/update the APB RPC register values into the
+ * registers of a specific SCB slave,the following sequence must be
+ * followed:
+ * 1) Embedded software running on E51 must force the mss_core_up and
+ * mss_flash valid must be high
+ * 2) Then do a soft reset of the specific SCB slave that will be
+ * re-flashed/updated.
+ *
+ * The APB RPC registers are used in the following ways to configure
+ * the MSS periphery
+ * 1) Load values to SCB registers.
+ * core_up" and "flash_valid" determines if the SCB registers get
+ * either:
+ * a. Reset to their hardware default
+ * (when core_up/flash_valis low)
+ * b. Loaded with the APB RPC register.
+ * (when core_up/flash_valid high)
+ * 2) IO configuration settings
+ * These are fed directly to the static configuration of IOA cells
+ * within the IOG lanes of the DDR and SGMII PHYs, as long as
+ * "core_up" and "flash_valid" are high.
+ * a. To avoid unwanted/intermediate states on IOs, the "core_up"
+ * and "flash_valid" should be initially 0 on MSS reset. This will
+ * select the safe hardware defaults. The RPC registers are written
+ * in the background and then simultaneously "flashed" as the new
+ * IO configuration by assertion of "core_up" and "flash_valid"
+ * being asserted.
+ * 3) Training IP settings
+ * These allow the direct control of the training IP via the APB
+ * registers.
+ *
+ * Notes:
+ * 1) When the MSS is reset, the SCB slaves won't take on the RPC
+ * values. They will be reset to their hardware default values.
+ *
+ * 2) Although RPC registers are writable in APB space,
+ * they only take effect on the SCB registers whenever there is a
+ * "virtual re-flash" operation, which involves performing
+ * a soft reset of an SCB slave (i.e. writing to the NV_MAP register
+ * bit in the SOFT_RESET register in the SCB slave).
+ * This mechanism would only be used if a full new configuration is to
+ * be applied to the full SCB slave and wouldn't be used, for example
+ * to change just a clock mux configuration.
+ *
+ * 3) To make configuration changes to individual registers, without
+ * "re-flashing" all registers in an MSS custom SCB slave, it is
+ * necessary to write directly to the SCB registers (via SCB space) in
+ * that slave, rather than writing RPC registers via APB space
+ *
+ */
+
+ /*
+ lp_state_mss :1;
+ lp_state_ip_mss :1;
+ lp_state_op_mss :1;
+ lp_state_persist_mss :1;
+ lp_state_bypass_mss :1;
+ lp_pll_locked_mss :1;
+ lp_stop_clocks_out_mss :1;
+ lp_stop_clocks_in_mss :1;
+ mss_dce :3;
+ mss_core_up :1;
+ mss_flash_valid :1;
+ mss_io_en :1;
+ */
+ /* DCE:111, CORE_UP:1, FLASH_VALID:0, mss_io_en:0 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x07U<<8U)|(0x01U<<11U)|(0x00U<<12U)|(0x00U<<13U);
+ delay((uint32_t) 10U);
+ /* DCE:000, CORE_UP:1, FLASH_VALID:0, mss_io_en:0 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x00U<<8U)|(0x01U<<11U)|(0x00U<<12U)|(0x00U<<13U);
+ delay((uint32_t) 10U);
+ /* DCE:000, CORE_UP:1, FLASH_VALID:1, mss_io_en:0 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x00U<<8U)|(0x01U<<11U)|(0x01U<<12U)|(0x00U<<13U);
+ delay((uint32_t) 10U);
+ /* DCE:000, CORE_UP:1, FLASH_VALID:1, mss_io_en:1 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x00U<<8U)|(0x01U<<11U)|(0x01U<<12U)|(0x01U<<13U);
+
+ /*
+ * Setup SGMII
+ * The SGMII set-upset configures the external clock reference so this must
+ * be called before configuring the MSS PLL
+ */
+ SIM_FEEDBACK0(2);
+ sgmii_setup();
+
+ /*
+ * Setup the MSS PLL
+ */
+ SIM_FEEDBACK0(3);
+ mss_pll_config();
+
+ {
+#ifdef DDR_SUPPORT
+#ifdef DEBUG_DDR_INIT
+ {
+ (void)setup_ddr_debug_port(g_debug_uart);
+ }
+#endif
+
+ uint32_t ddr_status;
+ ddr_status = ddr_state_machine(DDR_SS__INIT);
+
+ while((ddr_status & DDR_SETUP_DONE) != DDR_SETUP_DONE)
+ {
+ ddr_status = ddr_state_machine(DDR_SS_MONITOR);
+ }
+ if ((ddr_status & DDR_SETUP_FAIL) == DDR_SETUP_FAIL)
+ {
+ error |= (0x1U << 2U);
+ }
+ //todo: remove, just for sim test ddr_recalib_io_test();
+#endif
+ }
+
+#endif /* end of !define SIFIVE_HIFIVE_UNLEASHED */
+ SIM_FEEDBACK0(0x12345678U);
+ SIM_FEEDBACK0(error);
+ SIM_FEEDBACK0(0x87654321U);
+ return error;
+}
+
+
+/*-------------------------------------------------------------------------*//**
+ * delay()
+ * Not absolute. Dependency on current clk rate
+ * @param n Number of iterations to wait.
+ */
+void delay(uint32_t n)
+{
+ volatile uint32_t count = n;
+ while(count!=0U)
+ {
+ count--;
+ }
+}
+
+/*-------------------------------------------------------------------------*//**
+ * mtime_delay()
+ * waits x microseconds
+ * Assumption 1 is we have ensured clock is 1MHz
+ * Assumption 2 is we have not setup tick timer when using this function. It is
+ * only used by the startup code
+ * @param microseconds microseconds to delay
+ */
+
+void mtime_delay(uint32_t microseconds)
+{
+ CLINT->MTIME = 0ULL;
+ volatile uint32_t count = 0ULL;
+
+ while(CLINT->MTIME < microseconds)
+ {
+ count++;
+ }
+ return;
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_nwc_init.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_nwc_init.h
new file mode 100644
index 00000000..b759b82c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_nwc_init.h
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_nwc_init.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief defines for mss_nwc_init.c
+ *
+ */
+
+/*=========================================================================*//**
+ @page MPFS MSS NWC configuration
+ ==============================================================================
+ @section intro_sec Introduction
+ ==============================================================================
+ The MPFS microcontroller subsystem (MSS) includes a number of hard core
+ components physically located in the north west corner of the MSS on the die.
+
+ ==============================================================================
+ @section Items located in the north west corner
+ ==============================================================================
+ MSS PLL
+ SGMII
+ DDR phy
+ MSSIO
+
+ ==============================================================================
+ @section Flow diagram
+ ==============================================================================
+ todo: remove, added line here as test *****
+ Simplified flow diagram
+ +-----------------+
+ | start |
+ | NWC setup |
+ +-------+---------+
+ v
+ +-----------------+
+ | set SCB access|
+ | Parameters |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Release APB NWC |
+ | Turn on APB clk |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Set Dynamic |
+ | enable bits |
+ +-------++--------+
+ |
+ +-------v---------+
+ | Setup signals |
+ | DCE,CORE_UP, |
+ | Flash_Valid, |
+ | MSS_IO_EN |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Setup SGMII |
+ | |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Setup DDR |
+ | |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Setup MSSIO |
+ | |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Finished |
+ +-----------------+
+
+ *//*=========================================================================*/
+#ifndef __MSS_NWC_INIT_H_
+#define __MSS_NWC_INIT_H_ 1
+
+
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************************************************************//**
+ MSS_SCB_ACCESS_CONFIG_ON_RESET
+
+ SCB access settings on reset.
+ Bits 15:8 Sets how long SCB request is held active after SCB bus granted.
+ Allows SCB bus master-ship to maintained across multiple SCB access
+ cycles
+ Bits 7:0 Set the timeout for an SCB access in CPU cycles.
+
+ Note: These settings are used even after we change the MSS clock from SCB
+ 80MHz default setting. todo: This needs to be confirmed as OK, there will be
+ no potential timing issues:
+ Min 143 Hclk cycles for simulation set-up, making 160
+ todo: review setting
+ */
+
+#define MSS_SCB_ACCESS_CONFIG ((160UL<<8U)|(0x80U))
+
+
+/***************************************************************************//**
+ mss_nwc_init()
+ Called on start-up, initializes clocks, sgmii, ddr, mssio
+ */
+uint8_t
+mss_nwc_init
+(
+ void
+);
+
+
+/***************************************************************************//**
+ mtime_delay(x) delay function, passes microseconds
+ waits x microseconds
+ Assumption 1 is we have ensured clock is 1MHz
+ Assumption 2 is we have not setup tick timer when using this function. It is
+ only used by the startup code.
+
+ Example:
+ @code
+
+ mtime_delay(100UL);
+
+ @endcode
+
+ */
+void
+mtime_delay
+(
+ uint32_t microseconds
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_DDRC_H_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_pll.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_pll.c
new file mode 100644
index 00000000..df1ecc6f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_pll.c
@@ -0,0 +1,724 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_pll.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPSS PLL setup
+ *
+ */
+
+#include "mpfs_hal/mss_hal.h"
+#include "mss_pll.h"
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+/**
+ * We do it this way to avoid multiple LDRA warnings
+ * alternate it to
+ * #define MSS_SCB_MSS_PLL (IOSCB_CFM_MSS *) )x7xxxxxxx The actual
+ * address * but above results in error every time we use the function
+ */
+
+PLL_TypeDef * const MSS_SCB_MSS_PLL = ((PLL_TypeDef *) MSS_SCB_MSS_PLL_BASE);
+PLL_TypeDef * const MSS_SCB_DDR_PLL = ((PLL_TypeDef *) MSS_SCB_DDR_PLL_BASE);
+PLL_TypeDef * const MSS_SCB_SGMII_PLL = ((PLL_TypeDef *) MSS_SCB_SGMII_PLL_BASE);
+IOSCB_CFM_MSS * const MSS_SCB_CFM_MSS_MUX =\
+ ((IOSCB_CFM_MSS *) MSS_SCB_MSS_MUX_BASE);
+IOSCB_CFM_SGMII * const MSS_SCB_CFM_SGMII_MUX =\
+ ((IOSCB_CFM_SGMII *) MSS_SCB_SGMII_MUX_BASE);
+IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_SGMII =\
+ (IOSCB_IO_CALIB_STRUCT *)IOSCB_IO_CALIB_SGMII_BASE;
+IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_DDR =\
+ (IOSCB_IO_CALIB_STRUCT *)IOSCB_IO_CALIB_DDR_BASE;
+
+
+/*******************************************************************************-
+ * Symbols from the linker script used to locate the text, data and bss
+ * sections.
+ ******************************************************************************/
+#ifndef MPFS_HAL_HW_CONFIG
+uint32_t __sc_load;
+uint32_t __sc_start;
+uint32_t __sc_end;
+#else
+extern uint32_t __sc_load;
+extern uint32_t __sc_start;
+extern uint32_t __sc_end;
+
+/*******************************************************************************
+ * Local Defines *
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function declarations
+ */
+__attribute__((weak)) void copy_switch_code(void);
+
+
+/*******************************************************************************
+ * Instance definitions *
+ ******************************************************************************/
+
+void sgmii_mux_config(uint8_t option);
+
+/*******************************************************************************
+ Local functions *
+*******************************************************************************/
+
+
+/***************************************************************************//**
+ * set_RTC_divisor()
+ * Set the RTC divisor based on MSS Configurator setting
+ * Note: This will always be calculated so RTC clock is 1MHz.
+ */
+void set_RTC_divisor(void)
+{
+
+ SYSREG->RTC_CLOCK_CR &= ~(0x01U<<16); /* disable RTC clock */
+
+ SYSREG->RTC_CLOCK_CR = (LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK / \
+ LIBERO_SETTING_MSS_RTC_TOGGLE_CLK);
+
+ SYSREG->RTC_CLOCK_CR |= (0x01U<<16); /* enable RTC clock */
+
+}
+
+
+/***************************************************************************//**
+ * mss_mux_pre_mss_pll_config()
+ *
+ * Feed through required reference clks to PLL, configure PLL and wait for lock
+ ******************************************************************************/
+static void mss_mux_pre_mss_pll_config(void)
+{
+ /*
+ * PLL RF clk mux selections
+ * [31:15] Reserved
+ * [14:10] pll1_fdr_sel
+ * [9:8] pll1_rfclk1_sel
+ * [7:6] pll1_rfclk0_sel
+ * [5:4] pll0_rfclk1_sel
+ * [3:2] pll0_rfclk0_sel
+ * [1:0] clk_in_mac_tsu_sel
+ *
+ * Each mux uses 2 configuration bits. These are decoded as follows:
+ * 00 vss
+ * 01 refclk_p,refclk_n
+ * 10 scb_clk
+ * 10 serdes_refclk_crn_mss<0>, serdes_refclk_crn_mss<1>
+ *
+ * e.g.
+ * PLL_CKMUX = 0x00000154
+ * pll0_rfclk0_sel = 1 => refclk_p is used for pll0 ref0 and refclk_n is
+ * fed to MSS PLL ref1
+ */
+ /* CFM_MSS 0x3E002000 - 0x08 */
+ MSS_SCB_CFM_MSS_MUX->PLL_CKMUX = LIBERO_SETTING_MSS_PLL_CKMUX;
+ /*
+ * MSS Clock mux selections
+ * [31:5] Reserved
+ * [4] clk_standby_sel
+ * [3:2] mssclk_mux_md
+ * step 7: 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the
+ * MSS PLL clock.
+ * [1:0] mssclk_mux_sel MSS glitchless mux select
+ * 00 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=clk_standby
+ * 01 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=clk_standby
+ * 10 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=pllout1
+ * 11 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=pllout1
+ *
+ *
+ */
+ /*
+ * We will not set as already set to 0, we feed through after we have setup
+ * clock
+ * MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = LIBERO_SETTING_MSS_MSSCLKMUX;
+ */
+
+ /*
+ * Clock_Receiver
+ * [13] en_rdiff
+ * [12] clkbuf_en_pullup
+ * [11:10] en_rxmode_n
+ * [9:8] en_term_n
+ * [7] en_ins_hyst_n
+ * [6] en_udrive_n
+ * [5:4] en_rxmode_p
+ * [3:2] en_term_p
+ * [1] en_ins_hyst_p
+ * [0] en_udrive_p
+ */
+ MSS_SCB_CFM_SGMII_MUX->CLK_XCVR = LIBERO_SETTING_SGMII_CLK_XCVR;
+
+ /*
+ * 29:25 bclk5_sel
+ * 24:20 bclk4_sel
+ * 19:15 bclk3_sel
+ * 14:10 bclk2_sel
+ * 9:5 bclk1_sel
+ * 4:0 bclk0_sel
+ *
+ * From SAC spec:
+ * Table 9 1: Each gbim bank clock mux programming in MSS corner
+ * The DDRPHY bank clocks bclk_horz<5:0> and bclk_vert<5:0> are driven
+ * from mux's gbim<5:0> in the MSS corner. Each mux uses 5 configuration
+ * bits.
+ *
+ * BCLK mux selections
+ * bclk0_sel=0x8 (pll0_out_1k<2> selected)
+ * bclk1_sel=0x10 (pll0_out_1k<3> selected)
+ * bclk2_sel=0x1 (vss selected)
+ * bclk3_sel=0x1 (vss selected)
+ * bclk4_sel=0x1 (vss selected)
+ * bclk5_sel=0x1 (vss selected)
+ *
+ */
+ MSS_SCB_CFM_MSS_MUX->BCLKMUX = LIBERO_SETTING_MSS_BCLKMUX;
+
+ /* MSS_SCB_CFM_MSS_MUX->SPARE0 = BCLKMUX_USER_CONFIG; */
+ MSS_SCB_CFM_MSS_MUX->FMETER_ADDR = LIBERO_SETTING_MSS_FMETER_ADDR;
+
+ MSS_SCB_CFM_MSS_MUX->FMETER_DATAW = LIBERO_SETTING_MSS_FMETER_DATAW;
+
+ MSS_SCB_CFM_MSS_MUX->FMETER_DATAR = LIBERO_SETTING_MSS_FMETER_DATAR;
+
+ /*
+ *
+ */
+ volatile uint32_t i;
+ for(i = 0U; i < 400U; i++)
+ {
+ i++;
+ }
+}
+
+
+/***************************************************************************//**
+ * mss_mux_post_mss_pll_config(void)
+ *
+ * Once MSS locked, feed through to MSS
+ * We must run this code from RAM, as we need to modify the clock of the eNVM
+ * The first thing we do is change the eNVM clock, to prevent L1 cache accessing
+ * eNVM as it will do as we approach the return instruction
+ * The mb() makes sure order of processing is not changed by the compiler
+ ******************************************************************************/
+__attribute__((section(".ram_codetext"))) \
+ static void mss_mux_post_mss_pll_config(void)
+{
+ /*
+ * Modify the eNVM clock, so it now matches new MSS clock
+ *
+ * [5:0]
+ * Sets the number of AHB cycles used to generate the PNVM clock,.
+ * Clock period = (Value+1) * (1000/AHBFREQMHZ)
+ * Value must be 1 to 63 (0 defaults to 15)
+ * e.g.
+ * 7 will generate a 40ns period 25MHz clock if the AHB clock is 200MHz
+ * 11 will generate a 40ns period 25MHz clock if the AHB clock is 250MHz
+ * 15 will generate a 40ns period 25MHz clock if the AHB clock is 400MHz
+ *
+ */
+ SYSREG->ENVM_CR = LIBERO_SETTING_MSS_ENVM_CR;
+
+ mb(); /* make sure we change clock in eNVM first so ready by the time we
+ leave */
+
+ /*
+ * When you're changing the eNVM clock frequency, there is a bit
+ * (ENVM_CR_clock_okay) in the eNVM_CR which can be polled to check that
+ * the frequency change has happened before bumping up the AHB frequency.
+ */
+ volatile uint32_t wait_for_true = 0U;
+ while ((SYSREG->ENVM_CR & ENVM_CR_CLOCK_OKAY_MASK) !=\
+ ENVM_CR_CLOCK_OKAY_MASK)
+ {
+#ifdef RENODE_DEBUG
+ break;
+#endif
+ wait_for_true++; /* need something here to stop debugger freezing */
+ }
+
+ /*
+ * Change the MSS clock as required.
+ *
+ * CLOCK_CONFIG_CR
+ * [5:0]
+ * Sets the master synchronous clock divider
+ * bits [1:0] CPU clock divider
+ * bits [3:2] AXI clock divider
+ * bits [5:4] AHB/APB clock divider
+ * 00=/1 01=/2 10=/4 11=/8 (AHB/APB divider may not be set to /1)
+ * Reset = 0x3F
+ *
+ * SYSREG->CLOCK_CONFIG_CR = (0x0U<<0U) | (0x1U<<2U) | (0x2U<<4U);
+ * MSS clk= 80Mhz, implies CPU = 80Mhz, AXI = 40Mhz, AHB/APB = 20Mhz
+ * Until we switch in MSS PLL clock (MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = 0x01)
+ * e.g. If MSS clk 800Mhz
+ * MSS clk= 800Mhz, implies CPU = 800Mhz, AXI = 400Mhz, AHB/APB = 200Mhz
+ */
+ SYSREG->CLOCK_CONFIG_CR = LIBERO_SETTING_MSS_CLOCK_CONFIG_CR;
+
+ /*
+ * Feed clock from MSS PLL to MSS, using glitch-less mux
+ *
+ * MSS Clock mux selections
+ * [31:5] Reserved
+ * [4] clk_standby_sel
+ * [3:2] mssclk_mux_md
+ * step 7: 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the
+ * MSS PLL clock.
+ * [1:0] mssclk_mux_sel MSS glitchless mux select
+ * 00 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=clk_standby
+ * 01 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=clk_standby
+ * 10 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=pllout1
+ * 11 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=pllout1
+ *
+ *
+ */
+ MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = LIBERO_SETTING_MSS_MSSCLKMUX;
+
+ /*
+ * Change the RTC clock divisor, so RTC clock is 1MHz
+ */
+ set_RTC_divisor();
+}
+
+/***************************************************************************//**
+ * sgmii_mux_config(uint8_t option)
+ * @param option 1 => soft reset, load RPC settings
+ * 0 => write values using SCB
+ ******************************************************************************/
+void sgmii_mux_config(uint8_t option)
+{
+ switch(option)
+ {
+ default:
+ case SCB_UPDATE: /* write to SCB register */
+
+ /*
+ * SCB address: 0x3E20 0008
+ * MSS Clock mux selections
+ *
+ * [31:0] SGMII_CLKMUX
+ */
+ /* CFM_ETH - 0x3E200000 - - 0x08 */
+ MSS_SCB_CFM_SGMII_MUX->SGMII_CLKMUX =\
+ LIBERO_SETTING_SGMII_SGMII_CLKMUX;
+ /*
+ * SCB address: 0x3E20 0010
+ * Clock_Receiver
+ *
+ * [13] en_rdiff
+ * [12] clkbuf_en_pullup
+ * [11:10] en_rxmode_n
+ * [9:8] en_term_n
+ * [7] en_ins_hyst_n
+ * [6] en_udrive_n
+ * [5:4] en_rxmode_p
+ * [3:2] en_term_p
+ * [1] en_ins_hyst_p
+ * [0] en_udrive_p
+ */
+ MSS_SCB_CFM_SGMII_MUX->CLK_XCVR =\
+ LIBERO_SETTING_SGMII_CLK_XCVR; /* 0x2011 */
+ /*
+ * SCB address: 0x3E20 0004
+ * PLL RF clk mux selections
+ *
+ * [3:2] pll0_rfclk1_sel
+ * 00 => vss
+ * 01 => refclk_p muxed to DDR PLL
+ * and SGMII PLL ( see
+ * 10 => scb_clk
+ * 11 => serdes_refclk_crn_mss<1>
+ * [1:0] pll0_rfclk0_sel
+ * 00 => vss
+ * 01 => refclk_n muxed to DDR PLL
+ * and SGMII PLL
+ * 10 => scb_clk
+ * 11 => serdes_refclk_crn_mss<1>
+ *
+ *
+ */
+ /* 0x05 => ref to SGMII and DDR */
+ MSS_SCB_CFM_SGMII_MUX->RFCKMUX =\
+ LIBERO_SETTING_SGMII_REFCLKMUX;
+ break;
+
+ case RPC_REG_UPDATE:
+ /*
+ * set the NV map reset
+ * This will load the APB registers, set via SGMII TIP.
+ * */
+ MSS_SCB_CFM_SGMII_MUX->SOFT_RESET = 1U;
+ break;
+ }
+}
+
+/***************************************************************************//**
+ *
+ * On startup, MSS supplied with 80MHz SCB clock
+
+ 9.2 Power on procedure for the MSS PLL clock
+
+ During POR:
+ Keep PLL in power down mode. powerdown_int_b=0
+
+ After POR, Power-On steps:
+ 1) mssclk_mux_sel_int<0>=0 & powerdown_int_b=0 & clk_standby_sel=0
+ MSS PLL is powered down and selects clk_standby=scb_clk
+ 2) PFC Processor writes powerdown_int_b=1 & divq0_int_en=1
+ MSS PLL powers up, then lock asserts when locked.
+ 3) PFC Processor switches mssclk_mux_sel_int<0>=1
+ MSS PLL clock is now sent to MSS.
+ 4) When BOOT authentication is complete
+ a. PFC processor writes mssclk_mux_sel_int<0>=0 to select clk_standby.
+ b. PFC Processor writes powerdown_int_b=0 to power down the PLL
+ >>>>>>>> G5 Soc User code >>>>>>>>>>>>>>
+ c. MSS Processor writes new parameters to the MSS PLL
+ 5) MSS Processor writes powerdown_int_b=1
+ Start up the PLL with NEW parameters.
+ Wait for LOCK
+ 6) MSS Processor enables all 4 PLL outputs.
+ 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the MSS PLL
+ clock.
+ *
+ ******************************************************************************/
+void mss_pll_config(void)
+{
+ copy_switch_code(); /* copy switch code to RAM */
+
+ MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+ MSS_SCB_MSS_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+
+ /*
+ Enable the PLL by removing the reset-
+ PERIPH / periph_reset_b - This asserts the functional reset of the
+ block.
+ It is asserted at power up. When written is stays asserted until written
+ to 0.
+ */
+ /*
+ * 4. c. MSS Processor writes new parameters to the MSS PLL
+ */
+ /*
+ * [0] REG_BYPASS_GO_B
+ * [0] BYPCK_SEL
+ * [0] RESETONLOCK
+ * [0] REG_RFCLK_SEL
+ * [0] REG_DIVQ3_EN
+ * [0] REG_DIVQ2_EN
+ * [0] REG_DIVQ1_EN
+ * [0] REG_DIVQ0_EN
+ * [0] REG_RFDIV_EN
+ * [0] REG_POWERDOWN_B
+ */
+
+ MSS_SCB_MSS_PLL->PLL_CTRL = LIBERO_SETTING_MSS_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
+
+ /*
+ * PLL calibration register
+ * This value is factory set, do not overwrite
+ * MSS_SCB_MSS_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
+ *
+ */
+
+ MSS_SCB_MSS_PLL->PLL_REF_FB = LIBERO_SETTING_MSS_PLL_REF_FB;
+
+ MSS_SCB_MSS_PLL->PLL_DIV_0_1 = LIBERO_SETTING_MSS_PLL_DIV_0_1;
+
+ MSS_SCB_MSS_PLL->PLL_DIV_2_3 = LIBERO_SETTING_MSS_PLL_DIV_2_3;
+
+ MSS_SCB_MSS_PLL->PLL_CTRL2 = LIBERO_SETTING_MSS_PLL_CTRL2;
+
+ MSS_SCB_MSS_PLL->PLL_FRACN = LIBERO_SETTING_MSS_PLL_FRACN;
+ MSS_SCB_MSS_PLL->SSCG_REG_0 = LIBERO_SETTING_MSS_SSCG_REG_0;
+ MSS_SCB_MSS_PLL->SSCG_REG_1 = LIBERO_SETTING_MSS_SSCG_REG_1;
+
+ MSS_SCB_MSS_PLL->SSCG_REG_2 = LIBERO_SETTING_MSS_SSCG_REG_2;
+ MSS_SCB_MSS_PLL->SSCG_REG_3 = LIBERO_SETTING_MSS_SSCG_REG_3;
+
+ /* PLL phase registers */
+ MSS_SCB_MSS_PLL->PLL_PHADJ = LIBERO_SETTING_MSS_PLL_PHADJ;
+
+ /*
+ * 5) MSS Processor writes powerdown_int_b=1
+ * Start up the PLL with NEW parameters.
+ Wait for LOCK
+ */
+ mss_mux_pre_mss_pll_config(); /* feed required inputs */
+ /* bit 0 == REG_POWERDOWN_B */
+ MSS_SCB_MSS_PLL->PLL_CTRL = (LIBERO_SETTING_MSS_PLL_CTRL) | 0x01U;
+ /*
+ * Start up the PLL with NEW parameters.
+ * Wait for LOCK
+ * todo: make wait clock based
+ */
+ volatile uint32_t timer_out=0x000000FFU;
+ while((MSS_SCB_MSS_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == 0U)
+ {
+#ifdef RENODE_DEBUG
+ break;
+#endif
+ if (timer_out != 0U)
+ {
+ timer_out--;
+ }
+ else
+ {
+ //todo: add failure mode
+ }
+ }
+
+ /*
+ * 6) MSS Processor enables all 4 PLL outputs.
+ * 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the MSS PLL
+ * clock.
+ */
+ mss_mux_post_mss_pll_config();
+}
+
+/**
+ *
+ * @param option choose between SCB or RPC and soft reset update method.
+ */
+void ddr_pll_config(REG_LOAD_METHOD option)
+{
+
+ switch(option)
+ {
+ default:
+ case SCB_UPDATE: /* write to SCB register */
+ /* PERIPH / periph_reset_b - This asserts the functional reset of
+ * the block. It is asserted at power up. When written is stays
+ * asserted until written to 0.
+ * First set periph_reset_b, than remove reset. As may be called
+ * more than one.
+ * */
+ MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+
+ MSS_SCB_DDR_PLL->PLL_CTRL = LIBERO_SETTING_DDR_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
+ /* PLL calibration register */
+
+ /*
+ * PLL calibration register
+ * This value is factory set, do not overwrite
+ * MSS_SCB_DDR_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
+ *
+ */
+
+ MSS_SCB_DDR_PLL->PLL_REF_FB = LIBERO_SETTING_DDR_PLL_REF_FB;
+
+
+ MSS_SCB_DDR_PLL->PLL_DIV_0_1 = LIBERO_SETTING_DDR_PLL_DIV_0_1;
+
+ MSS_SCB_DDR_PLL->PLL_DIV_2_3 = LIBERO_SETTING_DDR_PLL_DIV_2_3;
+
+
+ MSS_SCB_DDR_PLL->PLL_CTRL2 = LIBERO_SETTING_DDR_PLL_CTRL2;
+
+ MSS_SCB_DDR_PLL->PLL_FRACN = LIBERO_SETTING_DDR_PLL_FRACN;
+ MSS_SCB_DDR_PLL->SSCG_REG_0 = LIBERO_SETTING_DDR_SSCG_REG_0;
+ MSS_SCB_DDR_PLL->SSCG_REG_1 = LIBERO_SETTING_DDR_SSCG_REG_1;
+
+ MSS_SCB_DDR_PLL->SSCG_REG_2 = LIBERO_SETTING_DDR_SSCG_REG_2;
+ MSS_SCB_DDR_PLL->SSCG_REG_3 = LIBERO_SETTING_DDR_SSCG_REG_3;
+
+ /* PLL phase registers */
+
+ MSS_SCB_DDR_PLL->PLL_PHADJ = LIBERO_SETTING_MSS_PLL_PHADJ;
+
+ MSS_SCB_DDR_PLL->PLL_CTRL = (LIBERO_SETTING_DDR_PLL_CTRL)\
+ | 0x01U; /* bit 0 == REG_POWERDOWN_B */
+
+ break;
+
+ case RPC_REG_UPDATE:
+ /* CFG_DDR_SGMII_PHY->SOFT_RESET_MAIN_PLL; */
+ CFG_DDR_SGMII_PHY->PLL_CTRL_MAIN.PLL_CTRL_MAIN =\
+ LIBERO_SETTING_DDR_PLL_CTRL | 0x01U;
+ CFG_DDR_SGMII_PHY->PLL_REF_FB_MAIN.PLL_REF_FB_MAIN =\
+ LIBERO_SETTING_DDR_PLL_REF_FB;
+ /* Read only in RPC
+ * CFG_DDR_SGMII_PHY->PLL_FRACN_MAIN.PLL_FRACN_MAIN =\
+ * LIBERO_SETTING_DDR_PLL_FRACN; */
+ CFG_DDR_SGMII_PHY->PLL_DIV_0_1_MAIN.PLL_DIV_0_1_MAIN =\
+ LIBERO_SETTING_DDR_PLL_DIV_0_1;
+ CFG_DDR_SGMII_PHY->PLL_DIV_2_3_MAIN.PLL_DIV_2_3_MAIN =\
+ LIBERO_SETTING_DDR_PLL_DIV_2_3;
+ CFG_DDR_SGMII_PHY->PLL_CTRL2_MAIN.PLL_CTRL2_MAIN =\
+ LIBERO_SETTING_DDR_PLL_CTRL2;
+ /* Read only in RPC todo: verify this is correct
+ * CFG_DDR_SGMII_PHY->PLL_CAL_MAIN.PLL_CAL_MAIN =\
+ * LIBERO_SETTING_DDR_PLL_CAL; */
+ CFG_DDR_SGMII_PHY->PLL_PHADJ_MAIN.PLL_PHADJ_MAIN =\
+ LIBERO_SETTING_DDR_PLL_PHADJ;
+ /*__I CFG_DDR_SGMII_PHY_SSCG_REG_0_MAIN_TypeDef SSCG_REG_0_MAIN; */
+ /*__I CFG_DDR_SGMII_PHY_SSCG_REG_1_MAIN_TypeDef SSCG_REG_1_MAIN; */
+ CFG_DDR_SGMII_PHY->SSCG_REG_2_MAIN.SSCG_REG_2_MAIN =\
+ LIBERO_SETTING_DDR_SSCG_REG_2;
+ /*__I CFG_DDR_SGMII_PHY_SSCG_REG_3_MAIN_TypeDef SSCG_REG_3_MAIN; */
+ /*
+ * set the NV map reset
+ * This will load the APB registers, set via SGMII TIP.
+ * */
+ /* bit 0 == REG_POWERDOWN_B */
+ MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+ break;
+ }
+}
+
+/**
+ * ddr_pll_lock_scb(void)
+ * checks to see if lock has occurred
+ * @return => lock has occurred, 1=> no lock
+ */
+uint8_t ddr_pll_lock_scb(void)
+{
+ uint8_t result = 1U;
+#ifndef RENODE_DEBUG
+ if((MSS_SCB_DDR_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == PLL_CTRL_LOCK_BIT)
+ {
+ result = 0U; /* PLL lock has occurred */
+ }
+#else
+ result = 0U;
+#endif
+ return (result);
+}
+
+/***************************************************************************//**
+ *
+ ******************************************************************************/
+void ddr_pll_config_scb_turn_off(void)
+{
+ /* PERIPH / periph_reset_b */
+ MSS_SCB_DDR_PLL->PLL_CTRL &= (uint32_t)~0x00000001UL;
+}
+
+
+/***************************************************************************//**
+ * sgmii_pll_config_scb(uint8_t option)
+ * @param option 1 => soft reset, load RPC settings
+ * 0 => write values using SCB
+ ******************************************************************************/
+void sgmii_pll_config_scb(uint8_t option)
+{
+
+ switch(option)
+ {
+ default:
+ case SCB_UPDATE: /* write to SCB register */
+ /* PERIPH / periph_reset_b - This asserts the functional reset of
+ * the block. It is asserted at power up. When written is stays
+ * asserted until written to 0.
+ * First set periph_reset_b, than remove reset. As may be called
+ * more than one.
+ * */
+ MSS_SCB_SGMII_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+
+ MSS_SCB_SGMII_PLL->PLL_CTRL = LIBERO_SETTING_SGMII_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
+ /* PLL calibration register */
+
+ /*
+ * PLL calibration register
+ * This value is factory set, do not overwrite
+ * MSS_SCB_SGMII_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
+ *
+ */
+
+ MSS_SCB_SGMII_PLL->PLL_REF_FB = LIBERO_SETTING_SGMII_PLL_REF_FB;
+
+
+ MSS_SCB_SGMII_PLL->PLL_DIV_0_1 = LIBERO_SETTING_SGMII_PLL_DIV_0_1;
+
+ MSS_SCB_SGMII_PLL->PLL_DIV_2_3 = LIBERO_SETTING_SGMII_PLL_DIV_2_3;
+
+
+ MSS_SCB_SGMII_PLL->PLL_CTRL2 = LIBERO_SETTING_SGMII_PLL_CTRL2;
+
+ MSS_SCB_SGMII_PLL->PLL_FRACN = LIBERO_SETTING_SGMII_PLL_FRACN;
+ MSS_SCB_SGMII_PLL->SSCG_REG_0 = LIBERO_SETTING_SGMII_SSCG_REG_0;
+ MSS_SCB_SGMII_PLL->SSCG_REG_1 = LIBERO_SETTING_SGMII_SSCG_REG_1;
+
+ MSS_SCB_SGMII_PLL->SSCG_REG_2 = LIBERO_SETTING_SGMII_SSCG_REG_2;
+ MSS_SCB_SGMII_PLL->SSCG_REG_3 = LIBERO_SETTING_SGMII_SSCG_REG_3;
+
+ /* PLL phase registers */
+
+ MSS_SCB_SGMII_PLL->PLL_PHADJ = LIBERO_SETTING_SGMII_PLL_PHADJ;
+
+ MSS_SCB_SGMII_PLL->PLL_CTRL = (LIBERO_SETTING_SGMII_PLL_CTRL)\
+ | 0x01U; /* bit 0 == REG_POWERDOWN_B */
+
+ break;
+
+ case RPC_REG_UPDATE:
+ /*
+ * set the NV map reset
+ * This will load the APB registers, set via SGMII TIP.
+ * */
+ /* bit 0 == REG_POWERDOWN_B */
+ MSS_SCB_SGMII_PLL->SOFT_RESET = 0x01U;
+ break;
+ }
+}
+
+/**
+ * sgmii_pll_lock_scb(void)
+ * checks to see if lock has occurred
+ * @return => lock has occurred, 1=> no lock
+ */
+uint8_t sgmii_pll_lock_scb(void)
+{
+ uint8_t result = 1U;
+#ifndef RENODE_DEBUG
+ if((MSS_SCB_SGMII_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == PLL_CTRL_LOCK_BIT)
+ {
+ result = 0U; /* PLL lock has occurred */
+ }
+#else
+ result = 0U;
+#endif
+ return (result);
+}
+
+
+/***************************************************************************//**
+ * Copy switch code routine to RAM.
+ * Copy locations have been defined in the linker script
+ ******************************************************************************/
+__attribute__((weak)) void copy_switch_code(void)
+{
+ uint32_t * sc_lma = &__sc_load;
+ uint32_t * end_sc_vma = &__sc_end;
+ uint32_t * sc_vma = &__sc_start;
+
+ if ( sc_vma != sc_lma )
+ {
+ while ( sc_vma < end_sc_vma )
+ {
+ *sc_vma = *sc_lma;
+ sc_vma++ ; sc_lma++;
+ }
+ }
+}
+
+#endif /* MPFS_HAL_HW_CONFIG */
+#endif
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_pll.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_pll.h
new file mode 100644
index 00000000..3581e6a8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_pll.h
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_pll.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PLL defines
+ *
+ */
+
+/*=========================================================================*//**
+ @page PolarFire SoC MSS Clock Setup
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor subsystem (MSS) has three PLL's, the MSS, DDR
+ and MSS SGMII's.
+ Two CFM IP blocks are used to mux the PLL input and outputs.
+
+ ==============================================================================
+ PLL Inputs
+ ==============================================================================
+ Each of the three PLL's can be configured with the following inputs:
+ - VSS ( default on reset )
+ - external ref clock in SGMII IO Block
+ - SCB Clock (80MHz)
+ - North West corner clock mux structure ICB
+
+ There are two bits associated with setting clk source
+
+ Note on North West corner clock mux structure ICB
+ The Fabric reference clock inputs source come from the clock mux's in the
+ upper left corner (regular FPGA corner) that provided clocks that can be
+ routed in from various places that will include from IOs, from the FPGA
+ fabric, etc.
+
+
+
+ ==============================================================================
+ MSS PLL Outputs
+ ==============================================================================
+ Each PLL has four outputs. These are generally gated through a mux
+ MSS PLL Outputs
+
+ | Output(0-3) | Detail | Mux | Muxed with |
+ | ------------- |:-------------:|:-------------:| -----------:|
+ | msspll_fdr_0 | clk_in_mss | no | - |
+ | msspll_fdr_1 | clk_in_crypto | no | - |
+ | msspll_fdr_2 | clk_in_emmc | glitch-less | SCB clk |
+ | msspll_fdr_3 | clk_in_can | glitch-less | SCB clk |
+
+ ==============================================================================
+ SCB bus timing
+ ==============================================================================
+ When the MSS is using the SCB bus, there is a timing relationship.
+ The defaults should be OK here. In necessary, the timing used by the MSS SCB
+ access is adjusted using the MSS system register TIMER.
+ (SCBCFG_REGS->TIMER.TIMER)
+ - Bits 15:8 Sets how long SCB request is held active after SCB bus granted.
+ - Allows SCB bus master-ship to maintained across multiple SCB access
+ cycles
+ - Bits 7:0 Set the timeout for an SCB access in CPU cycles.
+
+ ==============================================================================
+ eNVM timing
+ ==============================================================================
+ The clk used by the eNVM is adjusted using the following register:
+ SYSREG->ENVM_CR
+ [5:0]
+ Sets the number of AHB cycles used to generate the PNVM clock,.
+ Clock period = (Value+1) * (1000/AHBFREQMHZ)
+ Value must be 1 to 63 (0 defaults to 15)
+ e.g.
+ 11 will generate a 40ns period 25MHz clock if the AHB clock is 250MHz
+ 15 will generate a 40ns period 25MHz clock if the AHB clock is 400MHz
+
+ ==============================================================================
+ MSS clocks at reset
+ ==============================================================================
+ When the MSS comes out of reset, the MSS will be running on the SCB supplied
+ 80MHz clock.
+
+
+
+ ==============================================================================
+ MSS clock setup - Use case one - using external reference from SGMII I/O Blk
+ ==============================================================================
+ Use case one will be used in the majority of cases.
+ This is where the MSS PLL reference clk will be supplied from an external
+ reference through the external ref clock in SGMII IO Block.
+
+
+ scb clk
+ 01=>ext clk ref +
+ +----------+ +--------+ | 0=>SCB
+ crn | | | MSS | | 1=>PLL
+ +--->| | | PLL | | +------+
+ +-----+ scb | | | | +>| |mss
+ | | +---- | | | | mux +-->
+ | ext + p | mux +-->|ref0 0+--->| |clk
+ | clk +--------->| | | | +------+
+ | ref | n vss | | | | 0=>SCB
+ | +---+ ->| | | | 1=>PLL
+ | | | | | | | +------+
+ | | | | | | |scb-| |crypto
+ +-----+ | +----------+ | | | mux +-->
+ | | 1+--->| |clk
+ | 01=>ext clk ref | | +------+
+ | +----------+ | |
+ | crn| | | | +------+
+ | +-->| | | | | |
+ | scb| | | 2+--->| eMMC +
+ | +-->| | | | | |
+ | | mux +-->|ref1 | +------+
+ +----->| | | |
+ vss| | | | +------+
+ +-->| | | | | |
+ | | | 3+--->| CAN +
+ | | | | | |
+ +----------+ +--------+ +------+
+
+ Steps to setup ext clk:
+ 1. The external clock reference is setup- In SGMII setup
+ 2. The input mux is set to take input from ext ref clk
+ 3. MSS PLL clock is setup with required settings
+ 4. PLL is checked until locked
+ 5. MSS PLL output is switched through to MSS ( switch code run from ram )
+ 6. eNVM clcock is changed as required
+ 7. return from RAM routine and continue
+
+ ==============================================================================
+ MSS clock dividers
+ ==============================================================================
+ The three dividers generating the MSS master clocks are controllable via the
+ system register (CLOCK_CONFIG_CR).
+ CPU clock dividers are set in the function mss_mux_post_mss_pll_config(void)
+
+ | Divider | Config bits | Reset | MAX feq. * |
+ | ------------- |:-------------:|:----------:| -----------:|
+ | CPU | 1:0 | 00 | 625 |
+ | AXI | 3:2 | 01 | 312.5 |
+ | AHB/APB | 5:4 | 10 | 156.25 |
+
+ settings = 00=/1, 01=/2, 01=/4, 01=/8
+ * verify MAX feq. setting with particular silicon variant data sheet
+ - The CPU clock must not exceed 625MHz
+ - The AXI clock must not exceed 312.5MHz
+ - The AHB clock must not exceed 156.25MHz
+ - The CPU clock must be greater or equal to the AXI clock
+ - The AHB/APB clocks cannot be divided by 1. Divide by 1 will divide the
+ clock by 2.
+ - The clock divider register may be changed from any value to any value in
+ one go.
+ - When the USB block is in-use the AHB clock must be greater than 66 MHz.
+
+
+ +---------------------+ +-------------+
+ | +----------+ | | |
+ | +--> /1/2/4/8 +-->+--------->| CPU cores |
+ +-----------+ | | +----------+ | | |
+ | | | | | +-------------+
+ | MSS CLK | | | |
+ | | | | | +-------------+
+ | +---------+---+ +---------+ | | dfi_apb_pclk|
+ | | | +->|/4/8/16 +--->+----------> |
+ | | | | +---------+ | | |
+ | | | | | +-------------+
+ +-----------+ | | |
+ | | |
+ | | | +-------------+
+ | | +---------+ | | MSS AXI |
+ | +--> 1/2/4/8 +--->+--------->| Buses and |
+ | | +---------+ | | peripherals |
+ | | | +-------------+
+ | | |
+ | | |
+ | | | +-------------+
+ | | +-------+ | | MSS APB/AHB |
+ | +->| 2/4/8 +----->+--------->| Buses and
+ | +-------+ | | peripherals |
+ +---------------------+ +-------------+
+
+
+ *//*=========================================================================*/
+#ifndef MSS_DDR_SGMII_MSS_PLL_H_
+#define MSS_DDR_SGMII_MSS_PLL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PLL_CTRL_LOCK_BIT ((0x01U) << 25U)
+/*
+ * bit0 1: This when asserted resets all the non-volatile register bits
+ * e.g. RW-P bits, the bit self clears i.e. is similar to a W1P bit
+ * bit1 1: This when asserted resets all the register bits apart from the
+ * non-volatile registers, the bit self clears. i.e. is similar to a
+ * W1P bit
+ */
+#define PLL_INIT_AND_OUT_OF_RESET 0x00000003UL
+
+#define PLL_CTRL_REG_POWERDOWN_B_MASK 0x00000001UL
+
+typedef enum RTC_CLK_SOURCE_
+{
+ SCB_80M_CLOCK = 0x00, /*!< 0 SCB clock source */
+ MSS_PLL_CLOCK = 0x01, /*!< 1 MSS PLL clock source */
+} RTC_CLK_SOURCE;
+
+typedef enum REG_LOAD_METHOD_
+{
+ SCB_UPDATE = 0x00, /*!< 0 SCB direct load */
+ RPC_REG_UPDATE = 0x01, /*!< 1 RPC -> SCB load */
+} REG_LOAD_METHOD;
+
+
+
+/***************************************************************************//**
+ ddr_pll_config() configure DDR PLL
+
+ Example:
+ @code
+
+ ddr_pll_config();
+
+ @endcode
+
+ */
+void ddr_pll_config(REG_LOAD_METHOD option);
+
+/***************************************************************************//**
+ ddr_pll_lock_scb() Checks if PLL locked
+
+ @return
+ 0U if locked
+
+ Example:
+ @code
+ if (ddr_pvt_calibration() == 0U)
+ {
+ PLL is locked
+ }
+ @endcode
+
+ */
+uint8_t ddr_pll_lock_scb(void);
+
+/***************************************************************************//**
+ sgmii_pll_config_scb() configure sgmii PLL
+
+ @param option 1 => soft reset, load RPC settings
+ 0 => write values using SCB
+
+ Example:
+ @code
+
+ sgmii_pll_config_scb(1U);
+
+ @endcode
+
+ */
+void sgmii_pll_config_scb(uint8_t option);
+
+/***************************************************************************//**
+ sgmii_pll_lock_scb() Checks if PLL is locked
+
+ @return
+ 0U if locked
+
+ Example:
+ @code
+ if (ddr_pvt_calibration() == 0U)
+ {
+ PLL is locked
+ }
+ @endcode
+
+ */
+uint8_t sgmii_pll_lock_scb(void);
+
+/***************************************************************************//**
+ ddr_pll_config_scb_turn_off() Puts PLL in reset
+
+ Example:
+ @code
+
+ ddr_pll_config_scb_turn_off();
+
+ @endcode
+
+ */
+void ddr_pll_config_scb_turn_off(void);
+
+/***************************************************************************//**
+ set_RTC_divisor() Sets the RTC divisor based on values from Libero
+ It is assumed the RTC clock is set to 1MHz
+ Example:
+ @code
+
+ set_RTC_divisor();
+
+ @endcode
+
+ */
+void set_RTC_divisor(void);
+
+/***************************************************************************//**
+ sgmii_mux_config_via_scb() configures mux for SGMii
+
+ Example:
+ @code
+
+ sgmii_mux_config_via_scb();
+
+ @endcode
+
+ */
+void sgmii_mux_config_via_scb(uint8_t option);
+
+/***************************************************************************//**
+ pre_configure_sgmii_and_ddr_pll_via_scb()
+
+ @param option 1 => soft reset, load RPC settings
+ 0 => write values using SCB
+
+ Example:
+ @code
+
+ ddr_pvt_calibration(1U);
+
+ @endcode
+
+ */
+void pre_configure_sgmii_and_ddr_pll_via_scb(uint8_t option);
+
+/******************************************************************************
+ * Public Functions - API *
+ ******************************************************************************/
+void mss_pll_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_SGMII_MSS_PLL_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_scb_nwc_regs.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_scb_nwc_regs.h
new file mode 100644
index 00000000..8b908397
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_scb_nwc_regs.h
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_scb_nwc_regs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief SCB registers and associated structures relating to the NWC
+ *
+ */
+
+
+#ifndef MSS_DDR_SGMII_MSS_SCB_NWC_REGS_H_
+#define MSS_DDR_SGMII_MSS_SCB_NWC_REGS_H_
+
+#include "mpfs_hal/mss_hal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __I
+#define __I const volatile
+#endif
+#ifndef __IO
+#define __IO volatile
+#endif
+#ifndef __O
+#define __O volatile
+#endif
+
+/*------------ NWC PLL definition -----------*/
+typedef struct
+{
+ __IO uint32_t SOFT_RESET; /*!< Offset: 0x0 */
+ __IO uint32_t PLL_CTRL; /*!< Offset: 0x4 */
+ __IO uint32_t PLL_REF_FB; /*!< Offset: 0x8 */
+ __IO uint32_t PLL_FRACN; /*!< Offset: 0xc */
+ __IO uint32_t PLL_DIV_0_1; /*!< Offset: 0x10 */
+ __IO uint32_t PLL_DIV_2_3; /*!< Offset: 0x14 */
+ __IO uint32_t PLL_CTRL2; /*!< Offset: 0x18 */
+ __IO uint32_t PLL_CAL; /*!< Offset: 0x1c */
+ __IO uint32_t PLL_PHADJ; /*!< Offset: 0x20 */
+ __IO uint32_t SSCG_REG_0; /*!< Offset: 0x24 */
+ __IO uint32_t SSCG_REG_1; /*!< Offset: 0x28 */
+ __IO uint32_t SSCG_REG_2; /*!< Offset: 0x2c */
+ __IO uint32_t SSCG_REG_3; /*!< Offset: 0x30 */
+} PLL_TypeDef;
+
+/*------------ NWC PLL MUX definition -----------*/
+
+typedef struct
+{
+ __IO uint32_t SOFT_RESET; /*!< Offset: 0x0 */
+ __IO uint32_t BCLKMUX; /*!< Offset: 0x4 */
+ __IO uint32_t PLL_CKMUX; /*!< Offset: 0x8 */
+ __IO uint32_t MSSCLKMUX; /*!< Offset: 0xc */
+ __IO uint32_t SPARE0; /*!< Offset: 0x10 */
+ __IO uint32_t FMETER_ADDR; /*!< Offset: 0x14 */
+ __IO uint32_t FMETER_DATAW; /*!< Offset: 0x18 */
+ __IO uint32_t FMETER_DATAR; /*!< Offset: 0x1c */
+ __IO uint32_t TEST_CTRL; /*!< Offset: 0x20 */
+} IOSCB_CFM_MSS;
+
+typedef struct
+{
+ __IO uint32_t SOFT_RESET; /*!< Offset: 0x0 */
+ __IO uint32_t RFCKMUX; /*!< Offset: 0x4 */
+ __IO uint32_t SGMII_CLKMUX; /*!< Offset: 0x8 */
+ __IO uint32_t SPARE0; /*!< Offset: 0xc */
+ __IO uint32_t CLK_XCVR; /*!< Offset: 0x10 */
+ __IO uint32_t TEST_CTRL; /*!< Offset: 0x14 */
+} IOSCB_CFM_SGMII;
+
+
+typedef struct
+{
+ __IO uint32_t SOFT_RESET_IOCALIB; /*!< Offset: 0x00 */
+ __IO uint32_t IOC_REG0; /*!< Offset: 0x04 */
+ __I uint32_t IOC_REG1; /*!< Offset: 0x08 */
+ __I uint32_t IOC_REG2; /*!< Offset: 0x0c */
+ __I uint32_t IOC_REG3; /*!< Offset: 0x10 */
+ __I uint32_t IOC_REG4; /*!< Offset: 0x14 */
+ __I uint32_t IOC_REG5; /*!< Offset: 0x18 */
+ __IO uint32_t IOC_REG6; /*!< Offset: 0x1c */
+} IOSCB_IO_CALIB_STRUCT;
+
+
+#define MSS_SCB_MSS_PLL_BASE (0x3E001000U) /*!< ( MSS_SCB_MSS_PLL_BASE ) Base Address */
+#define MSS_SCB_DDR_PLL_BASE (0x3E010000U) /*!< ( MSS_SCB_DDR_PLL_BASE ) Base Address */
+#define MSS_SCB_SGMII_PLL_BASE (0x3E080000U) /*!< ( MSS_SCB_SGMII_PLL_BASE ) Base Address */
+
+#define MSS_SCB_MSS_MUX_BASE (0x3E002000U) /*!< ( MSS_SCB_MSS_MUX_BASE ) Base Address */
+#define MSS_SCB_SGMII_MUX_BASE (0x3E200000U) /*!< ( MSS_SCB_SGMII_PLL_BASE ) Base Address */
+
+#define IOSCB_IO_CALIB_SGMII_BASE (0x3E800000U) /*!< ( IOSCB_IO_CALIB_SGMII_BASE ) Base Address */
+#define IOSCB_IO_CALIB_DDR_BASE (0x3E040000U) /*!< ( IOSCB_IO_CALIB_SGMII_BASE ) Base Address */
+
+
+extern PLL_TypeDef * const MSS_SCB_MSS_PLL;
+extern PLL_TypeDef * const MSS_SCB_DDR_PLL;
+extern PLL_TypeDef * const MSS_SCB_SGMII_PLL;
+extern IOSCB_CFM_MSS * const MSS_SCB_CFM_MSS_MUX;
+extern IOSCB_CFM_SGMII * const MSS_SCB_CFM_SGMII_MUX;
+extern IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_SGMII;
+extern IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_DDR;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_SGMII_MSS_SCB_NWC_REGS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_sgmii.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_sgmii.c
new file mode 100644
index 00000000..a84396be
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_sgmii.c
@@ -0,0 +1,657 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_sgmii.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief sgmii related functions
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "simulation.h"
+
+#ifdef MPFS_HAL_HW_CONFIG
+
+static PART_TYPE silicon_variant = PART_NOT_DETERMINED;
+
+/*
+ * local functions
+ */
+static void setup_sgmii_rpc_per_config(void);
+#ifdef SGMII_SUPPORT
+static uint32_t sgmii_channel_setup(void);
+#endif
+
+/*
+ * local variable
+ */
+static uint32_t sro_dll_90_code;
+
+/*
+ * local functions
+ */
+static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold);
+
+/*
+ * extern functions
+ */
+extern void sgmii_mux_config(uint8_t option);
+
+
+uint32_t sgmii_setup(void)
+{
+#ifdef SGMII_SUPPORT
+ /*
+ * Check if any tx/Rx channels enabled
+ */
+ if((LIBERO_SETTING_SGMII_MODE & (TX_RX_CH_EN_MASK<SOFT_RESET_SGMII.SOFT_RESET_SGMII = \
+ (0x01 << 8U) | 1U; /* PERIPH soft reset */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;
+ setup_sgmii_rpc_per_config(); /* load RPC SGMII_MODE register ext */
+
+ /* Enable the Bank controller */
+ /*
+ * Set soft reset on IP to load RPC to SCB regs (dynamic mode)
+ * Bring the sgmii bank controller out of reset =- ioscb_bank_ctrl_sgmii
+ */
+ IOSCB_BANK_CNTL_SGMII->soft_reset = 1U; /* DPC_BITS NV_MAP reset */
+ sgmii_training_state = SGMII_IO_EN;
+ break;
+
+ case SGMII_IO_EN:
+ /*
+ * Check the IO_EN signal here.
+ * This is an output from the bank controller power detector, which are
+ * turned on using MSS_IO_EN
+ */
+ /* aro_ioen_bnk - PVT calibrator IOEN */
+ timer_out++;
+ if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (0x01U<<6U)) != 0U)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_RAMP_TIMER;
+ }
+ break;
+
+ case SGMII_RAMP_TIMER:
+ /*
+ * IO power ramp wait time
+ * After IOEN is received from power detectors DDR and SGMii, extra time
+ * required for voltage to ramp.
+ * This time will come from the user- Dependent on ramp time of power
+ * supply
+ * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
+ *
+ */
+ timer_out++;
+ if(timer_out >= 0xFU)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_IO_SETUP;
+ }
+ break;
+
+ case SGMII_IO_SETUP:
+ /*
+ * fixme- not sure if we should be setting this register
+ * From regmap detail:
+ * bit 8 of MSS_RESET_CR
+ * Asserts a reset the SGMII block containing the MSS reference clock
+ * input.
+ * Warning that setting this bit causes the external reference clock
+ * input to the
+ * MSS PLL to disappear.
+ * It is advisable to use the SGMII channel soft resets in the PHY
+ * instead of this bit.
+ * However if E51 software wants to set this bit, the MSS clock source
+ * should be switched over to the standby source in advance.
+ */
+ SCB_REGS->MSS_RESET_CR.MSS_RESET_CR = 0;
+
+ /*
+ * I ran the sim past the place where we set the nvmap_reset in the
+ * SOFT_RESET_SGMII register and it did not result in any
+ * change from the DLL default bits.
+ * But I traced the 'flashing' signal on one of these regs back to
+ * 'dll0_soft_reset_nv_map' (not 'pll0_soft_reset_periph').
+ * Now the only place I can find 'dll0_soft_reset_nv_map' is in SCB
+ * space...ie 0x3e10_0000 SOFT_RESET register.
+ *
+ */
+ /*
+ * so we have to use scb register to reset as no APB register available
+ * to soft reset the IP
+ * ioscb_dll_sgmii
+ * */
+ IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U); /* reset sgmii DLL */
+
+ /*
+ * I have discovered the problem with the tx channels (soft reset issue)
+ * So we require the:
+ *
+ * sgmiiphy_lane 01 soft-reset register (0x3650_0000) to be written to
+ * with 0x1 (to set the nv_map bit[0] =1 (self clears))
+ * same for sgmiiphy_lane 23 soft-reset register (0x3651_0000).
+ *
+ * This will result in the rpc bits for the Lane controls to get loaded.
+ * Not happening currently.
+ *
+ * The soft_reset_sgmii occurs in the mss_ddr.c line 436, so I suppose
+ * we put the 2 new soft reset writes after that.
+ *
+ */
+ {
+ /* sgmiiphy_lane 01 soft-reset register (0x3650_0000) */
+ SGMIIPHY_LANE01->soft_reset = 0x000000001U;
+ /* sgmiiphy_lane 23 soft-reset register (0x3650_0000) */
+ SGMIIPHY_LANE23->soft_reset = 0x000000001U;
+ }
+
+ /*
+ * Kick-off calibration, by taking calibration IP out of reset
+ */
+ /*
+ * Soft reset
+ */
+ {
+ /* PVT soft reset - APB*/
+ /* reg_pvt_soft_reset_periph */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x01U<< 10U) | (0x7FU<<0U);
+ /* reg_pvt_soft_reset_periph */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x7FU<<0U);
+ /* PVT soft reset - SCB */
+ /* make sure out of reset */
+ IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB = 0x1U;
+ /* make sure out of reset */
+ IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB = 0x0U;
+ }
+ sgmii_training_state = SGMII_WAIT_FOR_CALIB_COMPLETE;
+ break;
+
+ case SGMII_WAIT_FOR_CALIB_COMPLETE:
+ /*
+ * Verify calibration
+ * Bank 5 PVT calibrator can be controlled by MSS firmware through APB
+ * registers to do initial calibration and re-calibration. During startup,
+ * the initial calibration can be started by default when MSS releases SGMII
+ * reset. Re-calibration is enabled by default with reg_pvt_calib_start/lock
+ * bits being set to 1 before startup, and MSS firmware can start
+ * re-calibration after startup by toggling pvt_calib_start/lock bits per
+ * PVT calibrator spec.
+ *
+ */
+ if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (1U << 14U)) == (1U << 14U))
+ {
+ sgmii_training_state = SGMII_ASSERT_CALIB_LOCK;
+ }
+ break;
+
+ case SGMII_ASSERT_CALIB_LOCK:
+ /*
+ * now assert calib lock
+ * calibrated pcode and ncode will be written.
+ * */
+
+ CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT |= 0x40000000UL;
+ IOSCB_IO_CALIB_SGMII->IOC_REG0 |= (0x01U<<14U);
+ sgmii_training_state = SGMII_SET_UP_PLL;
+ break;
+
+ case SGMII_SET_UP_PLL:
+ /*
+ * SGMii Step 3) Wait for PLL and DLL lock
+ * Delay codes generated
+ */
+
+ /* 0U => configure using scb, 1U => NVMAP reset */
+ sgmii_mux_config(RPC_REG_UPDATE);
+ /* 0U => configure using scb, 1U => NVMAP reset */
+ sgmii_pll_config_scb(RPC_REG_UPDATE);
+
+ timer_out=0U;
+ sgmii_training_state = SGMII_WAIT_FOR_MSS_LOCK;
+ break;
+
+ case SGMII_WAIT_FOR_MSS_LOCK:
+ if (CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL & (1U<<7U))
+ {
+ sgmii_training_state = SGMII_WAIT_FOR_DLL_LOCK;
+ }
+ break;
+
+ case SGMII_WAIT_FOR_DLL_LOCK:
+ if (CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL & (1U<<23U))
+ {
+ sgmii_training_state = SGMII_TURN_ON_MACS;
+ }
+ break;
+
+ case SGMII_TURN_ON_MACS:
+ /*
+ * Provide mac clocks
+ * The nw_config register for mac0 (0x2011_0004): I am forcing 'gigabit' and
+ * 'tbi' bits = 11.
+ * The same for Mac1.
+ * This starts up the tx_mac_clocks for the 2 macs.
+ *
+ */
+ /* the mac clocks need to be turned on when setting up the sgmii */
+ (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ GEM_A_LO->network_config |= (0x01U << 10U) | (0x01U << 11U); /* GEM0 */
+ GEM_B_LO->network_config |= (0x01U << 10U) | (0x01U << 11U); /* GEM1 */
+ sgmii_training_state = SGMII_DETERMINE_SILICON_VARIANT;
+ break;
+
+ case SGMII_DETERMINE_SILICON_VARIANT:
+ /*
+ * Determine Silicon variant from generated dll generated sro_dll_90_code
+ */
+ sro_dll_90_code = ((CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL >> 16U) & 0x7FU);
+
+ if(CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & (01U<<31U)) /* bit31 == 1 => post rev B silicon */
+ {
+ silicon_variant = PART_REVC_OR_LATER;
+ set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST, EARLY_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST);
+ }
+ else
+ {
+ /*
+ * SS part expect < 13
+ * typical-typical or FF expect > 13
+ */
+ if(sro_dll_90_code < MIN_DLL_90_CODE_VALUE_INDICATING_TT_PART_REVB) /* SS part */
+ {
+ silicon_variant = SS_PART_REVB;
+ set_early_late_thresholds(LATE_EYE_WIDTH_SS_PART_REVB, EARLY_EYE_WIDTH_SS_PART_REVB);
+ }
+ else
+ {
+ silicon_variant = TT_PART_REVB;
+ set_early_late_thresholds(LATE_TT_PART_REVB, EARLY_TT_PART_REVB);
+ }
+ }
+ sgmii_training_state = SGMII_RESET_CHANNELS;
+ break;
+
+ case SGMII_RESET_CHANNELS:
+ /*
+ * DLL soft reset - Already configured
+ * PVT soft reset - Already configured
+ * Bank controller soft reset - Already configured
+ * CLKMUX soft reset - Already configured
+ * Lane0 soft reset - must be soft reset here
+ * Lane1 soft reset - must be soft reset here
+ *
+ * __IO uint32_t reg_lane0_soft_reset_periph :1; bit 13
+ * __IO uint32_t reg_lane1_soft_reset_periph :1; bit 14
+ */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
+ if(silicon_variant == PART_REVC_OR_LATER)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_WAIT_10MS;
+ }
+ else
+ {
+ sgmii_training_state = SGMII_CHANNELS_UP;
+ }
+ break;
+
+ case SGMII_WAIT_10MS:
+ timer_out++;
+ if(timer_out >= 0xFFFU)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_CHECK_REVC_RESULT;
+ }
+ break;
+
+ case SGMII_CHECK_REVC_RESULT:
+ if ( (CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & ARO_REF_PCODE_MASK) > ARO_REF_PCODE_REVC_THRESHOLD )
+ {
+ /* OK, we are good */
+ sgmii_training_state = SGMII_CHANNELS_UP;
+ }
+ else
+ {
+ /* need to adjust eye values */
+ set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER, EARLY_EYE_WIDTH_PART_REVC_OR_LATER);
+ /*
+ * Now reset the channels
+ */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
+ /* OK, we are good */
+ sgmii_training_state = SGMII_CHANNELS_UP;
+ }
+ break;
+
+ case SGMII_CHANNELS_UP:
+ /*
+ * SGMii Step 4) Monitor the DLL codes for Voltage and Temp variation
+ * MSS E51 software sets the magnitude value of variation to flag.
+ * MSS E51 software can poll this flag.
+ * Re-calibration, if needed, is controlled by E51 software if needed.
+ * ML step 4- This is a monitoring step- to be run constantly in the back
+ * ground
+ */
+ status = SGMII_FINISHED_SETUP;
+ break;
+ } /* end of switch statement */
+
+ return(status);
+}
+#endif
+
+/**
+ * setup_sgmii_rpc_per_config
+ * Configures SGMII RPC TIP registers
+ */
+static void setup_sgmii_rpc_per_config(void)
+{
+ CFG_DDR_SGMII_PHY->SGMII_MODE.SGMII_MODE = (LIBERO_SETTING_SGMII_MODE & ~REG_CDR_MOVE_STEP);
+ CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL = LIBERO_SETTING_CH0_CNTL;
+ CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL = LIBERO_SETTING_CH1_CNTL;
+ CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL = LIBERO_SETTING_RECAL_CNTL;
+ CFG_DDR_SGMII_PHY->CLK_CNTL.CLK_CNTL = LIBERO_SETTING_CLK_CNTL;
+ /* ibuffmx_p and _n rx1, bit 22 and 23 , rx0, bit 20 and 21 */
+ CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL = LIBERO_SETTING_SPARE_CNTL;
+ CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL = LIBERO_SETTING_PLL_CNTL;
+}
+
+/**
+ * SGMII Off mode
+ */
+void sgmii_off_mode(void)
+{
+ /*
+ * do soft reset of SGMII TIP
+ */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = (0x01 << 8U) | 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;
+
+ /*
+ *
+ */
+ setup_sgmii_rpc_per_config();
+
+ /*
+ * Resetting the SCB register only required in already in dynamic mode. If
+ * not reset, IO will not be configured.
+ */
+ IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U); /* reset sgmii */
+
+}
+
+/**
+ *
+ */
+void ddr_pvt_calibration(void)
+{
+ /*
+ * R3.1
+ * PVT calibration
+ * Wait for IOEN from power detectors DDR and SGMII - IO enable signal from
+ * System Control powers on
+ *
+ * From DDR phy SAC spec:
+ * MSS processor releases dce bus to send RPC bits to IO buffer,
+ * setting each to it's programmed mode and then asserts
+ * ioen high at end of this state.
+ *
+ *
+ * Following verification required for MSS IO Calibration (DDRPHY,
+ * SGMII and MSSIO)
+ * Auto-calibration supply ramp time settings
+ * Calibration in reset until ioen_bnk goes high, timer complete
+ * and setup of bits complete
+ * scbclk divider setting (/1)
+ * calibration clkdiv setting
+ * VS bit settings
+ * Initial non-calibrated codes to IOs (functional max codes)
+ * Calibration signal transitions
+ * pvt_calib_status , r in reg DYN_CNTL
+ * reg_calib_reset, w/r in reg IOC_REG6
+ * calib_clkdiv, w/r in reg IOC_REG6
+ * soft_reset_periph_b,
+ * calib_lock, w/r in reg IOC_REG0
+ * calib_start, w/r in reg IOC_REG0
+ * calib_intrpt r in reg
+ * Final calibration codes
+ * Lane latching of codes
+ * IO Glitching
+ */
+ volatile uint32_t timer_out=0U;
+
+ #ifndef RENODE_DEBUG
+ /* sro_ioen_out */
+ while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & (1U<<4U)) == 0U)
+ {
+ timer_out++;
+ /*todo: add a fail break */
+ }
+ #endif
+
+ /*
+ * R3.2 Trigger timer and wait for completion
+ * PVT calibration
+ * After IOEN is received from power detectors DDR and SGMII, extra time
+ * required for voltage to ramp.
+ * This time will come from the user- Dependent on ramp time of power supply
+ * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
+ *
+ */
+ /*todo: implement proper timer- user will supply ramp time */
+ timer_out=0U;
+ while(timer_out < 0xFU)
+ {
+ timer_out++;
+ }
+
+ /*
+ * R3.2 Initiate calibration:
+ *
+ * IOC_REG6
+ * bit 2:1 reg_calib_clkdiv
+ * bit 0 reg_calib_reset
+ *
+ * DDRIO: calib_reset: 1 -> 0
+ * mss_write(0x20007000 + 0x21C,0x00000004);
+ * DDRIO: calib_rst_b: 0 -> 1
+ * mss_write(0x20007000 + 0x220,0x00000000);
+ * SGMII: calib_rst_b: 0 -> 1
+ * mss_write(0x20007000 + 0xC1C,0x00000000);
+ *
+ */
+ /*
+ * Soft reset
+ */
+ /* PVT soft reset - APB*/
+ /* DDRIO: calib_reset: 1 -> 0, clk divider changed - from 2 - to 3 */
+ CFG_DDR_SGMII_PHY->IOC_REG6.IOC_REG6 = 0x00000006U;
+
+ /* PVT soft nv reset - SCB, should load from RPC */
+ IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB = 0x1U; /* make sure reset */
+ IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB = 0x0U; /* make sure reset */
+
+ /*
+ * R3.4 Wait for PVT calibration to complete
+ * Check:
+ * bit 2 sro_calib_status
+ *
+ * The G5 Memory controller needs to see that the IO calibration has
+ * completed before kicking off DDR training.
+ * It uses the calib_status signal as a flag for this.
+ */
+ timer_out=0U;
+ #ifndef RENODE_DEBUG
+ {
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ }
+ #endif
+ /*
+ * now assert calib lock
+ *
+ * */
+ {
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<14U);
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<14U);
+ }
+}
+
+
+/**
+ *
+ */
+void ddr_pvt_recalibration(void)
+{
+ volatile uint32_t timer_out=0U;
+
+ /*
+ * now assert calib start
+ *
+ * */
+ {
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<13U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<13U);
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<13U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<13U);
+ }
+
+ /*
+ * R3.4 Wait for PVT calibration to complete
+ * Check:
+ * bit 2 sro_calib_status
+ *
+ * The G5 Memory controller needs to see that the IO calibration has
+ * completed before kicking off DDR training.
+ * It uses the calib_status signal as a flag for this.
+ */
+ timer_out=0U;
+ #ifndef RENODE_DEBUG
+ {
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ }
+ #endif
+ /*
+ * now assert calib lock
+ *
+ * */
+ {
+#if 0 /*
+ * fixme: this appears to cause wite calibration to fail, investigating
+ */
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<14U);
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<14U);
+#endif
+ }
+}
+
+/**
+ * Set eye thresholds
+ * @param n_late_threshold
+ * @param p_early_threshold
+ */
+static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold)
+{
+ uint32_t n_eye_values;
+ uint32_t p_eye_value;
+
+ /*
+ * Set the N eye width value
+ * bits 31:29 for CH1, bits 28:26 for CH0 in spare control (N eye width value)
+ */
+ n_eye_values = (n_late_threshold << SHIFT_TO_CH0_N_EYE_VALUE);
+ n_eye_values |= (n_late_threshold << SHIFT_TO_CH1_N_EYE_VALUE);
+
+ CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL = (LIBERO_SETTING_SPARE_CNTL & N_EYE_MASK) | n_eye_values;
+
+ /*
+ * Set P values
+ */
+ p_eye_value = (p_early_threshold << SHIFT_TO_REG_RX0_EYEWIDTH);
+ CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL = ((LIBERO_SETTING_CH0_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX0_EN_FLAG_N;
+ CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL = ((LIBERO_SETTING_CH1_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX1_EN_FLAG_N;
+
+}
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_sgmii.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_sgmii.h
new file mode 100644
index 00000000..75b3f80f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/common/nwc/mss_sgmii.h
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_sgmii.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief SGMII defines
+ *
+ */
+
+#ifndef SRC_PLATFORM_MPFS_HAL_NWC_MSS_SGMII_H_
+#define SRC_PLATFORM_MPFS_HAL_NWC_MSS_SGMII_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define REG_RX0_EN_OFFSET (1U<<5U)
+#define REG_RX1_EN_OFFSET (1U<<7U)
+#define TX_RX_CH_EN_MASK 0xFU
+#define TX_RX_CH_EN_OFFSET 0x4U
+#define REG_CDR_MOVE_STEP (1U<<22U) /* delay taps 1 => 3 taps moved, 0 => 2 taps move. */
+ /* 2 taps best for small PPM values, best results observed. */
+
+#define SHIFT_TO_CH0_N_EYE_VALUE 26U /* 26-28 */
+#define SHIFT_TO_CH1_N_EYE_VALUE 29U /* 29-31 */
+#define N_EYE_MASK 0x03FFFFFFUL
+
+#define SHIFT_TO_REG_RX0_EYEWIDTH 21U
+#define REG_RX0_EYEWIDTH_P_MASK (~(0x7U<TEMP0 = (uint32_t)x)
+#define SIM_FEEDBACK1(x) (SYSREG->TEMP1 = (uint32_t)x)
+#else
+#define SIM_FEEDBACK0(x)
+#define SIM_FEEDBACK1(x)
+#endif
+
+#endif /* MSS_DDR_SGMII_SIMULATION_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/mpfs_hal_version.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/mpfs_hal_version.h
new file mode 100644
index 00000000..81ab4259
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/mpfs_hal_version.h
@@ -0,0 +1,50 @@
+#ifndef MPFS_HAL_VERSION_H
+#define MPFS_HAL_VERSION_H
+
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ *
+ */
+
+/*******************************************************************************
+ * @file mpfs_hal_version.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolareFire SoC Hardware Abstraction layer - MPFS HAL version.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MPFS_HAL_VERSION_MAJOR 1
+#define MPFS_HAL_VERSION_MINOR 8
+#define MPFS_HAL_VERSION_PATCH 125
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/mss_hal.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/mss_hal.h
new file mode 100644
index 00000000..86a3f9c5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/mss_hal.h
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_hal.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS HAL include file. This is the file intended for application to
+ * include so that all the other MPFS files are then accessible to it.
+ *
+ */
+
+#ifndef MSS_HAL_H
+#define MSS_HAL_H
+
+#ifndef CONFIG_OPENSBI
+# include // for size_t
+# include // for bool, true, false
+# include
+#ifndef ssize_t
+typedef long ssize_t;
+#endif
+#endif
+
+#include "common/mss_assert.h"
+#include "common/nwc/mss_ddr_defs.h"
+#include "common/nwc/mss_ddr_sgmii_regs.h"
+#include "common/nwc/mss_io_config.h"
+#include "common/nwc/mss_pll.h"
+#include "common/nwc/mss_scb_nwc_regs.h"
+#include "common/nwc/mss_scb_nwc_regs.h"
+/*
+ * mss_sw_config.h may be edited as required and should be located outside the
+ * mpfs_hal folder
+ */
+#include "mpfs_hal_config/mss_sw_config.h"
+/*
+ * The hw_platform.h is included here only. It must be included after
+ * mss_sw_config.h. This allows defines in hw_platform.h be overload from
+ * mss_sw_config.h if necessary.
+ * */
+#include "common/atomic.h"
+#include "common/bits.h"
+#include "common/encoding.h"
+#include "fpga_design_config/fpga_design_config.h"
+#include "common/nwc/mss_ddr.h"
+#include "common/mss_clint.h"
+#include "common/mss_h2f.h"
+#include "common/mss_hart_ints.h"
+#include "common/mss_mpu.h"
+#include "common/mss_pmp.h"
+#include "common/mss_plic.h"
+#include "common/mss_seg.h"
+#include "common/mss_sysreg.h"
+#include "common/mss_util.h"
+#include "common/mss_mtrap.h"
+#include "common/mss_l2_cache.h"
+#include "common/mss_axiswitch.h"
+#include "common/mss_peripherals.h"
+#include "common/nwc/mss_cfm.h"
+#include "common/nwc/mss_ddr.h"
+#include "common/nwc/mss_sgmii.h"
+#include "startup_gcc/system_startup.h"
+#include "common/nwc/mss_ddr_debug.h"
+#ifdef SIMULATION_TEST_FEEDBACK
+#include "nwc/simulation.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_HAL_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/readme.md b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/readme.md
new file mode 100644
index 00000000..f2ad5816
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/readme.md
@@ -0,0 +1,121 @@
+===============================================================================
+# mpfs_hal
+===============================================================================
+
+The PolarFire-SoC MSS HAL provides the initial boot code, interrupt handling,
+and hardware access methods for the MPFS MSS. The terms PolarFire-SoC HAL and
+MPFS HAL are used interchangeably but in the main the term PolarFire-SoC MSS HAL
+is preferred.
+The PolarFire-SoC MSS hal is a combination of C and assembly source code.
+
+The mpfs_hal folder is included in an PolarFire Embedded project under the
+platform directory.
+
+It contains :
+
+* Start-up code executing from reset
+* Interrupt handling support
+* Exception handling support
+* Memory protection configuration, PMP and MPU
+* DDR configuration
+* SGMII configuration
+* MSSIO setup
+
+## Inputs to the mss_hal
+There are two configuration sources.
+
+1. Libero design
+
+ Libero input through header files located in the config/hardware under the
+ platform directory. These files are generated using the PF SoC embedded
+ software configuration generator. It takes an xml file generated in the Libero
+ design flow and produces header files based on the xml content in a suitable
+ form for consumption by the hal.
+
+2. Software configuration
+ Software configuration settings are located in the mpfs_hal_config folder.
+
+
+### Example Project directory structure, showing where mpfs_hal folder sits.
+
+~~~~
+
+ +---------+
+ | project |
+ +----+----+ +---------+ +-----------+
+ +-----+| src |----->|application|
+ +---------+ | +-----------+
+ |
+ | +-----------+
+ +-->|boards |
+ + +----+------+
+ | | +---------------+
+ | +---------+|icicle-kit-es |
+ | +---+-----------+
+ | |
+ | | +---------------+
+ | +->|platform_config|
+ | | +---------------+
+ | |
+ | | +---------------+
+ | |---------|drivers_config |
+ | | +---------------+
+ | |
+ | | +---------------+
+ | |---------|linker |
+ | | +---------------+
+ | |
+ | | +---------------+
+ | |---------|mpfs_hal_config|
+ | | +---------------+
+ | |
+ | |
+ | | +---------------+
+ | +>|soc_config |
+ | | +---+-----------+
+ | | |
+ | | | +---------------+------------------------+
+ | | +->|multiple folders with fpga config for sw|
+ | | +----------------------------------------+
+ | |
+ | |
+ | |
+ | | +---------------+
+ | +>|soc_fpga_design|
+ | +--+------------+
+ | |
+ | | +---------------+
+ | +-->|libero_tcl |
+ | | +---------------+
+ | |
+ | +-----------+ | +---------------+
+ +--+|middleware + +-->|xml |
+ | +-----------+ +---------------+
+ |
+ +
+ | +-----------+
+ +--+|platform |
+ +----+------+
+ | +---------------+
+ +---------+|drivers |
+ | +---------------+
+ |
+ | +---------------+
+ +---------+|hal |
+ | +---------------+
+ |
+ | +---------------+
+ +---------+|mpfs_hal |
+ | +---------------+
+ |
+ | +-------------------------+
+ +---------+|platform_config_reference|
+ | +-------------------------+
+ |
+ | +---------------------+
+ +---------+|soc_config_generator |
+ +---------------------+
+~~~~
+
+Please see the user guide for further details on
+use.
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/mss_entry.S b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/mss_entry.S
new file mode 100644
index 00000000..62caf72a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/mss_entry.S
@@ -0,0 +1,658 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file entry.S
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief entry functions.
+ *
+ */
+
+#include "../common/bits.h"
+#include "../common/encoding.h"
+#include "../common/mss_mtrap.h"
+#include "system_startup_defs.h"
+#include "mpfs_hal_config/mss_sw_config.h"
+
+ .option norvc
+ .section .text.init,"ax", %progbits
+ .globl reset_vector
+ .globl _start
+
+reset_vector:
+_start:
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+ /*
+ * clear the Return Address Stack
+ */
+ call .clear_ras
+ /* Setup trap handler */
+ la a4, trap_vector
+ csrw mtvec, a4 # initalise machine trap vector address
+ /* Make sure that mtvec is updated before continuing */
+ 1:
+ csrr a5, mtvec
+ bne a4, a5, 1b
+ /* Disable and clear all interrupts */
+ li a2, MSTATUS_MIE
+ csrc mstatus, a2 # clear interrupt enable bit
+ csrw mie, zero
+ csrw mip, zero
+ # Init delegation registers, mideleg, medeleg, if a U54
+ # These are not initialised by the hardware and come up in a random state
+ csrr a0, mhartid
+ beqz a0, .skip_e51
+ csrw mideleg, 0
+ csrw medeleg, 0
+.skip_e51:
+ # mscratch must be init to zero- we are not using scratch memory
+ csrw mscratch, zero
+ csrw mcause, zero
+ csrw mepc, zero
+ /*
+ * clear PMP enables
+ */
+ csrw pmpcfg0, zero
+ csrw pmpcfg2, zero
+ /*
+ * clear regs
+ */
+ li x1, 0
+ li x2, 0
+ li x3, 0
+ li x4, 0
+ li x5, 0
+ li x6, 0
+ li x7, 0
+ li x8, 0
+ li x9, 0
+ li x10,0
+ li x11,0
+ li x12,0
+ li x13,0
+ li x14,0
+ li x15,0
+ li x16,0
+ li x17,0
+ li x18,0
+ li x19,0
+ li x20,0
+ li x21,0
+ li x22,0
+ li x23,0
+ li x24,0
+ li x25,0
+ li x26,0
+ li x27,0
+ li x28,0
+ li x29,0
+ li x30,0
+ li x31,0
+
+ # enable FPU and accelerator if present, setting ignored on E51
+ li t0, MSTATUS_FS | MSTATUS_XS
+ csrs mstatus, t0
+
+ # Init floating point control register to zero
+ # skip if e51
+ csrr a0, mhartid
+ beqz a0, .no_float
+#ifdef __riscv_flen
+ fscsr x0
+#endif
+.no_float:
+
+ # make sure XLEN agrees with compilation choice, if not will loop here
+.LxlenCheck:
+ csrr t0, misa
+#if __riscv_xlen == 64
+ bltz t0, .LxlenPass
+#else
+ bgez t0, .LxlenPass
+#endif
+ j .LxlenCheck
+.LxlenPass:
+
+ # initialize global pointer, global data
+ # The __global_pointer is allocated in the linker script. It points to a
+ # location 2k after sdata start as the offsets used in the gp are +/- 2k
+ # See https://www.sifive.com/blog/2017/08/28/all-aboard-part-3-linker-relaxation-in-riscv-toolchain/
+ # see: http://www.rowleydownload.co.uk/arm/documentation/gnu/as/RISC_002dV_002dDirectives.html
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+
+ # get core id
+ csrr a0, mhartid
+ li a1, 0
+ beq a0, a1, .hart0
+ li a1, 1
+ beq a0, a1, .hart1
+ li a1, 2
+ beq a0, a1, .hart2
+ li a1, 3
+ beq a0, a1, .hart3
+ li a1, 4
+ beq a0, a1, .hart4
+
+.hart0:
+ la a4, __stack_bottom_h0$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h0$
+ j .continue
+.hart1:
+ la a4, __stack_bottom_h1$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h1$
+ j .continue
+.hart2:
+ la a4, __stack_bottom_h2$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h2$
+ j .continue
+.hart3:
+ la a4, __stack_bottom_h3$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h3$
+ j .continue
+.hart4:
+ la a4, __stack_bottom_h4$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h4$
+
+.continue:
+ # clear HLS and stack
+ mv a5, sp
+.init_stack:
+ #csrw mepc, zero
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, .init_stack
+ # Allocate some space at top of stack for the HLS
+ addi sp, sp, -HLS_DEBUG_AREA_SIZE
+ # HLS grows up from new top of stack
+ mv tp, sp
+ # get core id
+ csrr a0, mhartid
+ li a1, MPFS_HAL_FIRST_HART
+ bne a0, a1, .LOtherHartstoWFI
+ # clear the common heap
+ la a4, __heap_start
+ la a5, __heap_end
+.init_heap:
+ #csrw mepc, zero
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, .init_heap
+ #
+ # clear DTIM - this is required to stop memory errors on initial access by
+ # cache
+ # Also, stops x propagation in simulation, when cache/stack reads unused
+ # area
+ #
+ li a2, MPFS_HAL_CLEAR_MEMORY
+ beq x0, a2, .skip_mem_clear
+ call .clear_dtim
+ call .clear_l2lim
+.skip_mem_clear:
+ /*
+ * Clear bus error unit accrued register on start-up
+ * This is cleared by the first hart only
+ */
+ la a4,0x01700020UL
+ sb x0, 0(a4)
+ la a4,0x01701020UL
+ sb x0, 0(a4)
+ la a4,0x01702020UL
+ sb x0, 0(a4)
+ la a4,0x01703020UL
+ sb x0, 0(a4)
+ la a4,0x01704020UL
+ sb x0, 0(a4)
+ # now core MPFS_HAL_FIRST_HART jumps to main_first_hart
+.main_hart:
+ # pass HLS address
+ mv a0, tp
+ j main_first_hart
+.LoopForeverMain:
+ #in case of return, loop forever. nop's added so can be seen in debugger
+ nop
+ nop
+ j .LoopForeverMain
+
+.LOtherHartstoWFI:
+ li a2, MSTATUS_MIE
+ csrc mstatus, a2 # clear interrupt enable bit
+ csrw mie, zero
+ csrw mip, zero
+ li a2, MIP_MSIP
+ csrw mie, a2 # Set MSIE bit to receive IPI. This needs to be
+ # enabled- otherwise stays in wfi.
+ # Other interrupts appera to bring out of wfi,even if
+ # not enabled.
+ #
+ # Wait here until main hart is up and running
+ #
+ li a3, HLS_MAIN_HART_STARTED
+ la a1, (__stack_top_h0$ - HLS_DEBUG_AREA_SIZE)
+.wait_main_hart:
+ LWU a2, 0(a1)
+ bne a3, a2, .wait_main_hart
+ # Flag we are here to the main hart
+ li a1, HLS_OTHER_HART_IN_WFI
+ sw a1, 0(tp)
+ /* flush the instruction cache */
+ fence.i
+.LwaitOtherHart:
+ # We assume wfi instruction will be run before main hart attampts to take
+ # out of wfi
+ wfi
+ # Only start if MIP_MSIP is set - the wfi will ensure this, but adding
+ # breakpoints in the debugger (halt)
+ # will wakeup wfi, so the following code will make sure we remain here until
+ # we get a software interrupt
+ csrr a2, mip
+ andi a2, a2, MIP_MSIP
+ beqz a2, .LwaitOtherHart
+ /* Disable and clear all interrupts- should be only a sw interrupt */
+ li a2, MSTATUS_MIE
+ csrc mstatus, a2 # clear interrupt enable bit
+ csrw mie, zero
+ csrw mip, zero
+ # set marker as to where we are
+ li a1, HLS_OTHER_HART_PASSED_WFI
+ sw a1, 0(tp)
+ # pass HLS address
+ mv a0, tp
+ j main_other_hart
+.LoopForeverOther:
+ #in case of return, loop forever. nop's added so can be seen in debugger
+ nop
+ nop
+ j .LoopForeverOther
+
+#else /* IMAGE_LOADED_BY_BOOTLOADER == 1 */
+
+/***********************************************************************************
+ *The program has been loaded by a bootloader
+ * a0 - contains the hart ID
+ * a1 - contains pointer to bootloader -Hart Local Storage, for this hart.
+ */
+_start_non_bootloader_image:
+ /* ebreak called at the start of the program if required when debuging. */
+ /* DEBUG_EBREAK_AT_START is set to one in the debug build, 0 in the */
+ /* release build */
+ /* uncomment the 3 lines below if you want to use this method to for */
+ /* debugging */
+ /* li a2, DEBUG_EBREAK_AT_START
+ beq x0, a2, 1f
+ ebreak */
+1:
+ /* store the value here received from boot-loader */
+ /* a0 will always contain the hart ID */
+ /* If a1 is null, boot-loader is not passing pointer to the HLS */
+ /* If this is the case, point HLS to out own and fill with hart ID */
+ /* Setup trap handler */
+ /* we are currently only supporting mmode */
+ /* m-mode/s-mode set-up option will be added here */
+ la a4, trap_vector
+ csrw mtvec, a4 # initalise machine trap vector address
+ /* Make sure that mtvec is updated before continuing */
+2:
+ csrr a5, mtvec
+ bne a4, a5, 2b
+ /* Disable and clear all interrupts */
+ /* assumption is this has been done by the Boot-loader */
+ # Init delegation registers, mideleg, medeleg, if a U54
+ # These are not initialised by the hardware and come up in a random state
+ # mhartid is in a0
+ beqz a0, 3f
+ csrw mideleg, 0
+ csrw medeleg, 0
+3:
+ # mscratch must be init to zero- we are not using scratch memory
+ csrw mscratch, zero
+ csrw mcause, zero
+ csrw mepc, zero
+
+ # Init floating point control register to zero
+ # skip if e51
+ # mhartid is in a0
+ beqz a0, 1f
+#ifdef __riscv_flen
+ fscsr x0
+#endif
+1: # no float
+ # make sure XLEN agrees with compilation choice, if not will loop here
+ csrr t0, misa
+#if __riscv_xlen == 64
+ bltz t0, 2f
+#else
+ bgez t0, 2f
+#endif
+ j 1b
+2:
+ # initialize global pointer, global data
+ # The __global_pointer is allocated in the linker script. It points to a
+ # location 2k after sdata start as the offsets used in the gp are +/- 2k
+ # See https://www.sifive.com/blog/2017/08/28/all-aboard-part-3-linker-relaxation-in-riscv-toolchain/
+ # see: http://www.rowleydownload.co.uk/arm/documentation/gnu/as/RISC_002dV_002dDirectives.html
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+
+ la a4, __app_stack_bottom # keep bottom of stack in a5 so we can init later
+ la a5, __app_stack_top
+ la sp, __app_stack_top
+1:
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, 1b
+ # clear the common heap
+ la a4, __heap_start
+ la a5, __heap_end
+2:
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, 2b
+ # check if HLS passed by BL, if not allocate one here
+ bnez a1, 1f
+ # Allocate some space at top of stack for the HLS, as HLS mem not passed
+ addi sp, sp, -HLS_DEBUG_AREA_SIZE
+ # HLS grows up from new top of stack
+ mv tp, sp
+ mv a0, tp
+ j u54_single_hart
+1:
+ # pass HLS address from the boot-loader
+ mv a0, a1
+ j u54_single_hart
+2:
+ # in case of return, loop forever. nop's added so can be seen in debugger
+ nop
+ nop
+ j 2b
+#endif /* IMAGE_LOADED_BY_BOOTLOADER */
+
+/******************************************************************************/
+/******************************interrupt handeling below here******************/
+/******************************************************************************/
+
+trap_vector:
+ # The mscratch register is an XLEN-bit read/write register dedicated for use by machine mode.
+ # Typically, it is used to hold a pointer to a machine-mode hart-local context space and swapped
+ # with a user register upon entry to an M-mode trap handler.
+ # In this implementation, we are noty using HLS
+ # csrrw sp, mscratch, sp #copy sp to mscratch, and mscrath to sp
+
+ addi sp, sp, -INTEGER_CONTEXT_SIZE # moves sp down stack to make I
+ # INTEGER_CONTEXT_SIZE area
+ # Preserve the registers.
+ STORE sp, 2*REGBYTES(sp) # sp
+ STORE a0, 10*REGBYTES(sp) # save a0,a1 in the created CONTEXT
+ STORE a1, 11*REGBYTES(sp)
+ STORE ra, 1*REGBYTES(sp)
+ STORE gp, 3*REGBYTES(sp)
+ STORE tp, 4*REGBYTES(sp)
+ STORE t0, 5*REGBYTES(sp)
+ STORE t1, 6*REGBYTES(sp)
+ STORE t2, 7*REGBYTES(sp)
+ STORE s0, 8*REGBYTES(sp)
+ STORE s1, 9*REGBYTES(sp)
+ STORE a2,12*REGBYTES(sp)
+ STORE a3,13*REGBYTES(sp)
+ STORE a4,14*REGBYTES(sp)
+ STORE a5,15*REGBYTES(sp)
+ STORE a6,16*REGBYTES(sp)
+ STORE a7,17*REGBYTES(sp)
+ STORE s2,18*REGBYTES(sp)
+ STORE s3,19*REGBYTES(sp)
+ STORE s4,20*REGBYTES(sp)
+ STORE s5,21*REGBYTES(sp)
+ STORE s6,22*REGBYTES(sp)
+ STORE s7,23*REGBYTES(sp)
+ STORE s8,24*REGBYTES(sp)
+ STORE s9,25*REGBYTES(sp)
+ STORE s10,26*REGBYTES(sp)
+ STORE s11,27*REGBYTES(sp)
+ STORE t3,28*REGBYTES(sp)
+ STORE t4,29*REGBYTES(sp)
+ STORE t5,30*REGBYTES(sp)
+ STORE t6,31*REGBYTES(sp)
+ # Invoke the handler.
+ mv a0, sp # a0 <- regs
+ # Please note: mtval is the newer name for register mbadaddr
+ # If you get a compile failure here, use the newer name
+ # At this point (2019), both are supported in latest compiler
+ # older compiler versions only support mbadaddr, so going with this.
+ # See: https://github.com/riscv/riscv-gcc/issues/133
+ csrr a1, mbadaddr # useful for anaysis when things go wrong
+ csrr a2, mepc
+ jal trap_from_machine_mode
+
+restore_regs:
+ # Restore all of the registers.
+ LOAD ra, 1*REGBYTES(sp)
+ LOAD gp, 3*REGBYTES(sp)
+ LOAD tp, 4*REGBYTES(sp)
+ LOAD t0, 5*REGBYTES(sp)
+ LOAD t1, 6*REGBYTES(sp)
+ LOAD t2, 7*REGBYTES(sp)
+ LOAD s0, 8*REGBYTES(sp)
+ LOAD s1, 9*REGBYTES(sp)
+ LOAD a0,10*REGBYTES(sp)
+ LOAD a1,11*REGBYTES(sp)
+ LOAD a2,12*REGBYTES(sp)
+ LOAD a3,13*REGBYTES(sp)
+ LOAD a4,14*REGBYTES(sp)
+ LOAD a5,15*REGBYTES(sp)
+ LOAD a6,16*REGBYTES(sp)
+ LOAD a7,17*REGBYTES(sp)
+ LOAD s2,18*REGBYTES(sp)
+ LOAD s3,19*REGBYTES(sp)
+ LOAD s4,20*REGBYTES(sp)
+ LOAD s5,21*REGBYTES(sp)
+ LOAD s6,22*REGBYTES(sp)
+ LOAD s7,23*REGBYTES(sp)
+ LOAD s8,24*REGBYTES(sp)
+ LOAD s9,25*REGBYTES(sp)
+ LOAD s10,26*REGBYTES(sp)
+ LOAD s11,27*REGBYTES(sp)
+ LOAD t3,28*REGBYTES(sp)
+ LOAD t4,29*REGBYTES(sp)
+ LOAD t5,30*REGBYTES(sp)
+ LOAD t6,31*REGBYTES(sp)
+ LOAD sp, 2*REGBYTES(sp)
+ addi sp, sp, +INTEGER_CONTEXT_SIZE # moves sp up stack to reclaim
+ # INTEGER_CONTEXT_SIZE area
+ mret
+
+ /*****************************************************************************/
+ /******************************interrupt handeling above here*****************/
+ /*****************************************************************************/
+
+.enable_sw_int:
+ li a2, MIP_MSIP
+ csrw mie, a2 # Set MSIE bit to receive IPI
+ li a2, MSTATUS_MIE
+ csrs mstatus, a2 # enable interrupts
+ /* flush the instruction cache */
+ fence.i
+ ret
+
+ /***********************************************************************************
+ *
+ * The following init_memory() symbol overrides the weak symbol in the HAL and does
+ * a safe copy of RW data and clears zero-init memory
+ *
+ */
+ // zero_section helper function:
+ // a0 = exec_start_addr
+ // a1 = exec_end_addr
+ //
+ .globl zero_section
+ .type zero_section, @function
+zero_section:
+ bge a0, a1, .zero_section_done
+ sd zero, (a0)
+ addi a0, a0, 8
+ j zero_section
+.zero_section_done:
+ ret
+
+ // zero_section helper function:
+ // a0 = exec_start_addr
+ // a1 = exec_end_addr
+ // a2 = start count
+ //
+ .globl count_section
+ .type count_section, @function
+count_section:
+ beq a0, a1, .count_section_done
+ sd a2, (a0)
+ addi a0, a0, 8
+ addi a2, a2, 8
+ j count_section
+.count_section_done:
+ ret
+
+ // copy_section helper function:
+ // a0 = load_addr
+ // a1 = exec_start_addr
+ // a2 = exec_end_addr
+ .globl copy_section
+ .type copy_section, @function
+copy_section:
+ beq a1, a0, .copy_section_done // if load_addr == exec_start_addr, goto copy_section_done
+.check_if_copy_section_done:
+ beq a1, a2, .copy_section_done // if offset != length, goto keep_copying
+.keep_copying:
+ ld a3, 0(a0) // val = *load_addr
+ sd a3, 0(a1) // *exec_start_addr = val;
+ addi a0, a0, 8 // load_addr = load_addr + 8
+ addi a1, a1, 8 // exec_start_addr = exec_start_addr + 8
+ j .check_if_copy_section_done
+.copy_section_done:
+ ret
+
+
+/***********************************************************************************
+ *
+ * The following copy_switch_code() symbol overrides the weak symbol in the HAL and does
+ * a safe copy of HW config data
+ */
+ .globl copy_switch_code
+ .type copy_switch_code, @function
+copy_switch_code:
+ la a5, __sc_start // a5 = __sc_start
+ la a4, __sc_load // a4 = __sc_load
+ beq a5,a4,.copy_switch_code_done // if a5 == a4, goto copy_switch_code_done
+ la a3, __sc_end // a3 = __sc_end
+ beq a5,a3,.copy_switch_code_done // if a5 == a3, goto copy_switch_code_done
+.copy_switch_code_loop:
+ lw a2,0(a4) // a2 = *a4
+ sw a2,0(a5) // *a5 = a2
+ addi a5,a5,4 // a5+=4
+ addi a4,a4,4 // a4+=4
+
+ bltu a5,a3,.copy_switch_code_loop // if a5 < a3, goto copy_switch_code_loop
+.copy_switch_code_done:
+ ret
+
+/*******************************************************************************
+ *
+ */
+#define START__OF_LIM 0x08000000
+#define END__OF_LIM 0x08200000
+#define START__OF_DTM 0x01000000
+#define END__OF_DTM 0x01002000
+
+
+.clear_l2lim:
+ // Clear the LIM
+ //
+ // On reset, the first 15 ways are L2 and the last way is cache
+ // We can initialize all, as cache write through to DDR is blocked
+ // until DDR in initialized, so will have no effect other than clear ECC
+ //
+ // NOTE: we need to check if we are debugging from LIM,if so do not
+ // initialize.
+ //
+ la a2, _start
+ la a4, 0x08000000 # start of LIM address
+ and a2, a2, a4
+ bnez a2, .done_clear
+ la a5, 0x08200000 # end of LIM address
+ j 1f
+.clear_dtim:
+ //
+ // Clear the E51 DTIM to prevent any ECC memory errors on initial access
+ //
+ la a4, 0x01000000 # DTIM start
+ la a5, 0x01002000 # DTIM end
+1:
+ // common loop used by both .clear_l2lim and .clear_dtim
+ sd x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, 1b
+.done_clear:
+ ret
+
+/*
+ * record_ecc_error_counts on reset
+ * These are non-zero in the coreplex.
+ * Can be checked later on to see if values have changed
+ * a0 = mECCDataFailCount save address
+ a1 = mECCDataCorrectionCount save address
+ a2 = mECCDirFixCount save address
+ */
+.record_ecc_error_counts:
+ # Store initial ECC errors
+ #define mECCDataFailCount 0x02010168U
+ la a5, mECCDataFailCount
+ mv a4, a0// eg. Use stat of DTIM in not used for anything else 0x01000100
+ lw t2,0(a5)
+ sw t2,0(a4)
+ #define mECCDataCorrectionCount 0x02010148U
+ la a5, mECCDataCorrectionCount
+ mv a4, a1// eg. Use stat of DTIM in not used for anything else 0x01000110
+ lw t2,0(a5)
+ sw t2,0(a4)
+ #define mECCDirFixCount 0x02010108u
+ la a5, mECCDirFixCount
+ mv a4, a2// eg. Use stat of DTIM in not used for anything else 0x01000120
+ lw t2,0(a5)
+ sw t2,0(a4)
+ ret
+
+/*
+ * clear_ras , clear_ras_2_deep
+ * Two deep function calls.
+ * Used to clear the interal processor Return Address Stack
+ * This is belt and braces, may not be required
+ */
+.clear_ras:
+ mv a5, x1
+ nop
+ call .clear_ras_2_deep
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ mv x1, a5
+ ret
+
+.clear_ras_2_deep:
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ ret
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/mss_utils.S b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/mss_utils.S
new file mode 100644
index 00000000..482d4b61
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/mss_utils.S
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright 2021 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_utils.S
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief utilities used by mpfs-hal startup code
+ *
+ */
+ .section .text.init,"ax", %progbits
+ .align 3
+
+/***********************************************************************************
+ *
+ * pdma_transfer
+ * Only used by the mpfs hal. App code uses the provided driver.
+ *
+ * a0 = dest
+ * a1 = src
+ * a2 = length
+ * a3 = PDMA Base Address - 0x3000000 + (0x01000 * PDMA_CHANNEL)
+ */
+ .globl pdma_transfer
+ .type pdma_transfer, @function
+pdma_transfer:
+ mv t1,a0
+ mv t0, a3 // Base address
+ li t1, 1
+ sw t1, 0(t0) // claim
+ li t1, 0
+ sw t1, 4(t0) // read[31:28]/write[27:24] size 0=>1byte, 1 =>2 bytes etx
+ mv t1, a2 // SIZE
+ sd t1, 8(t0) // bytes
+ mv t1, a0 // dest address
+ sd t1, 16(t0) // dest
+ mv t1, a1 // source address
+ sd t1, 24(t0) // src
+ li t1, 0xff000000
+ sw t1, 4(t0) // full speed copy
+ li t1, 3
+ sw t1, 0(t0) // start transfer
+ fence
+ ret
+
+/***********************************************************************************
+ *
+ * pdma_transfer_complete
+ * Loops until transfer complete
+ * Only used by the mpfs hal. App code uses the provided driver.
+ *
+ * a0 = PDMA Base Address - 0x3000000 + (0x01000 * PDMA_CHANNEL)
+ */
+ //
+ .globl pdma_transfer_complete
+ .type pdma_transfer_complete, @function
+pdma_transfer_complete:
+ mv t0, a0 // Base address
+1: // wait for completion
+ lw t1, 0(t0)
+ andi t1, t1, 2
+ bnez t1, 1b
+ // release DMA
+ sw zero, 0(t0)
+ ret
+
+
+ /***********************************************************************************
+ *
+ * memfill() - fills memory, alternate to lib function when not available
+ */
+ // memfill helper function:
+ // a0 = dest
+ // a1 = value to fill
+ // a2 = length
+ .globl memfill
+ .type memfill, @function
+memfill:
+ mv t1,a0
+ mv t2,a1
+ beqz a2,2f
+1:
+ sb t2,0(t1)
+ addi a2,a2,-1
+ addi t1,t1,1
+ bnez a2,1b
+2:
+ ret
+
+/***********************************************************************************
+ *
+ * The following config_copy() symbol overrides the weak symbol in the HAL and does
+ * a safe copy of HW config data
+ */
+ // config_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_copy
+ .type config_copy, @function
+config_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ lb t2,0(a1)
+ sb t2,0(t1)
+ addi a2,a2,-1
+ addi t1,t1,1
+ addi a1,a1,1
+ bnez a2,1b
+2:
+ ret
+
+ /***********************************************************************************
+ *
+ * config_16_copy () Copies a word at a time, used when copying to contigous registers
+ */
+ // config_16_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_16_copy
+ .type config_16_copy, @function
+config_16_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ lh t2,0(a1)
+ sh t2,0(t1)
+ addi a2,a2,-2
+ addi t1,t1,2
+ addi a1,a1,2
+ bnez a2,1b
+2:
+ ret
+
+/***********************************************************************************
+ *
+ * config_32_copy () Copies a word at a time, used when copying to contigous registers
+ */
+ // config_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_32_copy
+ .type config_32_copy, @function
+config_32_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ lw t2,0(a1)
+ sw t2,0(t1)
+ addi a2,a2,-4
+ addi t1,t1,4
+ addi a1,a1,4
+ bnez a2,1b
+2:
+ ret
+
+ /***********************************************************************************
+ *
+ * config_64_copy - copying using 64 bit loads, addresses must be on 64 bit boundary
+ */
+ // config_64_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_64_copy
+ .type config_64_copy, @function
+config_64_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ ld t2,0(a1)
+ sd t2,0(t1)
+ addi a2,a2,-8
+ addi t1,t1,8
+ addi a1,a1,8
+ bnez a2,1b
+2:
+ ret
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/newlib_stubs.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/newlib_stubs.c
new file mode 100644
index 00000000..0ed8513d
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/newlib_stubs.c
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file newlib_stubs.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Stubs for Newlib system calls.
+ *
+ */
+#include
+#include
+#include
+#include
+#include
+#include "../mss_hal.h"
+
+/*==============================================================================
+ * Redirection of standard output to a SmartFusion2 MSS UART.
+ *------------------------------------------------------------------------------
+ * A default implementation for the redirection of the output of printf() to a
+ * UART is provided at the bottom of this file. This redirection is enabled by
+ * adding the symbol/define MICROCHIP_STDIO_THRU_MMUART0 or
+ * MICROCHIP_STDIO_THRU_MMUART0 to your project settings and specifying the baud
+ * rate using the MICROCHIP_STDIO_BAUD_RATE define.
+ */
+#ifdef MICROCHIP_STDIO_THRU_MMUART0
+#ifndef MICROCHIP_STDIO_THRU_UART
+#define MICROCHIP_STDIO_THRU_UART
+#endif
+#endif /* MICROCHIP_STDIO_THRU_MMUART0 */
+
+#ifdef MICROCHIP_STDIO_THRU_MMUART1
+#ifndef MICROCHIP_STDIO_THRU_UART
+#define MICROCHIP_STDIO_THRU_UART
+#endif
+#endif /* MICROCHIP_STDIO_THRU_MMUART1 */
+
+/*
+ * Select which MMUART will be used for stdio and what baud rate will be used.
+ * Default to 57600 baud if no baud rate is specified using the
+ * MICROCHIP_STDIO_BAUD_RATE #define.
+ */
+#ifdef MICROCHIP_STDIO_THRU_UART
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+#ifndef MICROCHIP_STDIO_BAUD_RATE
+#define MICROCHIP_STDIO_BAUD_RATE MSS_UART_115200_BAUD
+#endif
+
+#ifdef MICROCHIP_STDIO_THRU_MMUART0
+static mss_uart_instance_t * const gp_my_uart = &g_mss_uart0;
+#else
+static mss_uart_instance_t * const gp_my_uart = &g_mss_uart1;
+#endif
+
+/*------------------------------------------------------------------------------
+ * Global flag used to indicate if the UART driver needs to be initialized.
+ */
+static int g_stdio_uart_init_done = 0;
+
+#endif /* MICROCHIP_STDIO_THRU_UART */
+
+/*==============================================================================
+ * Environment variables.
+ * A pointer to a list of environment variables and their values. For a minimal
+ * environment, this empty list is adequate:
+ */
+char *__env[1] = { 0 };
+char **environ = __env;
+
+
+/*==============================================================================
+ * Close a file.
+ */
+int _close(int file);
+int _close(int file)
+{
+ (void)file;
+ return -1;
+}
+
+/*==============================================================================
+ * Transfer control to a new process.
+ */
+int _execve(char *name, char **argv, char **env);
+int _execve(char *name, char **argv, char **env)
+{
+ (void)name;
+ (void)argv;
+ (void)env;
+ errno = ENOMEM;
+ return -1;
+}
+
+/*==============================================================================
+ * Exit a program without cleaning up files.
+ */
+void _exit( int code )
+{
+ (void)code;
+ /* Should we force a system reset? */
+ while( 1 )
+ {
+ ;
+ }
+}
+
+/*==============================================================================
+ * Create a new process.
+ */
+int _fork(void);
+int _fork(void)
+{
+ errno = EAGAIN;
+ return -1;
+}
+
+/*==============================================================================
+ * Status of an open file.
+ */
+int _fstat(int file, struct stat *st);
+int _fstat(int file, struct stat *st)
+{
+ (void)file;
+ st->st_mode = S_IFCHR;
+ return (0);
+}
+
+/*==============================================================================
+ * Process-ID
+ */
+int _getpid(void);
+int _getpid(void)
+{
+ return (1);
+}
+
+/*==============================================================================
+ * Query whether output stream is a terminal.
+ */
+int _isatty(int file);
+int _isatty(int file)
+{
+ (void)file;
+ return (1);
+}
+
+/*==============================================================================
+ * Send a signal.
+ */
+int _kill(int pid, int sig);
+int _kill(int pid, int sig)
+{
+ (void)pid;
+ (void)sig;
+ errno = EINVAL;
+ return (-1);
+}
+
+/*==============================================================================
+ * Establish a new name for an existing file.
+ */
+int _link(char *old, char *new);
+int _link(char *old, char *new)
+{
+ (void)old;
+ (void)new;
+ errno = EMLINK;
+ return (-1);
+}
+
+/*==============================================================================
+ * Set position in a file.
+ */
+int _lseek(int file, int ptr, int dir);
+int _lseek(int file, int ptr, int dir)
+{
+ (void)file;
+ (void)ptr;
+ (void)dir;
+ return (0);
+}
+
+/*==============================================================================
+ * Open a file.
+ */
+int _open(const char *name, int flags, int mode);
+int _open(const char *name, int flags, int mode)
+{
+ (void)name;
+ (void)flags;
+ (void)mode;
+ return (-1);
+}
+
+/*==============================================================================
+ * Read from a file.
+ */
+int _read(int file, char *ptr, int len);
+int _read(int file, char *ptr, int len)
+{
+ (void)file;
+ (void)ptr;
+ (void)len;
+ return (0);
+}
+
+/*==============================================================================
+ * Write to a file. libc subroutines will use this system routine for output to
+ * all files, including stdout so if you need to generate any output, for
+ * example to a serial port for debugging, you should make your minimal write
+ * capable of doing this.
+ */
+int _write_r( void * reent, int file, char * ptr, int len );
+int _write_r( void * reent, int file, char * ptr, int len )
+{
+ (void)reent;
+ (void)file;
+ (void)ptr;
+ (void)len;
+#ifdef MICROCHIP_STDIO_THRU_UART
+ /*--------------------------------------------------------------------------
+ * Initialize the UART driver if it is the first time this function is
+ * called.
+ */
+ if(!g_stdio_uart_init_done)
+ {
+ MSS_UART_init(gp_my_uart,
+ MICROCHIP_STDIO_BAUD_RATE,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY);
+
+ g_stdio_uart_init_done = 1;
+ }
+
+ /*--------------------------------------------------------------------------
+ * Output text to the UART.
+ */
+ MSS_UART_polled_tx(gp_my_uart, (uint8_t *)ptr, len);
+
+ return len;
+#else /* MICROCHIP_STDIO_THRU_UART */
+ return (0);
+#endif /* MICROCHIP_STDIO_THRU_UART */
+}
+
+/*==============================================================================
+ * Increase program data space. As malloc and related functions depend on this,
+ * it is useful to have a working implementation. The following suffices for a
+ * standalone system; it exploits the symbol _end automatically defined by the
+ * GNU linker.
+ */
+caddr_t _sbrk(int incr);
+caddr_t _sbrk(int incr)
+{
+ extern char _end; /* Defined by the linker */
+ extern char __heap_start;
+ extern char __heap_end;
+ static char *heap_end;
+ char *prev_heap_end;
+
+ (void)__heap_start;
+ (void)__heap_end;
+#ifdef DEBUG_HEAP_SIZE
+ char * stack_ptr = NULL;
+#endif
+
+ /*
+ * Did we allocated memory for the heap in the linker script?
+ * You need to set HEAP_SIZE to a non-zero value in your linker script if
+ * the following assertion fires.
+ */
+ ASSERT(&__heap_end > &__heap_start);
+
+ if (heap_end == NULL)
+ {
+ heap_end = &_end;
+ }
+
+ prev_heap_end = heap_end;
+
+#ifdef DEBUG_HEAP_SIZE /* add this define if you want to debug crash due to overflow of heap */
+ /* fixme- this test needs to be reworked to take account of multiple harts and TLS */
+ stack_ptr = read_csr(sp);
+ /* stack_ptr has just been placed on the stack, so its address in currently pointing to the stack end */
+ if(heap_end < stack_ptr)
+ {
+ /*
+ * Heap is at an address below the stack, growing up toward the stack.
+ * The stack is above the heap, growing down towards the heap.
+ * Make sure the stack and heap do not run into each other.
+ */
+ if (heap_end + incr > stack_ptr)
+ {
+ _write_r ((void *)0, 1, "Heap and stack collision\n", 25);
+ _exit (1);
+ }
+ }
+ else
+ {
+ /*
+ * If the heap and stack are not growing towards each other then use the
+ * _eheap linker script symbol to figure out if there is room left on
+ * the heap.
+ * Please note that this use case makes sense when the stack is located
+ * in internal eSRAM in the 0x20000000 address range and the heap is
+ * located in the external memory in the 0xA0000000 memory range.
+ * Please note that external memory should not be accessed using the
+ * 0x00000000 memory range to read/write variables/data because of the
+ * SmartFusion2 cache design.
+ */
+ extern char _heap_end; /* Defined by the linker */
+ char *top_of_heap;
+
+ top_of_heap = &_heap_end;
+ if(heap_end + incr > top_of_heap)
+ {
+ _write_r ((void *)0, 1, "Out of heap memory\n", 25);
+ _exit (1);
+ }
+ }
+#endif
+ heap_end += incr;
+
+ /*
+ * Did we run out of heap?
+ * You need to increase the heap size in the linker script if the following
+ * assertion fires.
+ * */
+ ASSERT(heap_end <= &__heap_end);
+
+ return ((caddr_t) prev_heap_end);
+}
+
+/*==============================================================================
+ * Status of a file (by name).
+ */
+int _stat(char *file, struct stat *st);
+int _stat(char *file, struct stat *st)
+{
+ (void)file;
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+/*==============================================================================
+ * Timing information for current process.
+ */
+int _times(struct tms *buf);
+int _times(struct tms *buf)
+{
+ (void)buf;
+ return (-1);
+}
+
+/*==============================================================================
+ * Remove a file's directory entry.
+ */
+int _unlink(char *name);
+int _unlink(char *name)
+{
+ (void)name;
+ errno = ENOENT;
+ return (-1);
+}
+
+/*==============================================================================
+ * Wait for a child process.
+ */
+int _wait(int *status);
+int _wait(int *status)
+{
+ (void)status;
+ errno = ECHILD;
+ return (-1);
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup.c b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup.c
new file mode 100644
index 00000000..7656c489
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup.c
@@ -0,0 +1,585 @@
+/******************************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+/***************************************************************************
+ * @file system_startup.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief first C code called on startup. Will call user code created outside
+ * the HAL.
+ */
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#ifdef MPFS_HAL_HW_CONFIG
+#include "../common/nwc/mss_nwc_init.h"
+#include "system_startup_defs.h"
+#endif
+
+
+/*==============================================================================
+ * This function is called by the lowest enabled hart (MPFS_HAL_FIRST_HART) in
+ * the configuration file (platform/config/software/mpfs_hal/mss_sw_config.h )
+ *
+ * The other harts up to MPFS_HAL_LAST_HART are placed in wfi at this point.
+ * This function brings them out of wfi in sequence.
+ * If you need to modify this function, create your own one in a user directory
+ * space
+ * e.g. /hart0/e51.c
+ */
+__attribute__((weak)) int main_first_hart(HLS_DATA* hls)
+{
+ uint64_t hartid = read_csr(mhartid);
+
+ if(hartid == MPFS_HAL_FIRST_HART)
+ {
+ uint8_t hart_id;
+ ptrdiff_t stack_top;
+
+ /*
+ * We only use code within the conditional compile
+ * #ifdef MPFS_HAL_HW_CONFIG
+ * if this program is used as part of the initial board bring-up
+ * Please comment/uncomment MPFS_HAL_HW_CONFIG define in
+ * platform/config/software/mpfs_hal/sw_config.h
+ * as required.
+ */
+#ifdef MPFS_HAL_HW_CONFIG
+ config_l2_cache();
+#endif /* MPFS_HAL_HW_CONFIG */
+
+ init_memory();
+#ifndef MPFS_HAL_HW_CONFIG
+ hls->my_hart_id = MPFS_HAL_FIRST_HART;
+#endif
+#ifdef MPFS_HAL_HW_CONFIG
+ load_virtual_rom();
+ (void)init_bus_error_unit();
+ (void)init_mem_protection_unit();
+ (void)init_pmp((uint8_t)MPFS_HAL_FIRST_HART);
+ (void)mss_set_apb_bus_cr((uint32_t)LIBERO_SETTING_APBBUS_CR);
+#endif /* MPFS_HAL_HW_CONFIG */
+ /*
+ * Initialise NWC
+ * Clocks
+ * SGMII
+ * DDR
+ * IOMUX
+ */
+#ifdef MPFS_HAL_HW_CONFIG
+ (void)mss_nwc_init();
+
+ /* main hart init's the PLIC */
+ PLIC_init_on_reset();
+ /*
+ * Start the other harts. They are put in wfi in entry.S
+ * When debugging, harts are released from reset separately,
+ * so we need to make sure hart is in wfi before we try and release.
+ */
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h0$);
+ hls = (HLS_DATA*)(stack_top - HLS_DEBUG_AREA_SIZE);
+ hls->in_wfi_indicator = HLS_MAIN_HART_STARTED;
+ hls->my_hart_id = MPFS_HAL_FIRST_HART;
+ WFI_SM sm_check_thread = INIT_THREAD_PR;
+ hart_id = MPFS_HAL_FIRST_HART + 1U;
+ while( hart_id <= MPFS_HAL_LAST_HART)
+ {
+ uint32_t wait_count = 0U;
+
+ switch(sm_check_thread)
+ {
+ default:
+ case INIT_THREAD_PR:
+
+ switch (hart_id)
+ {
+ case 1:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h1$);
+ break;
+ case 2:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h2$);
+ break;
+ case 3:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h3$);
+ break;
+ case 4:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h4$);
+ break;
+ }
+ hls = (HLS_DATA*)(stack_top - HLS_DEBUG_AREA_SIZE);
+ sm_check_thread = CHECK_WFI;
+ wait_count = 0U;
+ break;
+
+ case CHECK_WFI:
+ if( hls->in_wfi_indicator == HLS_OTHER_HART_IN_WFI )
+ {
+ /* Separate state- to add a little delay */
+ sm_check_thread = SEND_WFI;
+ }
+ break;
+
+ case SEND_WFI:
+ hls->my_hart_id = hart_id; /* record hartid locally */
+ raise_soft_interrupt(hart_id);
+ sm_check_thread = CHECK_WAKE;
+ wait_count = 0UL;
+ break;
+
+ case CHECK_WAKE:
+ if( hls->in_wfi_indicator == HLS_OTHER_HART_PASSED_WFI )
+ {
+ sm_check_thread = INIT_THREAD_PR;
+ hart_id++;
+ wait_count = 0UL;
+ }
+ else
+ {
+ wait_count++;
+ if(wait_count > 0x10U)
+ {
+ if( hls->in_wfi_indicator == HLS_OTHER_HART_IN_WFI )
+ {
+ hls->my_hart_id = hart_id; /* record hartid locally */
+ raise_soft_interrupt(hart_id);
+ wait_count = 0UL;
+ }
+ }
+ }
+ break;
+ }
+ }
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h0$);
+ hls = (HLS_DATA*)(stack_top - HLS_DEBUG_AREA_SIZE);
+ hls->in_wfi_indicator = HLS_MAIN_HART_FIN_INIT;
+
+ /*
+ * Turn on fic interfaces by default. Drivers will turn on/off other MSS
+ * peripherals as required.
+ */
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC0, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC1, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC2, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC3, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+
+#endif /* MPFS_HAL_HW_CONFIG */
+ (void)main_other_hart(hls);
+ }
+
+ /* should never get here */
+ while(true)
+ {
+ static volatile uint64_t counter = 0U;
+ /* Added some code as debugger hangs if in loop doing nothing */
+ counter = counter + 1U;
+ }
+
+ return (0);
+}
+
+/*==============================================================================
+ * u54_single_hart startup.
+ * This is called when a bootloader has loaded a single hart program.
+ * A pointer to the hart Local Storage (HLS) is passed here which has been
+ * passed by the boot program in the a1 register.
+ * The HLS contains the hartID.
+ * It also contains a pointer to shared memory
+ * Information on the HLS used in the bare metal examples.
+ * The HLS is a small amount of memory dedicated to each hart.
+ * The HLS also contains a pointer to shared memory.
+ * The shared memory is accessible by all harts if used. It is
+ * allocated by the boot-loader if the MPFS_HAL_SHARED_MEM_ENABLED
+ * is defined in the mss_sw_config.h file project configuration file.
+ * Please see the project mpfs-hal-run-from-ddr-u54-1 located in the Bare Metal
+ * library under examples/mpfs-hal for an example of it use.
+ *
+ * https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
+ *
+ * If you need to modify this function, create your own one in a user directory
+ * space
+ * e.g. /hart1/x.c
+ */
+__attribute__((weak)) int u54_single_hart(HLS_DATA* hls)
+{
+ init_memory();
+ hls->my_hart_id = MPFS_HAL_FIRST_HART;
+#ifdef MPFS_HAL_SHARED_MEM_ENABLED
+ /* if shared memory enabled, pointer from Boot-loader in the HLS should be
+ * non-zero */
+ ASSERT(hls->shared_mem != NULL);
+#endif
+ switch(hls->my_hart_id)
+ {
+ case 0U:
+ e51();
+ break;
+
+ case 1U:
+ u54_1();
+ break;
+
+ case 2U:
+ u54_2();
+ break;
+
+ case 3U:
+ u54_3();
+ break;
+
+ case 4U:
+ u54_4();
+ break;
+
+ default:
+ /* no more harts */
+ break;
+ }
+
+ /* should never get here */
+ while(true)
+ {
+ static volatile uint64_t counter = 0U;
+ /* Added some code as debugger hangs if in loop doing nothing */
+ counter = counter + 1U;
+ }
+
+ return (0);
+}
+
+/*==============================================================================
+ * U54s startup.
+ * This is called from entry.S
+ * If you need to modify this function, create your own one in a user directory
+ * space.
+ *
+ * Please note: harts MPFS_HAL_FIRST_FIRST + 1 to MPFS_HAL_FIRST_LAST will wait
+ * in startup code in entry.S as they run the wfi (wait for interrupt)
+ * instruction.
+ * They are woken up as required by the the MPFS_HAL_FIRST_HART, in the function
+ * main_first_hart().
+ * ( It triggers a software interrupt on the particular hart to be woken up )
+ */
+__attribute__((weak)) int main_other_hart(HLS_DATA* hls)
+{
+#ifdef MPFS_HAL_HW_CONFIG
+ extern char __app_stack_top_h0;
+ extern char __app_stack_top_h1;
+ extern char __app_stack_top_h2;
+ extern char __app_stack_top_h3;
+ extern char __app_stack_top_h4;
+
+ const uint64_t app_stack_top_h0 = (const uint64_t)&__app_stack_top_h0 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h1 = (const uint64_t)&__app_stack_top_h1 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h2 = (const uint64_t)&__app_stack_top_h2 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h3 = (const uint64_t)&__app_stack_top_h3 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h4 = (const uint64_t)&__app_stack_top_h4 - (HLS_DEBUG_AREA_SIZE);
+
+#ifdef MPFS_HAL_HW_CONFIG
+#ifdef MPFS_HAL_SHARED_MEM_ENABLED
+ /*
+ * If we are a boot-loader, and shared memory enabled (MPFS_HAL_SHARED_MEM_ENABLED)
+ * sets the pointer in each harts HLS to the shared memory.
+ * This allows access to this shared memory across all harts.
+ */
+ const uint64_t app_hart_common_start = (const uint64_t)&__app_hart_common_start;
+ hls->shared_mem = (uint64_t *)app_hart_common_start;
+ hls->shared_mem_marker = SHARED_MEM_INITALISED_MARKER;
+ hls->shared_mem_status = SHARED_MEM_DEFAULT_STATUS;
+#endif
+#else
+#ifdef MPFS_HAL_SHARED_MEM_ENABLED
+ /* make sure each harts Harts Local Storage has pointer to common memory if enabled */
+ /* store the value here received from boot-loader */
+ /* a1 will contain pointer to the start of shared memory */
+ //hls->shared_mem = (uint64_t *)__uninit_bottom$;
+#else
+ /*
+ * We are not using shared memory
+ */
+ hls->shared_mem = (uint64_t *)NULL;
+#endif
+#endif
+
+ volatile uint64_t dummy;
+
+ switch(hls->my_hart_id)
+ {
+
+ case 0U:
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h0));
+ e51();
+ break;
+
+ case 1U:
+ (void)init_pmp((uint8_t)1);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h1));
+ u54_1();
+ break;
+
+ case 2U:
+ (void)init_pmp((uint8_t)2);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h2));
+ u54_2();
+ break;
+
+ case 3U:
+ (void)init_pmp((uint8_t)3);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h3));
+ u54_3();
+ break;
+
+ case 4U:
+ (void)init_pmp((uint8_t)4);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h4));
+ u54_4();
+ break;
+
+ default:
+ /* no more harts */
+ break;
+ }
+
+ /* should never get here */
+ while(true)
+ {
+ static volatile uint64_t counter = 0U;
+ /* Added some code as debugger hangs if in loop doing nothing */
+ counter = counter + 1U;
+ }
+#endif
+ return (0);
+
+}
+
+/*==============================================================================
+ * Load the virtual ROM located at address 0x20003120 within the SCB system
+ * registers with an executable allowing to park a hart in an infinite loop.
+ */
+#ifdef MPFS_HAL_HW_CONFIG
+#define VIRTUAL_BOOTROM_BASE_ADDR 0x20003120UL
+#define NB_BOOT_ROM_WORDS 8U
+const uint32_t rom[NB_BOOT_ROM_WORDS] =
+{
+ 0x00000513U, /* li a0, 0 */
+ 0x34451073U, /* csrw mip, a0 */
+ 0x10500073U, /* wfi */
+ 0xFF5FF06FU, /* j 0x20003120 */
+ 0xFF1FF06FU, /* j 0x20003120 */
+ 0xFEDFF06FU, /* j 0x20003120 */
+ 0xFE9FF06FU, /* j 0x20003120 */
+ 0xFE5FF06FU /* j 0x20003120 */
+};
+
+void load_virtual_rom(void)
+{
+ volatile uint32_t * p_virtual_bootrom = (uint32_t *)VIRTUAL_BOOTROM_BASE_ADDR;
+ config_copy( (void *)p_virtual_bootrom, (void *)rom,sizeof(rom[NB_BOOT_ROM_WORDS]));
+}
+#endif /* MPFS_HAL_HW_CONFIG */
+
+/*==============================================================================
+ * Put the hart executing this code into an infinite loop executing from the
+ * SCB system register memory space.
+ * This allows preventing a hart from accessing memory regardless of memory
+ * hierarchy configuration or compiler/linker settings.
+ * This function relies on load_virtual_rom() having been called previously to
+ * populate the virtual ROM with a suitable executable.
+ */
+static void park_hart(void)
+{
+ clear_csr(mstatus, MSTATUS_MIE);
+ __asm volatile("fence.i");
+ __asm volatile("li ra,0x20003120");
+ __asm volatile("ret");
+}
+
+/*==============================================================================
+ * E51 code executing after system startup.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void e51(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+/*==============================================================================
+ * First U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_1(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+
+/*==============================================================================
+ * Second U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_2(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+/*==============================================================================
+ * Third U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_3(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+/*==============================================================================
+ * Fourth U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_4(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+ /*-----------------------------------------------------------------------------
+ * _start() function called invoked
+ * This function is called on power up and warm reset.
+ */
+ __attribute__((weak)) void init_memory( void)
+ {
+ copy_section(&__text_load, &__text_start, &__text_end);
+ copy_section(&__sdata_load, &__sdata_start, &__sdata_end);
+ copy_section(&__data_load, &__data_start, &__data_end);
+
+ zero_section(&__sbss_start, &__sbss_end);
+ zero_section(&__bss_start, &__bss_end);
+
+ __disable_all_irqs(); /* disables local and global interrupt enable */
+ }
+
+ /*-----------------------------------------------------------------------------
+ * _start() function called invoked
+ * This function is called on power up and warm reset.
+ */
+ __attribute__((weak)) void init_ddr(void)
+ {
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK) != DDR_OFF_MODE) {
+#ifdef DDR_SUPPORT
+ uint64_t end_address;
+
+#if 0 /* enable to init cache to zero using 64 bit writes */
+ end_address = LIBERO_SETTING_DDR_64_NON_CACHE + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0 + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1;
+ zero_section((uint64_t *)LIBERO_SETTING_DDR_64_NON_CACHE, (uint64_t *)end_address);
+#endif
+
+ end_address = LIBERO_SETTING_DDR_64_CACHE + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_0 + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_1;
+ zero_section((uint64_t *)LIBERO_SETTING_DDR_64_CACHE, (uint64_t *)end_address);
+#endif
+ }
+ }
+
+ /**
+ * This function is configured by editing parameters in
+ * mss_sw_config.h as required.
+ * @return
+ */
+
+__attribute__((weak)) uint8_t init_bus_error_unit(void)
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ uint8_t hart_id;
+ /* Init BEU in all harts - enable local interrupt */
+ for(hart_id = MPFS_HAL_FIRST_HART; hart_id <= MPFS_HAL_LAST_HART; hart_id++)
+ {
+ BEU->regs[hart_id].ENABLE = (uint64_t)BEU_ENABLE;
+ BEU->regs[hart_id].PLIC_INT = (uint64_t)BEU_PLIC_INT;
+ BEU->regs[hart_id].LOCAL_INT = (uint64_t)BEU_LOCAL_INT;
+ BEU->regs[hart_id].CAUSE = 0ULL;
+ BEU->regs[hart_id].ACCRUED = 0ULL;
+ BEU->regs[hart_id].VALUE = 0ULL;
+ }
+#endif
+ return (0U);
+}
+
+/**
+ * init_mem_protection_unit(void)
+ * add this function to you code and configure as required
+ * @return
+ */
+__attribute__((weak)) uint8_t init_mem_protection_unit(void)
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ mpu_configure();
+#endif
+ return (0U);
+}
+
+/**
+ * init_pmp(void)
+ * add this function to you code and configure as required
+ * @return
+ */
+__attribute__((weak)) uint8_t init_pmp(uint8_t hart_id)
+{
+ pmp_configure(hart_id);
+ return (0U);
+}
+
+/**
+ * set_apb_bus_cr(void)
+ * todo: add check to see if value valid re. mss configurator
+ * @return
+ */
+__attribute__((weak)) uint8_t mss_set_apb_bus_cr(uint32_t reg_value)
+{
+ SYSREG->APBBUS_CR = reg_value;
+ return (0U);
+}
+
+/**
+ * get_apb_bus_cr(void)
+ * @return
+ */
+__attribute__((weak)) uint8_t mss_get_apb_bus_cr(void)
+{
+ return (SYSREG->APBBUS_CR);
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup.h
new file mode 100644
index 00000000..3c962166
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup.h
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+*/
+
+/******************************************************************************
+ * @file system_startup.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Macros and APIs for the system_startup.c
+ */
+
+#ifndef SYSTEM_STARTUP_H
+#define SYSTEM_STARTUP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum WFI_SM_
+{
+ INIT_THREAD_PR = 0x00, /*!< 0 init pointer */
+ CHECK_WFI = 0x01, /*!< is hart in wfi? */
+ SEND_WFI = 0x02, /*!< separate state to
+ add a little delay*/
+ CHECK_WAKE = 0x03, /*!< has hart left wfi*/
+} WFI_SM;
+
+/*------------------------------------------------------------------------------
+ * Markers used to indicate startup status of hart
+ */
+#ifndef HLS_DATA_IN_WFI
+#define HLS_DATA_IN_WFI 0x12345678U
+#endif
+#ifndef HLS_DATA_PASSED_WFI
+#define HLS_DATA_PASSED_WFI 0x87654321U
+#endif
+
+#ifndef SHARED_MEM_INITALISED_MARKER
+#define SHARED_MEM_INITALISED_MARKER 0xA1A2A3A4UL
+#endif
+#ifndef SHARED_MEM_DEFAULT_STATUS
+#define SHARED_MEM_DEFAULT_STATUS 0x00000000UL
+#endif
+
+typedef struct HLS_DATA_
+{
+ volatile uint32_t in_wfi_indicator;
+ volatile uint32_t my_hart_id;
+ volatile uint32_t shared_mem_marker;
+ volatile uint32_t shared_mem_status;
+ volatile uint64_t * shared_mem;
+} HLS_DATA;
+
+/*------------------------------------------------------------------------------
+ * Symbols from the linker script used to locate the text, data and bss sections.
+ */
+extern unsigned long __stack_top_h0$;
+extern unsigned long __stack_bottom_h0$;
+extern unsigned long __stack_top_h1$;
+extern unsigned long __stack_bottom_h1$;
+extern unsigned long __stack_top_h2$;
+extern unsigned long __stack_bottom_h2$;
+extern unsigned long __stack_top_h3$;
+extern unsigned long __stack_bottom_h3$;
+extern unsigned long __stack_top_h4$;
+extern unsigned long __stack_bottom_h4$;
+extern unsigned long __app_hart_common_start;
+extern unsigned long __app_hart_common_end;
+
+extern unsigned long __data_load;
+extern unsigned long __data_start;
+extern unsigned long __data_end;
+
+extern unsigned long __sbss_start;
+extern unsigned long __sbss_end;
+
+extern unsigned long __bss_start;
+extern unsigned long __bss_end;
+
+extern unsigned long __sdata_load;
+extern unsigned long __sdata_start;
+extern unsigned long __sdata_end;
+
+extern unsigned long __text_load;
+extern unsigned long __text_start;
+extern unsigned long __text_end;
+
+extern unsigned long __l2lim_end;
+
+extern unsigned long __e51itim_start;
+extern unsigned long __e51itim_end;
+
+extern unsigned long __u54_1_itim_start;
+extern unsigned long __u54_1_itim_end;
+
+extern unsigned long __u54_2_itim_start;
+extern unsigned long __u54_2_itim_end;
+
+extern unsigned long __u54_3_itim_start;
+extern unsigned long __u54_3_itim_end;
+
+extern unsigned long __u54_4_itim_start;
+extern unsigned long __u54_4_itim_end;
+
+#ifndef MPFS_HAL_HW_CONFIG
+extern unsigned long __uninit_bottom$;
+extern unsigned long __uninit_top$;
+#endif
+
+/*
+ * Function Declarations
+ */
+int main_first_hart(HLS_DATA* hls);
+int main_other_hart(HLS_DATA* hls);
+void e51(void);
+void u54_1(void);
+void u54_2(void);
+void u54_3(void);
+void u54_4(void);
+void init_memory( void);
+void init_ddr( void);
+uint8_t init_mem_protection_unit(void);
+uint8_t init_pmp(uint8_t hart_id);
+uint8_t init_bus_error_unit( void);
+uint8_t mss_set_apb_bus_cr(uint32_t reg_value);
+uint8_t mss_get_apb_bus_cr(void);
+char * memfill(void *dest, const void * src, size_t len);
+char * config_copy(void *dest, const void * src, size_t len);
+char * config_16_copy(void *dest, const void * src, size_t len);
+char * config_32_copy(void *dest, const void * src, size_t len);
+char * config_64_copy(void *dest, const void * src, size_t len);
+
+void copy_section
+(
+ uint64_t * p_load,
+ uint64_t * p_vma,
+ uint64_t * p_vma_end
+);
+void zero_section
+(
+ uint64_t *__sbss_start,
+ uint64_t * __sbss_end
+);
+void load_virtual_rom(void);
+
+void count_section
+(
+ uint64_t * start_address,
+ uint64_t * end_address,
+ uint64_t * start_value
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_STARTUP_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup_defs.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup_defs.h
new file mode 100644
index 00000000..586c5b97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/mpfs_hal/startup_gcc/system_startup_defs.h
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+*/
+
+/******************************************************************************
+ * @file system_startup_defs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Defines for the system_startup_defs.c
+ */
+
+#ifndef SYSTEM_STARTUP_DEFS_H
+#define SYSTEM_STARTUP_DESF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ * Markers used to indicate startup status of hart
+ */
+#define HLS_MAIN_HART_STARTED 0x12344321U
+#define HLS_MAIN_HART_FIN_INIT 0x55555555U
+#define HLS_OTHER_HART_IN_WFI 0x12345678U
+#define HLS_OTHER_HART_PASSED_WFI 0x87654321U
+
+/*------------------------------------------------------------------------------
+ * Define the size of the HLS used
+ * In our HAL, we are using Hart Local storage for debug data storage only
+ * as well as flags for wfi instruction management.
+ * The TLS will take memory from top of the stack if allocated
+ *
+ */
+#if !defined (HLS_DEBUG_AREA_SIZE)
+#define HLS_DEBUG_AREA_SIZE 64
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_STARTUP_DESF_H */
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld
new file mode 100644
index 00000000..45c143ed
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-ddr-loaded-by-boot-loader.ld
+ * Use this linker script when the program is fully located in DDR. The
+ * assumption is DDR has already been initialized by another program.
+ *
+ * This linker script can be used with a debugger or when compiled and loaded
+ * by a boot-loader.
+ * The loading program passes two parameters in a0 and a1
+ * a0 - The hartid is passed here
+ * a1 - A pointer to Hart Local Storage (HLS) is passed here
+ * The HLS is a small amount of memory dedicated to each hart.
+ * The HLS also contains a pointer to shared memory.
+ * The shared memory is accessible by all harts if used. It is
+ * allocated by the boot-loader if the MPFS_HAL_SHARED_MEM_ENABLED
+ * is defined in the mss_sw_config.h file project configuration file.
+ * Please see the project mpfs-hal-run-from-ddr-u54-1 located in the Bare Metal
+ * library under examples/mpfs-hal for an example of it use.
+ *
+ * https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+HEAP_SIZE = 0k; /* needs to be calculated for your application if using */
+
+/*
+ * Stack size for our single hart U54 application.
+ */
+STACK_SIZE_U54_APPLICATION = 8k;
+
+/*
+ * A small amount of unitialised memory used to store information
+ * obtained from the boot-loader on start-up
+ */
+UNITITALISED_MEM = 16B;
+
+/* reset address 0xC0000000 */
+SECTION_START_ADDRESS = 0x80000000;
+
+
+SECTIONS
+{
+
+ /* text: test code section */
+ . = SECTION_START_ADDRESS;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > ddr_cached_32bit
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > ddr_cached_32bit
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > ddr_cached_32bit
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > ddr_cached_32bit
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__app_stack_bottom = .);
+ . += STACK_SIZE_U54_APPLICATION;
+ PROVIDE(__app_stack_top = .);
+ } > ddr_cached_32bit
+
+ /*
+ * used by a program loaded by a bootloader to store information passed
+ * from boot-loader
+ * a0 holds the hart ID
+ * a1 hold pointer to device data, which includes pointer to shared memory
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .no_init : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ . += UNITITALISED_MEM;
+ PROVIDE(__uninit_top_h$ = .);
+ } > ddr_cached_32bit
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..b98f7342
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-envm-lma-scratchpad-vma.ld
+ * Code starts from eNVM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * STACK_SIZE_xxx_STARTUP
+ * Stack size for each hart's startup code.
+ * Before copying itself to the scratchpad memory area and executing the code from there, the
+ * startup code is executing from LIM. The scratchpad area is not configured yet. This per-hart
+ * startup stack area is located in LIM and used during this phase of the startup code.
+ * STACK_SIZE_xxx_APPLICATION
+ * After the startup code executing from LIM configures the scratchpad memory, it configures
+ * the each hart's SP with this stack area for the respective hart's application function,
+ * (namely e51(), u54_1(), u54_2(), u54_3(), u54_4() ) to use it.
+ * This per-hart application stack area is located in scratchpad and used by application when
+ * it is executing from scratchpad.
+ *
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >envm
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> envm /* On the MPFS for startup code use, >switch_code AT>envm */
+}
+
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-envm.ld b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-envm.ld
new file mode 100644
index 00000000..29817bd0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-envm.ld
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_envm.ld
+ * Use with Bare metal startup code.
+ * Startup code runs from envm on MSS reset
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ /* *entry.o(.text); */
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > envm
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> envm
+
+ /*
+ * The .ram_code section will contain the code that is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code_dtim AT>envm
+
+ /*
+ * The .ddr_code section will contain the code that is run from DDR.
+ * This is to verify DDR working as expeted
+ */
+ .ddr_code :
+ {
+ . = ALIGN (4);
+ __ddr_load = LOADADDR (.ram_code);
+ __ddr_start = .;
+ *(.ddr_codetext) /* .ram_codetext sections (code) */
+ *(.ddr_codetext*) /* .ram_codetext* sections (code) */
+ *(.ddr_coderodata) /* read-only data (constants) */
+ *(.ddr_coderodata*)
+ . = ALIGN (4);
+ __ddr_end = .;
+ } >ddr_cached_32bit AT>envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set
+ point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing.
+ Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim AT > envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim AT > envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary (0x1000) - corresponds to page size, when using
+ memory mem */
+ /* protection */
+ /* .stack : ALIGN(0x1000) */
+ .stack : ALIGN(0x10)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ /* place __start_of_free_lim$ after last allocation of l2_lim */
+ . = ALIGN(0x10);
+ PROVIDE(__start_of_free_lim$ = .);
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..391c47bf
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ * Code starts from LIM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * STACK_SIZE_xxx_STARTUP
+ * Stack size for each hart's startup code.
+ * Before copying itself to the scratchpad memory area and executing the code from there, the
+ * startup code is executing from LIM. The scratchpad area is not configured yet. This per-hart
+ * startup stack area is located in LIM and used during this phase of the startup code.
+ * STACK_SIZE_xxx_APPLICATION
+ * After the startup code executing from LIM configures the scratchpad memory, it configures
+ * the each hart's SP with this stack area for the respective hart's application function,
+ * (namely e51(), u54_1(), u54_2(), u54_3(), u54_4() ) to use it.
+ * This per-hart application stack area is located in scratchpad and used by application when
+ * it is executing from scratchpad.
+ *
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __l2lim_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >l2lim
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> l2lim
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>envm */
+
+}
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-lim.ld b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-lim.ld
new file mode 100644
index 00000000..908cf23e
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/linker/mpfs-lim.ld
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_lim.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+ /* text: text code section */
+ . = __l2lim_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ . = ALIGN(0x10);
+ } > l2lim
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ . = ALIGN (0x10);
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> l2lim
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including eNVM clock.
+ * This can not be done when running from eNVM
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>eNVM */
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h
new file mode 100644
index 00000000..7b6e905d
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * Platform definitions
+ * Version based on requirements of MPFS MSS
+ *
+ */
+ /*========================================================================*//**
+ @mainpage Sample file detailing how mss_sw_config.h should be constructed for
+ the MPFS MSS
+
+ @section intro_sec Introduction
+ The mss_sw_config.h has the default software configuration settings for the
+ MPFS HAL and will be located at
+ /src/platform/platform_config_reference folder of the bare
+ metal SoftConsole project. The platform_config_reference is provided as a
+ default reference configuration.
+ When you want to configure the MPFS HAL with required configuration for
+ your project, the mss_sw_config.h must be edited and be placed in the
+ following project directory:
+ /src/boards//platform_config/mpfs_hal_config/
+
+ @section
+
+*//*==========================================================================*/
+
+
+#ifndef MSS_SW_CONFIG_H_
+#define MSS_SW_CONFIG_H_
+
+/*
+ * MPFS_HAL_FIRST_HART and MPFS_HAL_LAST_HART defines are used to specify which
+ * harts to actually start. The value and the actual hart it represents are
+ * listed below:
+ * value hart
+ * 0 E51
+ * 1 U54_1
+ * 2 U54_2
+ * 3 U54_3
+ * 4 U54_4
+ * Set MPFS_HAL_FIRST_HART to a value greater than 0 if you do not want your
+ * application to start and execute code on the harts represented by smaller
+ * value numbers.
+ * Set MPFS_HAL_LAST_HART to a value smaller than 4 if you do not wish to use
+ * all U54_x harts.
+ * Harts that are not started will remain in an infinite WFI loop unless used
+ * through some other method.
+ * The value of MPFS_HAL_FIRST_HART must always be less than MPFS_HAL_LAST_HART.
+ * The value of MPFS_HAL_LAST_HART must never be greater than 4.
+ * A typical use-case where you set MPFS_HAL_FIRST_HART = 1 and
+ * MPFS_HAL_LAST_HART = 1 is when
+ * your application is running on U54_1 and a bootloader running on E51 loads
+ * your application to the target memory and kicks-off U54_1 to run it.
+ */
+#ifndef MPFS_HAL_FIRST_HART
+#define MPFS_HAL_FIRST_HART 0
+#endif
+
+#ifndef MPFS_HAL_LAST_HART
+#define MPFS_HAL_LAST_HART 4
+#endif
+
+/*
+ * IMAGE_LOADED_BY_BOOTLOADER
+ * We set IMAGE_LOADED_BY_BOOTLOADER = 0 if the application image runs from
+ * non-volatile memory after reset. (No previous stage bootloader is used.)
+ * Set IMAGE_LOADED_BY_BOOTLOADER = 1 if the application image is loaded by a
+ * previous stage bootloader.
+ *
+ * MPFS_HAL_HW_CONFIG is defined if we are a boot-loader. This is a
+ * conditional compile switch is used to determine if MPFS HAL will perform the
+ * hardware configurations or not.
+ * Defined => This program acts as a First stage bootloader and performs
+ * hardware configurations.
+ * Not defined => This program assumes that the hardware configurations are
+ * already performed (Typically by a previous boot stage)
+ *
+ * List of items initialised when MPFS_HAL_HW_CONFIG is enabled
+ * - load virtual rom (see load_virtual_rom(void) in system_startup.c)
+ * - l2 cache config
+ * - Bus error unit config
+ * - MPU config
+ * - pmp config
+ * - I/O, clock and clock mux's, DDR and SGMII
+ * - will start other harts, see text describing MPFS_HAL_FIRST_HART,
+ * MPFS_HAL_LAST_HART above
+ *
+ */
+#define IMAGE_LOADED_BY_BOOTLOADER 0
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+#define MPFS_HAL_HW_CONFIG
+#endif
+
+
+/*
+ * If you are using common memory for sharing across harts,
+ * uncomment #define MPFS_HAL_SHARED_MEM_ENABLED
+ * make sure common memory is allocated in the linker script
+ * See app_hart_common mem section in the example platform
+ * linker scripts.
+ */
+
+#define MPFS_HAL_SHARED_MEM_ENABLED
+
+
+/* define the required tick rate in Milliseconds */
+/* if this program is running on one hart only, only that particular hart value
+ * will be used */
+#define HART0_TICK_RATE_MS 5UL
+#define HART1_TICK_RATE_MS 5UL
+#define HART2_TICK_RATE_MS 5UL
+#define HART3_TICK_RATE_MS 5UL
+#define HART4_TICK_RATE_MS 5UL
+
+/*
+ * Define the size of the Hart Local Storage (HLS).
+ * In the MPFS HAL, we are using HLS for debug data storage during the initial
+ * boot phase.
+ * This includes the flags which indicate the hart state regarding boot state.
+ * The HLS will take memory from top of each stack allocated at boot time.
+ *
+ */
+#define HLS_DEBUG_AREA_SIZE 64
+
+/*
+ * Bus Error Unit (BEU) configurations
+ * BEU_ENABLE => Configures the events that the BEU can report. bit value
+ * 1= enabled, 0 = disabled.
+ * BEU_PLIC_INT => Configures which accrued events should generate an
+ * interrupt to the PLIC.
+ * BEU_LOCAL_INT => Configures which accrued events should generate a
+ * local interrupt to the hart on which the event accrued.
+ */
+#define BEU_ENABLE 0x0ULL
+#define BEU_PLIC_INT 0x0ULL
+#define BEU_LOCAL_INT 0x0ULL
+
+/*
+ * Clear memory on startup
+ * 0 => do not clear DTIM and L2
+ * 1 => Clears memory
+ * Note: If you are the zero stage bootloader, set this to one.
+ */
+#ifndef MPFS_HAL_CLEAR_MEMORY
+#define MPFS_HAL_CLEAR_MEMORY 1
+#endif
+
+/*
+ * Comment out the lines to disable the corresponding hardware support not required
+ * in your application.
+ * This is not necessary from an operational point of view as operation dictated
+ * by MSS configurator settings, and items are enabled/disabled by this method.
+ * The reason you may want to use below is to save code space.
+ */
+#define SGMII_SUPPORT
+#define DDR_SUPPORT
+#define MSSIO_SUPPORT
+
+/*
+ * DDR software options
+ */
+
+/*
+ * Debug DDR startup through a UART
+ * Comment out in normal operation. May be useful for debug purposes in bring-up
+ * of a new board design.
+ * See the weakly linked function setup_ddr_debug_port(mss_uart_instance_t * uart)
+ * If you need to edit this function, make another copy of the function in your
+ * application without the weak linking attribute. This copy will then get linked.
+ * */
+//#define DEBUG_DDR_INIT
+//#define DEBUG_DDR_RD_RW_FAIL
+//#define DEBUG_DDR_RD_RW_PASS
+//#define DEBUG_DDR_CFG_DDR_SGMII_PHY
+//#define DEBUG_DDR_DDRCFG
+
+
+/*
+ * The hardware configuration settings imported from Libero project get generated
+ * into /src/boards// folder.
+ * If you need to overwrite them for testing purposes, you can do so here.
+ * e.g. If you want change the default SEG registers configuration defined by
+ * LIBERO_SETTING_SEG0_0, define it here and it will take precedence.
+ * #define LIBERO_SETTING_SEG0_0 0x80007F80UL
+ *
+ */
+
+#endif /* USER_CONFIG_MSS_USER_CONFIG_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-basic/src/platform/soc_config_generator/mpfs_configuration_generator.py b/driver-examples/mss-can/mpfs-can-basic/src/platform/soc_config_generator/mpfs_configuration_generator.py
new file mode 100644
index 00000000..3394bdba
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-basic/src/platform/soc_config_generator/mpfs_configuration_generator.py
@@ -0,0 +1,713 @@
+#-------------------------------------------------------------------------------
+# This script takes an xml file which describes hardware options and produces
+# header files in the target directory which are used by the embedded
+# software.
+#-------------------------------------------------------------------------------
+
+import datetime
+import os
+import os.path
+import xml.etree.ElementTree as ET
+import sys
+from pathlib import Path
+
+
+# --------------------------------------------------------------------------------------------
+# mpfs_configuration_generator.py version
+#
+# 0.6.3 target folder name change from "fpga_config" -> fpga_design config, filename
+# hw_platform.h changed to fpga_design_config.h ,
+# bug fix related to multiple xml file selection and added libero design information
+# constants in fpga_design_config.h/ removed date,version and design information from all the files
+# except fpga_design_config.h
+#
+# 0.6.2 added support for multiple xml file found in input folder
+# /empty xml file check/ xml filename arg in current folder/
+# if multiple files are there then the file with the latest time stamp will
+# be selected.
+# 0.6.1 changed target folder name from soc_config to fpga_config
+#
+# 0.5.2 Aries Embedded Feedback: remove trailing spaces.
+# 0.5.1 Added check that the source XML document is more recent than content of already existing
+# SoC configuration files.
+#
+# 0.4.2 Allowed to only specify the folder where the input XML
+# file is located. Use file ending with _mss_cfg.xml if one exists, any other .xml file in
+# the input folder otherwise.
+#
+# 0.4.1 Modified the arguments to allow specifying
+# the folder where the soc_config folder should be generated.
+#
+# 0.3.4 fixed comment formatting bug in hw_memory.h generation
+# 0.3.3 updated copyright format
+# 0.3.2 removed leading zeros from decimal values ( clock rates)
+# -------------------------------------------------------------------------------------------------------
+def get_script_ver():
+ '''
+ This changes anytime anytime the mpfs_configuration_generator.py script
+ changes. This does not necessarily mean the xml format has been updated in
+ get_xml_ver()
+ :return: script version
+ '''
+ return "0.6.3"
+
+
+
+
+# -----------------------------------------------------------------------------
+# xml file to parse
+# Also an xml files listing tags used for reference
+# -----------------------------------------------------------------------------
+reference_xml_file = \
+ ('hardware_des_xml,src_example,mpfs_hw_ref_defaults.xml,default',
+ 'hardware_des_xml,src_example,mpfs_hw_ref_ddr3_100Mhz_ext_clk.xml,ddr3_100Mhz_ref')
+
+xml_tag_file = 'hardware_des_xml,src_example,mpfs_hw_tag_reference.xml'
+
+
+# -----------------------------------------------------------------------------
+# xml tags, the structure here should follow the readme.md description
+# contained in the root folder for tags
+# Please note: The tag in the first column ( mss_xxx) is the same as the
+# directory name (/fpga_design_config/mss_xxx)
+# the fourth item lets program know how to format info in header file
+# the six item lets program know how to format value, decimal or hex
+# -----------------------------------------------------------------------------
+xml_tags = ('mss_memory_map,map,mem_elements,fm_define,none,hex',
+ 'mss_memory_map,apb_split,registers,fm_struct,none,hex',
+ 'mss_memory_map,cache,registers,fm_struct,none,hex',
+ 'mss_memory_map,pmp_h0,registers,fm_struct,HART0_,hex64',
+ 'mss_memory_map,pmp_h1,registers,fm_struct,HART1_,hex64',
+ 'mss_memory_map,pmp_h2,registers,fm_struct,HART2_,hex64',
+ 'mss_memory_map,pmp_h3,registers,fm_struct,HART3_,hex64',
+ 'mss_memory_map,pmp_h4,registers,fm_struct,HART4_,hex64',
+ 'mss_memory_map,mpu_fic0,registers,fm_struct,FIC0_,hex64',
+ 'mss_memory_map,mpu_fic1,registers,fm_struct,FIC1_,hex64',
+ 'mss_memory_map,mpu_fic2,registers,fm_struct,FIC2_,hex64',
+ 'mss_memory_map,mpu_crypto,registers,fm_struct,CRYPTO_,hex64',
+ 'mss_memory_map,mpu_gem0,registers,fm_struct,GEM0_,hex64',
+ 'mss_memory_map,mpu_gem1,registers,fm_struct,GEM1_,hex64',
+ 'mss_memory_map,mpu_usb,registers,fm_struct,USB_,hex64',
+ 'mss_memory_map,mpu_mmc,registers,fm_struct,MMC_,hex64',
+ 'mss_memory_map,mpu_scb,registers,fm_struct,SCB_,hex64',
+ 'mss_memory_map,mpu_trace,registers,fm_struct,TRACE_,hex64',
+ 'mss_io,io_mux,registers,fm_reg,none,hex',
+ 'mss_io,hsio,registers,fm_reg,none,hex',
+ 'mss_sgmii,tip,registers,fm_reg,none,hex',
+ 'mss_ddr,options,registers,fm_reg,none,hex',
+ 'mss_ddr,io_bank,registers,fm_reg,none,hex',
+ 'mss_ddr,mode,registers,fm_reg,none,hex',
+ 'mss_ddr,off_mode,registers,fm_reg,none,hex',
+ 'mss_ddr,segs,registers,fm_reg,none,hex',
+ 'mss_ddr,ddrc,registers,fm_reg,none,hex',
+ 'mss_clocks,clocks,registers,fm_define,none,decimal',
+ 'mss_clocks,mss_sys,registers,fm_define,MSS_,hex',
+ 'mss_clocks,mss_pll,registers,fm_define,MSS_,hex',
+ 'mss_clocks,sgmii_pll,registers,fm_reg,SGMII_,hex',
+ 'mss_clocks,ddr_pll,registers,fm_reg,DDR_,hex',
+ 'mss_clocks,mss_cfm,registers,fm_reg,MSS_,hex',
+ 'mss_clocks,sgmii_cfm,registers,fm_reg,SGMII_,hex',
+ 'mss_general,mss_peripherals,registers,fm_reg,none,hex',)
+
+
+# -----------------------------------------------------------------------------
+# Header files to generate
+# -----------------------------------------------------------------------------
+header_files = ('fpga_design_config,memory_map,hw_memory.h',
+ 'fpga_design_config,memory_map,hw_apb_split.h',
+ 'fpga_design_config,memory_map,hw_cache.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart0.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart1.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart2.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart3.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart4.h',
+ 'fpga_design_config,memory_map,hw_mpu_fic0.h',
+ 'fpga_design_config,memory_map,hw_mpu_fic1.h',
+ 'fpga_design_config,memory_map,hw_mpu_fic2.h',
+ 'fpga_design_config,memory_map,hw_mpu_crypto.h',
+ 'fpga_design_config,memory_map,hw_mpu_gem0.h',
+ 'fpga_design_config,memory_map,hw_mpu_gem1.h',
+ 'fpga_design_config,memory_map,hw_mpu_usb.h',
+ 'fpga_design_config,memory_map,hw_mpu_mmc.h',
+ 'fpga_design_config,memory_map,hw_mpu_scb.h',
+ 'fpga_design_config,memory_map,hw_mpu_trace.h',
+ 'fpga_design_config,io,hw_mssio_mux.h',
+ 'fpga_design_config,io,hw_hsio_mux.h',
+ 'fpga_design_config,sgmii,hw_sgmii_tip.h',
+ 'fpga_design_config,ddr,hw_ddr_options.h',
+ 'fpga_design_config,ddr,hw_ddr_io_bank.h',
+ 'fpga_design_config,ddr,hw_ddr_mode.h',
+ 'fpga_design_config,ddr,hw_ddr_off_mode.h',
+ 'fpga_design_config,ddr,hw_ddr_segs.h',
+ 'fpga_design_config,ddr,hw_ddrc.h',
+ 'fpga_design_config,clocks,hw_mss_clks.h',
+ 'fpga_design_config,clocks,hw_clk_sysreg.h',
+ 'fpga_design_config,clocks,hw_clk_mss_pll.h',
+ 'fpga_design_config,clocks,hw_clk_sgmii_pll.h',
+ 'fpga_design_config,clocks,hw_clk_ddr_pll.h',
+ 'fpga_design_config,clocks,hw_clk_mss_cfm.h',
+ 'fpga_design_config,clocks,hw_clk_sgmii_cfm.h',
+ 'fpga_design_config,general,hw_gen_peripherals.h')
+
+MAX_LINE_WIDTH = 80
+
+
+# -----------------------------------------------------------------------------
+# Read the xml file into ET
+# -----------------------------------------------------------------------------
+def read_xml_file(s):
+ file_dir = os.path.join(*s)
+ tree = ET.parse(file_dir.strip())
+ root = tree.getroot() # type: object
+ return root
+
+
+# -----------------------------------------------------------------------------
+# Routine to make a folder
+# -----------------------------------------------------------------------------
+def safe_make_folder(i):
+ '''Makes a folder (and its parents) if not present'''
+ try:
+ os.makedirs(i)
+ except:
+ pass
+
+
+# -----------------------------------------------------------------------------
+# Create the directory structure
+# -----------------------------------------------------------------------------
+def create_hw_dir_struct(root_folder, TOP):
+ '''Creates directory structure off root, subdirectories passed in a tupple'''
+ for folder in TOP:
+ safe_make_folder(root_folder + '/' + folder)
+
+
+# -----------------------------------------------------------------------------
+# Generate the copyright notice at the top of the header file
+# -----------------------------------------------------------------------------
+def WriteCopyright(root, theFile, filename, creator):
+ '''
+ generate copyright notice based on the following:
+ #/*******************************************************************************
+ # * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ # *
+ # * SPDX-License-Identifier: MIT
+ # *
+ # * MPFS HAL Embedded Software
+ # *
+ # */
+ :param root:
+ :param theFile:
+ :param filename:
+ :param creator:
+ :return:
+ '''
+ theFile.write('/**********************************************************'
+ '*********************\n')
+ theFile.write(" * Copyright 2019-" + str(datetime.datetime.now().year) + " Microchip FPGA Embedded Systems Solutions.\n")
+ theFile.write(' *\n')
+ theFile.write(' * SPDX-License-Identifier: MIT\n')
+ theFile.write(' *\n')
+ theFile.write(" * @file " + filename + "\n")
+ theFile.write(" * @author " + creator + "\n")
+ theFile.write(' *\n')
+ if theFile.name == "fpga_design_config\fpga_design_config.h":
+ for child in root:
+ if child.tag == "design_information":
+ for child1 in child:
+ if child1.tag == "design_name":
+ theFile.write(' * Libero design name: ' + child1.text.strip() + "\n")
+ if child1.tag == "libero_version":
+ theFile.write(' * Generated using Libero version: ' + child1.text.strip() + "\n")
+ if child1.tag == "mpfs_part_no":
+ theFile.write(' * MPFS part number used in design: ' + child1.text.strip() + "\n")
+ if child1.tag == "creation_date_time":
+ theFile.write(' * Date generated by Libero: ' + child1.text.strip() + "\n")
+ if child1.tag == "xml_format_version":
+ theFile.write(' * Format version of XML description: ' + child1.text.strip() + "\n")
+ theFile.write(' * PolarFire SoC Configuration Generator version: ' + get_script_ver() + "\n")
+
+ strings = ('', ' Note 1: This file should not be edited. If you need to modify a parameter',\
+ ' without going through regenerating using the MSS Configurator Libero flow ' ,' or editing the associated xml file',\
+ ' the following method is recommended: \n',\
+ ' 1. edit the following file ',' boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h\n',\
+ ' 2. define the value you want to override there.',' (Note: There is a commented example in the platform directory)\n',\
+ ' Note 2: The definition in mss_sw_config.h takes precedence, as',\
+ ' mss_sw_config.h is included prior to the generated header files located in', ' boards/your_board/fpga_design_config'\
+ )
+ for string in strings:
+ theFile.write(' *' + string + "\n")
+ theFile.write(' *\n */\n')
+
+
+# -----------------------------------------------------------------------------
+# the header start define
+# -----------------------------------------------------------------------------
+def start_define(theFile, filename):
+ filename = filename[:-2] # remove .h from file name
+ theFile.write('\n#ifndef ' + filename.upper() + '_H_')
+ theFile.write('\n#define ' + filename.upper() + '_H_\n\n')
+
+
+# -----------------------------------------------------------------------------
+# start c plus define
+# -----------------------------------------------------------------------------
+def start_cplus(theFile, filename):
+ theFile.write('\n#ifdef __cplusplus\n')
+ theFile.write('extern ' + ' \"C\"' + ' {\n')
+ theFile.write('#endif\n\n')
+
+
+# -----------------------------------------------------------------------------
+# end define associated with header start define
+# -----------------------------------------------------------------------------
+def end_define(theFile, filename):
+ filename = filename[:-2] # remove .h from file name
+ theFile.write('\n#endif /*' + ' #ifdef ' + filename.upper() + '_H_ */\n\n')
+
+
+# -----------------------------------------------------------------------------
+# end c++ define
+# -----------------------------------------------------------------------------
+def end_cplus(theFile, filename):
+ theFile.write('\n#ifdef __cplusplus\n}\n#endif\n\n')
+
+
+# -----------------------------------------------------------------------------
+# write line, break into chunks
+# -----------------------------------------------------------------------------
+def write_line(headerFile , reg_description):
+ ''' write line, break into chunks '''
+ word_list = reg_description.split() # list of words
+ sentence = word_list[0] + ' '
+ word_list.pop(0)
+ for word in word_list:
+ if (len(sentence + word + ' ') > MAX_LINE_WIDTH):
+ headerFile.write(sentence.rstrip() + '\n')
+ sentence = word + ' '
+ else:
+ sentence = sentence + word + ' '
+ if len(sentence) > 0:
+ headerFile.write(sentence.rstrip() + '\n')
+
+
+# -----------------------------------------------------------------------------
+# Iterate through registers and produce header file output
+# -----------------------------------------------------------------------------
+def generate_register(headerFile, registers, tags):
+ '''
+ Parse registers tag for register tags and print to header file
+ :param headerFile: header file to print to
+ :param registers: registers in a tag
+ :param tags: Some tags used to determine print format
+ :return:
+ '''
+ for register in registers:
+ # if tag 4 is set, pre-append register name with tag[4] value
+ if tags[4] != 'none':
+ pre_append = tags[4]
+ name = 'LIBERO_SETTING_' + pre_append + register.get('name')
+ else:
+ name = 'LIBERO_SETTING_' + register.get('name')
+ name_of_reg = name
+ description = register.get('description')
+ name_gap = 15
+ if len(name) > 15:
+ name_gap = len(name)
+ s = '#define' + ' ' + name.ljust(name_gap, ' ')
+ name = register.get('name') + "_OFF_MODE"
+ name_gap = 15
+ if len(name) > 15:
+ name_gap = len(name)
+ stest1 = '#define' + ' ' + name.ljust(name_gap, ' ')
+ field_list = []
+ reg_value = 0
+ reg_value_default = 0
+ for field in register:
+ if field.tag == "field":
+ gap = 30
+ if len(field.get('name')) > gap:
+ gap = len(field.get('name')) + 4
+ sfield = ' /* ' + field.get('name').ljust(gap, ' ')
+ stemp = ' [' + field.get('offset') + ':' + field.get('width') + ']'
+ stemp = stemp.ljust(12, ' ')
+ sfield += stemp
+ sfield += field.get('Type')
+ if (field.get('Type') == 'RW'):
+ sfield += ' value= ' + field.text.strip()
+ temp_val = ((int(field.text.strip(), 16)) << int(field.get('offset')))
+ reg_value += temp_val
+ sfield += ' */\n'
+ # add the field to list of fields
+ field_list.extend([sfield])
+ if tags[5] == 'decimal':
+ value = format(reg_value, '01X')
+ default_value = format(reg_value_default, '08X')
+ elif tags[5] == 'hex64':
+ value = '0x' + format(reg_value, '016X') + 'ULL'
+ default_value = '0x' + format(reg_value_default, '08X')
+ else :
+ value = '0x' + format(reg_value, '08X') + 'UL'
+ default_value = '0x' + format(reg_value_default, '08X')
+ name_gap = 4
+ if len(s) >= name_gap:
+ name_gap = len(s) + 4
+ s = s.ljust(name_gap, ' ') + value + '\n'
+ reg_description = '/*' + description + ' */\n'
+ headerFile.write('#if !defined ' + '(' + name_of_reg + ')\n')
+ # Write out the register description, max chars per line 80
+ write_line(headerFile , reg_description)
+ headerFile.write(s)
+ for x in range(len(field_list)):
+ headerFile.write(field_list[x])
+ headerFile.write('#endif\n')
+
+
+# -----------------------------------------------------------------------------
+# Iterate through tag mem_elements looking for mem elements produce header file
+# output
+# -----------------------------------------------------------------------------
+def generate_mem_elements(headerFile, mem_elements, tags):
+ '''
+ Parse registers tag for mem tags and print to header file
+ :param headerFile:
+ :param registers:
+ :return:
+ '''
+ for mem in mem_elements:
+ name = 'LIBERO_SETTING_' + mem.get('name')
+ name_of_reg = name
+ name_size = name + '_SIZE'
+ description = mem.get('description')
+ name_gap = 15
+ if len(name) > 15:
+ name_gap = len(name)
+ s = '#define' + ' ' + name.ljust(name_gap, ' ')
+ s1 = '#define' + ' ' + name_size.ljust(name_gap, ' ')
+ # get the values
+ mem_value = mem.text.strip()
+ mem_size = mem.get('size')
+ # make sure space between name and value 4 spaces
+ name_gap = 4
+ if len(s) >= name_gap:
+ name_gap = len(s) + 4
+ # make sure space between name and value 4 spaces
+ name_size_gap = 4
+ if len(s1) >= name_size_gap:
+ name_size_gap = len(s1) + 4
+ # create the strings for writing
+ s = s.ljust(name_gap, ' ') + mem_value + '\n'
+ reg_description = '/*' + description + ' */\n'
+ s1 = s1.ljust(name_size_gap, ' ') + mem_size \
+ + ' /* Length of memory block*/ \n'
+ headerFile.write('#if !defined ' + '(' + name_of_reg + ')\n')
+ headerFile.write(reg_description)
+ headerFile.write(s)
+ headerFile.write(s1)
+ headerFile.write('#endif\n')
+
+
+# -----------------------------------------------------------------------------
+# generate a header file
+# -----------------------------------------------------------------------------
+def generate_header( file, real_root, root, file_name, tags):
+ creator = "Microchip-FPGA Embedded Systems Solutions"
+ with open(file, 'w+') as headerFile:
+ # write the copyright header
+ WriteCopyright(real_root, headerFile, file_name, creator)
+ start_define(headerFile, file_name)
+ start_cplus(headerFile, file_name)
+ for child in root:
+ if child.tag == "registers":
+ generate_register(headerFile, child, tags)
+ if child.tag == "mem_elements":
+ generate_mem_elements(headerFile, child, tags)
+ for child2 in child:
+ if child2.tag == "registers":
+ generate_register(headerFile, child2, tags)
+ end_cplus(headerFile, file_name)
+ end_define(headerFile, file_name)
+
+
+# -----------------------------------------------------------------------------
+# fpga_design_config.h header file generation.
+# -----------------------------------------------------------------------------
+
+def write_libero_config_info(root,theFile):
+ script_version = get_script_ver().split('.')
+ tags_dic = {"design_name":"LIBERO_SETTING_DESIGN_NAME","libero_version":"LIBERO_SETTING_MSS_CONFIGURATOR_VERSION","mpfs_part_no" :"LIBERO_SETTING_MPFS_PART "\
+ ,"creation_date_time":"LIBERO_SETTING_GENERATION_DATE","xml_format_version":"LIBERO_SETTING_XML_VERSION"}
+
+ #max constant name size + some extra buffer space
+ max_gap = max([len(v) for k,v in tags_dic.items()]) + 8
+
+ fixed_gap = 12
+ xml_version = []
+ for child in root:
+ if child.tag == "design_information":
+ for child1 in child:
+ if child1.tag in tags_dic:
+ gap = max_gap - (len(tags_dic[child1.tag]))
+ theFile.write('#define '+ tags_dic[child1.tag].ljust(4,' ') + " "*(gap + fixed_gap) + "\"" + child1.text.strip() + "\"" + "\n")
+ if child1.tag == "xml_format_version":
+ xml_version = child1.text.strip().split('.')
+
+ const = {"LIBERO_SETTING_XML_VERSION_MAJOR": xml_version[0],"LIBERO_SETTING_XML_VERSION_MINOR":xml_version[1],"LIBERO_SETTING_XML_VERSION_PATCH":xml_version[2], "LIBERO_SETTING_HEADER_GENERATOR_VERSION":'.'.join(script_version),"LIBERO_SETTING_HEADER_GENERATOR_VERSION_MAJOR":script_version[0],"LIBERO_SETTING_HEADER_GENERATOR_VERSION_MINOR":script_version[1],"LIBERO_SETTING_HEADER_GENERATOR_VERSION_PATCH":script_version[2]}
+
+ # write hard coded constants in the fpga_design_config.h file.
+ for k,v in const.items():
+ gap = max_gap - len(k)
+ if k == "LIBERO_SETTING_HEADER_GENERATOR_VERSION":
+ theFile.write('#define '+ k.ljust(4,' ') + " "*(gap + fixed_gap) + "\"" + v + "\"" + "\n")
+ else:
+ theFile.write('#define '+ k + " "*(gap + fixed_gap) + v + "\n")
+ #new line
+ theFile.write("\n")
+
+
+def generate_reference_header_file(ref_header_file, root, header_files):
+ creator = "Embedded Software"
+ # itemName ="io_mux configuration"
+ s = ref_header_file.split(',')
+ file = os.path.join(*s)
+ file_name = s[-1]
+ with open(file, 'w+') as headerFile:
+ # write the copyright header
+
+ WriteCopyright(root, headerFile, file_name, creator)
+ # add exclusive define
+ start_define(headerFile, file_name)
+ # include all the headers
+
+ #define Libero design information constants
+ write_libero_config_info(root,headerFile)
+ index = 0
+ for child in header_files:
+ c = header_files[index].split(',')
+ c.remove('fpga_design_config')
+ # include_file = os.path.join(*c)
+ # as we need formatting correct for linux and windows
+ include_file = c[0] + '/' + c[1]
+ headerFile.write('#include \"' + include_file + '\"\n')
+ index += 1
+ # add the c++ define
+ start_cplus(headerFile, file_name)
+ # no content in this case
+ comment = '/* No content in this file, used for referencing header */\n'
+ headerFile.write(comment)
+ # end the c++ define
+ end_cplus(headerFile, file_name)
+ end_define(headerFile, file_name)
+
+
+# -----------------------------------------------------------------------------
+# Generate all the header files, passed in output_header_files
+# -----------------------------------------------------------------------------
+def generate_header_files(output_header_files, input_xml_file, input_xml_tags):
+ # read in an xml file
+ s = input_xml_file.split(',')
+
+ root = read_xml_file(s)
+ index = 0
+ while index < len(input_xml_tags):
+ ref_tags = input_xml_tags[index].split(',')
+ s = output_header_files[index].split(',')
+ file_name = s[-1]
+ dir_name = s[-2]
+ file_dir = os.path.join(*s)
+ found_match = 0
+ for child in root:
+ if child.tag == 'mss_' + dir_name:
+ for child1 in child:
+ if child1.tag == ref_tags[1]:
+ found_match = 1
+ break
+ #
+ # Next, create file based on xml content
+ #
+ if found_match == 1:
+ generate_header(file_dir, root, child1, file_name, ref_tags)
+ index += 1
+
+ '''
+ generate a header which references all the generated headers
+ '''
+ file_name = 'fpga_design_config,fpga_design_config.h'
+ generate_reference_header_file(file_name, root, output_header_files)
+
+
+# -----------------------------------------------------------------------------
+# Return absolute path created from working directory location and relative
+# path passed as argument. Handles path to an XML file and path to a folder.
+# -----------------------------------------------------------------------------
+def get_full_path(in_path):
+ print(in_path)
+ cwd = os.getcwd()
+ print(cwd)
+ filename = ''
+ temp = in_path
+ if in_path.endswith('.xml'):
+ path_comp = in_path.split('/')
+ last = len(path_comp) - 1
+ filename = path_comp[last]
+
+ in_path = in_path.replace(filename, '')
+ print(in_path)
+ if in_path == '':
+ filename = temp
+ in_path = os.getcwd()
+ print(in_path)
+ else:
+ xml_list = []
+ dir_entries = os.listdir(in_path)
+ for dir_entry in dir_entries:
+
+ if dir_entry.endswith('.xml'):
+ xml_list.append(dir_entry)
+ else:
+ if dir_entry.endswith('_mss_cfg.xml'):
+ xml_list.append(dir_entry)
+ break
+ #This section will sort the xml file by the latest timestamp
+ if len(xml_list) > 1:
+
+ xml_list = sort_by_timestamp(xml_list,in_path)
+ filename = xml_list[-1]
+ #prompt the selected filename
+ print("selected xml file is : {}".format(filename))
+ else:
+ if len(xml_list) != 0:
+ filename = xml_list[0]
+
+ print(in_path)
+
+ try:
+ print("trying to change directory")
+ os.chdir(in_path)
+ full_path = os.getcwd()
+ except IOError:
+ print("caught IO error ")
+ sys.exit()
+
+ os.chdir(cwd)
+ full_path = full_path + '/' + filename
+ if is_empty_file(full_path):
+ print("\nxml File is empty")
+ sys.exit()
+ else:
+ return full_path
+
+
+# -------------------------------------------------------
+# check is fpath is a file and empty
+# -------------------------------------------------------
+def is_empty_file(fpath):
+ return os.path.isfile(fpath) and os.path.getsize(fpath) == 0
+
+# -------------------------------------------------------
+# sort file names on the basis of time stamp
+# -------------------------------------------------------
+def sort_by_timestamp(file_name,file_path):
+ cwd = os.getcwd()
+ try :
+ os.chdir(file_path)
+ path = os.getcwd()
+ except IOError :
+ print("not a valid folder name--------------")
+ sys.exit()
+
+
+ Files = [path + '/' + file_name[i] for i in range(len(file_name))]
+ Files.sort(key=os.path.getmtime)
+ s_file_name = []
+ for i in range(len(Files)):
+ s_file_name.append(Files[i].split('/')[-1])
+
+ print("sorted list of files\n",s_file_name)
+ os.chdir(cwd)
+ return s_file_name
+
+# -----------------------------------------------------------------------------
+# helper for showing help information
+# -----------------------------------------------------------------------------
+def show_help():
+ print ('no of args you entered = ' + str(len(sys.argv) - 1))
+ print ('mpfs_configuration_generator.py :')
+ print (' This program reads xml hardware definition, outputs: header files')
+ print \
+ (' Usage: python3 mpfs_configuration_generator.py [xml file path] [output folder path] ')
+ print('path can be absolute as well as relative \n')
+ input(' Please run again with correct arguments')
+
+
+# -----------------------------------------------------------------------------
+# main function
+# todo: add options from the command line
+# -----------------------------------------------------------------------------
+def main_config_generator():
+ '''
+ This script takes an xml file which describes hardware options and produces
+ header files in the target directory which are used by the embedded
+ software.
+ Currently there are Two command line arguments
+ arg0: path to the folder containing xml file.
+ arg1: path of the folder where the fpga_design_config will be generated.
+ Note - If multiple xml files are present then the one with the latest time stamp
+ will be selected.
+
+ '''
+
+ #
+ # check/parse arguments
+ #
+ nb_arguments = len(sys.argv) - 1
+ if nb_arguments < 2:
+ show_help()
+ sys.exit()
+ fullCmdArguments = sys.argv
+ # - further arguments
+ argumentList = fullCmdArguments[1:]
+ input_xml_file = argumentList[0]
+ input_xml_file = get_full_path(input_xml_file)
+
+ if nb_arguments >= 2:
+ output_folder_name = argumentList[1]
+ output_folder_name = get_full_path(output_folder_name)
+ os.chdir(output_folder_name)
+
+ debug_reg_csv = False
+ if nb_arguments >= 4:
+ if argumentList[3] == 'debug_regs':
+ debug_reg_csv = True
+ if nb_arguments >= 3:
+ if argumentList[2] == 'generate_refernce_xml':
+ gen_xml = True
+ else:
+ gen_xml = False
+ #
+ # Check version of python interpreter, helps debugging
+ # Currently runs on python version 2 and 3
+ #
+ print ('python interpreter details:',sys.version_info)
+ if sys.version_info > (3, 0):
+ # # Python 3 code in this block
+ print ('python interpreter running is version 3')
+ else:
+ # # Python 2 code in this block
+ print ('python interpreter running is version 2')
+
+ # Create directory structure for the header files
+ #
+ root_folder = 'fpga_design_config'
+ TOP = ['clocks', 'ddr', 'io', 'memory_map', 'sgmii', 'general']
+ create_hw_dir_struct(root_folder, TOP)
+ #
+ # Next, read in XML content and create header files
+ #
+ generate_header_files(header_files, input_xml_file, xml_tags)
+ print('Hardware configuration header files created in directory:', os.path.join(output_folder_name, 'fpga_design_config'))
+
+if __name__ == "__main__":
+ main_config_generator()
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/.cproject b/driver-examples/mss-can/mpfs-can-external-loopback/.cproject
new file mode 100644
index 00000000..1fb9a52a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/.cproject
@@ -0,0 +1,1016 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/.gitignore b/driver-examples/mss-can/mpfs-can-external-loopback/.gitignore
new file mode 100644
index 00000000..65d718f0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/.gitignore
@@ -0,0 +1,8 @@
+/Debug*/
+/Release*/
+/core
+/LIM-Debug/
+/LIM-Release/
+/eNVM-Scratchpad-Release/
+/DDR-Release/
+/.settings/
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/.project b/driver-examples/mss-can/mpfs-can-external-loopback/.project
new file mode 100644
index 00000000..27864670
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/.project
@@ -0,0 +1,26 @@
+
+
+ mpfs-can-external-loopback
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/README.md b/driver-examples/mss-can/mpfs-can-external-loopback/README.md
new file mode 100644
index 00000000..c7bef078
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/README.md
@@ -0,0 +1,59 @@
+# PolarFire SoC MSS Full CAN external loop back example
+
+This example project demonstrates using the MSS CAN peripheral to perform CAN
+message transmission and reception using external loop back. The user need to
+connect the CAN_H and CAN_L as mentioned below in jumper setting section before
+running the example project.
+
+The operation of the MSS CAN is controlled via a serial console.
+
+## How to use this example
+
+On connecting Icicle kit J11 to the host PC, you should see 4 COM port interfaces.
+To use this project, configure the COM port **interface1** as below:
+ - 115200 baud
+ - 8 data bits
+ - 1 stop bit
+ - no parity
+ - no flow control
+
+This is a self contained example project. A greeting message is displayed
+over the UART terminal. On startup, the example project requests the user to
+enter the data to be send via the CAN Bus. You can enter up to 32 pairs of hex
+digits (no separating spaces) and the data will be sent out in chunks of 8
+bytes at a time in up to 4 CAN packets. You can send less than 32 bytes of
+data by pressing return to terminate the data early.
+
+The test program then enters a loop looking for user input to select the next
+action to perform. Whilst in this loop, the data portion of any CAN Bus packets
+received into the rx buffers is displayed on the console.
+
+The following macros modify the behaviour of the program:
+
+ CAN_TX_EXTENDED_ID - Defining this macro causes CAN messages with
+ with extended 29 bit IDs to be sent instead of
+ the standard 11 bit IDs.
+
+Jumper settings:
+Connect CAN-0 and CAN-1 as mentioned below:
+
+ | J25 | J27 | Description |
+ |---------|---------|--------------|
+ | 1 | 1 | CAN_H |
+ | 2 | 2 | CAN_L |
+ | 3 | 3 | GND |
+
+## Test CAN Message Transmission
+ 1. Enter the data on hyperterminal, which will be received through MSSUART1.
+ 2. Based on received data bytes, segregate as CAN messages of maximum 8
+ bytes length.
+ 3. Send the received data in terms of CAN messages from CAN-0 to CAN-1
+ 4. Observe the received CAN messages on CAN-1
+ 5. Compare the data received on CAN-1 with the data sent from the
+ hyperterminal data should be same.
+
+This project provides build configurations and debug launchers as exaplained
+[here](https://github.com/polarfire-soc/polarfire-soc-bare-metal-examples/blob/main/README.md)
+
+The design description file with this clock setting is available at ./src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
+This project can be tested with standard Libero reference design. However, please make sure that the input clock to MSS CAN block is set to 8MHz in xml.
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/mpfs-can-external-loopback hw all-harts attach.launch b/driver-examples/mss-can/mpfs-can-external-loopback/mpfs-can-external-loopback hw all-harts attach.launch
new file mode 100644
index 00000000..f61f0d1c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/mpfs-can-external-loopback hw all-harts attach.launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/mpfs-can-external-loopback hw all-harts debug.launch b/driver-examples/mss-can/mpfs-can-external-loopback/mpfs-can-external-loopback hw all-harts debug.launch
new file mode 100644
index 00000000..d8d77115
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/mpfs-can-external-loopback hw all-harts debug.launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart0/e51.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart0/e51.c
new file mode 100644
index 00000000..a14b792a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart0/e51.c
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on E51.
+ *
+ * Please refer to README.md file for more details
+ */
+
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h0 = 0U;
+
+/* Main function for the hart0(E51 processor).
+ * Application code running on hart1 is placed here
+ *
+ * The hart1 is in WFI while booting, hart0 brings it out of WFI when it raises
+ * the first Software interrupt.
+ */
+void e51(void)
+{
+ uint8_t flag = 0u;
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ (void)mss_config_clk_rst(MSS_PERIPH_MMUART0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+
+ MSS_UART_init( &g_mss_uart0_lo,
+ MSS_UART_115200_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx_string(&g_mss_uart0_lo ,
+ (const uint8_t*)"\r\nPlease observe UART-1 for application messages\r\n");
+
+ /* Raise software interrupt to wake hart 1 */
+ raise_soft_interrupt(1U);
+
+ __enable_irq();
+
+ while (1U)
+ {
+ icount++;
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ }
+ }
+ /* never return */
+}
+
+/* hart0 Software interrupt handler */
+void Software_h0_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h0++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart1/u54_1.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart1/u54_1.c
new file mode 100644
index 00000000..7817ed36
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart1/u54_1.c
@@ -0,0 +1,566 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_1
+ *
+ * PolarFire SoC MSS CAN example demonstrating the Data transmission and
+ * Reception using MSS CAN external loop back.
+ * For Transmission: Get data from Hyperterminal using MSSUART1 --> Form as CAN
+ * packets --> Send to CAN-0 to CAN-1.
+ * For Reception: Read the received message either from CAN-0 or CAN-1 -->
+ * Send to hyperterminal using MSSUART1.
+ *
+ * Board settings and test procedure clearly mentioned in README.md file.
+ *
+ */
+#include "stdio.h"
+#include "mpfs_hal/mss_hal.h"
+#include "drivers/mss/mss_can/mss_can.h"
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+/*------------------------------------------------------------------------------
+ * Macros.
+ */
+#define ENTER 0x0DU
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ */
+static void display_greeting(void);
+static uint8_t get_data_frm_uart(void);
+static void display_hex_values(const uint8_t *, uint32_t);
+static void ascii_to_hex(uint8_t *, uint32_t );
+static void display_option(void);
+static void check_rx_buffer(void);
+
+/*------------------------------------------------------------------------------
+ * Static Variables.
+ */
+static uint8_t g_uart_to_can[32];
+static uint8_t g_temp[64];
+static uint8_t g_can_to_uart[8];
+
+/*------------------------------------------------------------------------------
+ * Global Variables.
+ */
+mss_can_filterobject pfilter;
+mss_can_msgobject pmsg;
+mss_can_msgobject rx_buf;
+mss_can_rxmsgobject rx_msg;
+
+/*------------------------------------------------------------------------------
+ * MSS UART instance for UART1
+ */
+mss_uart_instance_t *g_uart= &g_mss_uart1_lo;
+
+uint64_t uart_lock;
+
+mss_can_instance_t* g_mss_can_0 = &g_mss_can_0_lo;
+mss_can_instance_t* g_mss_can_1 = &g_mss_can_1_lo;
+
+volatile uint32_t count_sw_ints_h1 = 0U;
+
+/******************************************************************************
+ * Greeting messages displayed over the UART.
+ */
+const uint8_t g_greeting_msg[] =
+"\n\r******************************************************************************\n\r\
+******* PolarFire SoC MSS CAN Driver Example (External loop back ) ***********\n\r\
+******************************************************************************\n\r\
+ Example project demonstrates the use of MSS CAN Transmission and Reception \n\r\
+ using external loop back. \n\r\
+------------------------------------------------------------------------------\n\r\
+ Read data from the UART1 and transmit as CAN message from CAN 0 to CAN 1 \n\r\
+------------------------------------------------------------------------------\n\r\
+ Receive the CAN Message from CAN 1 channel and send this to UART1\n\r\
+******************************************************************************\n\r";
+
+const uint8_t g_separator[] =
+"\r\n----------------------------------------------------------------------\r\n";
+
+/* Main function for the HART1(U54_1 processor).
+ * Application code running on HART1 is placed here
+ *
+ * The HART1 goes into WFI. HART0 brings it out of WFI when it raises the first
+ * Software interrupt to this HART
+ */
+void u54_1(void)
+{
+ uint8_t ret_status;
+ uint8_t rx_bytes = 0u;
+ uint8_t no_of_msgs = 0u;
+ uint8_t init_return_value = 0u;
+ uint8_t rx_char, count;
+ uint8_t loop_count;
+ uint32_t msg_len;
+ uint32_t chunk_size;
+ uint32_t error_flag;
+ uint32_t tx_status = 0u;
+ size_t rx_size;
+
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+#endif
+
+ /* The hart is out of WFI, clear the SW interrupt. Here onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ (void)mss_config_clk_rst(MSS_PERIPH_MMUART1, (uint8_t) 1, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_CAN0, (uint8_t) 1, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_CAN1, (uint8_t) 1, PERIPHERAL_ON);
+
+ PLIC_DisableIRQ(CAN0_PLIC);
+ PLIC_DisableIRQ(CAN1_PLIC);
+
+ PLIC_init();
+ __enable_irq();
+
+ MSS_UART_init(g_uart,
+ MSS_UART_115200_BAUD,
+ (MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY |
+ MSS_UART_ONE_STOP_BIT));
+
+ /*--------------------------------------------------------------------------
+ * Performs CAN Initialization and Message Buffer Configuration
+ */
+ /* ----------------------- CAN - 0 Initialization ----------------- */
+ init_return_value = MSS_CAN_init(g_mss_can_0, CAN_SPEED_8M_1M,
+ (pmss_can_config_reg)0, 6u, 6u);
+ MSS_CAN_set_mode(g_mss_can_0, CANOP_MODE_NORMAL);
+ MSS_CAN_start(g_mss_can_0);
+
+ /* ----------------------- CAN - 1 Initialization ----------------- */
+ init_return_value = MSS_CAN_init(g_mss_can_1, CAN_SPEED_8M_1M,
+ (pmss_can_config_reg)0, 6u, 6u);
+ MSS_CAN_set_mode(g_mss_can_1, CANOP_MODE_NORMAL);
+ MSS_CAN_start(g_mss_can_1);
+
+ /* Display greeting message */
+ display_greeting();
+
+ /* Clear receive buffer */
+ for (count = 0u; count < 8u; count++)
+ {
+ rx_buf.DATA[count] = 0u;
+ }
+
+ /* Configure for transmit */
+ pmsg.ID = 0x78u;
+ pmsg.DATALOW = 0xAAAAAAAAu;
+ pmsg.DATAHIGH = 0x55555555u;
+#ifdef CAN_TX_EXTENDED_ID
+ pmsg.L =((1<<20) | 0x00080000u); /* Extended ID, 8 bytes of data */
+#else
+ pmsg.L = 0x00080000u; /* Standard ID, 8 bytes of data */
+#endif
+
+ /* Configure for receive */
+ /* Initialize the rx mailbox */
+ rx_msg.ID = 0x80u;
+ rx_msg.DATAHIGH = 0u;
+ rx_msg.DATALOW = 0u;
+ rx_msg.AMR.L = 0xFFFFFFFFu;
+ rx_msg.ACR.L = 0x00000000u;
+ rx_msg.AMR_D = 0xFFFFFFFFu;
+ rx_msg.ACR_D = 0x00000000u;
+ rx_msg.RXB.DLC = 8u;
+ rx_msg.RXB.IDE = 0u;
+
+ /* Configure receive buffer For CAN 0 */
+ ret_status = MSS_CAN_config_buffer_n(g_mss_can_0, 0, &rx_msg);
+ if (CAN_OK != ret_status)
+ {
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r CAN 0 Message Buffer configuration Error");
+ }
+
+ /* Configure receive buffer For CAN 1 */
+ rx_msg.ID = 0x78u;
+ ret_status = MSS_CAN_config_buffer_n(g_mss_can_1, 1, &rx_msg);
+ if (CAN_OK != ret_status)
+ {
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r CAN 1 Message Buffer configuration Error");
+ }
+
+ while (1)
+ {
+ /*----------------------------------------------------------------------
+ * Read the Data from UART and Transmit using CAN
+ */
+ rx_bytes = get_data_frm_uart();
+
+ /* Convert ASCII values to Hex */
+ ascii_to_hex(g_temp, rx_bytes);
+
+ for (loop_count = 0u; loop_count < rx_bytes / 2u; loop_count++)
+ {
+ g_uart_to_can[loop_count] = g_temp[loop_count * 2u];
+ g_uart_to_can[loop_count] = g_uart_to_can[loop_count] << 4u;
+ g_uart_to_can[loop_count] |= g_temp[(loop_count * 2u) + 1u];
+ }
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r Data transmitted as CAN Message ");
+ display_hex_values(g_uart_to_can, loop_count);
+
+ /*------------------------------------------------------------------
+ Identify the number of messages to transmit based on rx_bytes
+ */
+ no_of_msgs = rx_bytes / 16u;
+ if ((rx_bytes % 16u) != 0)
+ {
+ no_of_msgs = no_of_msgs + 1u;
+ }
+
+ if (0u == loop_count) /* Allow sending an empty packet */
+ {
+ no_of_msgs = 1u;
+ }
+
+ count = 0u;
+
+ msg_len = loop_count;
+ error_flag = 0u;
+ while ((no_of_msgs != 0u) && (0u == error_flag))
+ {
+ /* Pack up to 8 bytes into this packet in 2 x 32bit chunks */
+ if (msg_len >= 8u)
+ {
+ chunk_size = 8u;
+ }
+ else
+ {
+ chunk_size = msg_len;
+ }
+
+ for (loop_count = 0u; loop_count < chunk_size; loop_count++)
+ {
+ if (loop_count < 4u)
+ {
+ pmsg.DATA[3u - loop_count] = \
+ g_uart_to_can[loop_count +(count * 8u)];
+ }
+ else
+ {
+ pmsg.DATA[11u - loop_count] = \
+ g_uart_to_can[loop_count + (count * 8u)];
+ }
+ }
+
+ pmsg.DLC = chunk_size;
+ ret_status = MSS_CAN_send_message_n(g_mss_can_0, 0u, &pmsg);
+ if (CAN_VALID_MSG != ret_status)
+ {
+ error_flag = 1; /* Didn't succeed in sending packet... */
+ }
+ else
+ {
+ /* Wait around for this packet to send before going any
+ * further */
+ tx_status = MSS_CAN_get_tx_buffer_status(g_mss_can_0);
+ while (1u == (tx_status & 1))
+ {
+ tx_status = MSS_CAN_get_tx_buffer_status(g_mss_can_0);
+ }
+
+ no_of_msgs--;
+ msg_len -= chunk_size;
+ count++;
+ }
+ }
+
+ if (0u == count) /* Nothing sent */
+ {
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r Unable to send data via CAN Bus");
+ }
+ else
+ {
+ if (0u == error_flag) /* Everything sent */
+ {
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r Observe the data received on CAN 1");
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r It should be same as the data "
+ "transmitted from Hyperterminal");
+ }
+ else /* Some error occurred */
+ {
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r Observe the data Received on CAN "
+ "1");
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\r Some transmission error(s) were "
+ "detected.");
+ }
+ }
+
+ MSS_UART_polled_tx_string (g_uart, g_separator);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r Press any key "
+ "to continue...");
+
+ do {
+ rx_size = MSS_UART_get_rx(g_uart, &rx_char, sizeof(rx_char));
+ } while (rx_size == 0u);
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+
+ /*----------------------------------------------------------------------
+ * Display options
+ */
+ display_option();
+ }
+}
+
+static void check_rx_buffer(void)
+{
+ uint8_t loop_count;
+
+ /*----------------------------------------------------------------------
+ Read the Data from CAN channel and Transmit Through UART
+ */
+ if (CAN_VALID_MSG == MSS_CAN_get_message_n(g_mss_can_0, 0u, &rx_buf))
+ {
+ for (loop_count = 0u; loop_count < rx_buf.DLC; loop_count++)
+ {
+ if (loop_count < 4u)
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[3u - loop_count];
+ }
+ else
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[11u - loop_count];
+ }
+ }
+
+ MSS_UART_polled_tx_string (g_uart, g_separator);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\r Data Received "
+ "as CAN-0 Message is ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r ");
+
+ /* Send to UART */
+ display_hex_values(g_can_to_uart, rx_buf.DLC);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\r Observe the "
+ "message sent from the CAN Analyzer ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\r It should be "
+ " same as message Received on Hyperterminal");
+ MSS_UART_polled_tx_string (g_uart, g_separator);
+ }
+}
+
+static void can1_check_rx_buffer(void)
+{
+ uint8_t loop_count;
+
+ /*----------------------------------------------------------------------
+ Read the Data from CAN channel and Transmit Through UART
+ */
+ if (CAN_VALID_MSG == MSS_CAN_get_message_n(g_mss_can_1, 1u, &rx_buf))
+ {
+ for (loop_count = 0u; loop_count < rx_buf.DLC; loop_count++)
+ {
+ if (loop_count < 4u)
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[3u - loop_count];
+ }
+ else
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[11u - loop_count];
+ }
+ }
+
+ MSS_UART_polled_tx_string (g_uart, g_separator);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\r Data Received "
+ "as CAN 1 Message is ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r ");
+
+ /* Send to UART */
+ display_hex_values(g_can_to_uart, rx_buf.DLC);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\r Observe the"
+ "message sent from the CAN 0 ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\r It should be "
+ "same as message Received on Hyperterminal");
+ MSS_UART_polled_tx_string (g_uart, g_separator);
+ }
+}
+
+/*------------------------------------------------------------------------------
+ Receive the data from UART
+ */
+static uint8_t get_data_frm_uart(void)
+{
+ uint8_t complete = 0;
+ uint8_t rx_buff[1];
+ uint8_t count = 0;
+ uint8_t rx_size = 0;
+
+ for (count = 0u; count < 32u; count++)
+ {
+ g_uart_to_can[count] = 0u;
+ }
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\r\n Enter the data to "
+ "transmit through the CAN Channel:\r\n ");
+
+ count = 0u;
+ while (!complete)
+ {
+ rx_size = MSS_UART_get_rx(g_uart, rx_buff, sizeof(rx_buff));
+ if(rx_size > 0u)
+ {
+ MSS_UART_polled_tx(g_uart, rx_buff, sizeof(rx_buff));
+
+ if (ENTER == rx_buff[0])
+ {
+ complete = 1u;
+ }
+ else
+ {
+ if (count % 2u == 0u)
+ {
+ g_temp[count] = rx_buff[0];
+ }
+ else
+ {
+ g_temp[count] = rx_buff[0];
+ }
+
+ count++;
+ }
+
+ if (64u == count)
+ {
+ complete = 1u;
+ }
+ }
+ }
+
+ return(count);
+}
+
+/*------------------------------------------------------------------------------
+ Display greeting message when application is started.
+ */
+static void display_greeting(void)
+{
+ MSS_UART_polled_tx_string (g_uart, g_greeting_msg);
+}
+
+/*------------------------------------------------------------------------------
+ Display content of buffer passed as parameter as hex values
+ */
+static void display_hex_values
+(
+ const uint8_t * in_buffer,
+ uint32_t byte_length
+)
+{
+ uint8_t display_buffer[128];
+ uint32_t inc;
+
+ if (0u == byte_length)
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)" \n\r");
+ }
+ else
+ {
+ if (byte_length > 16u)
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r ");
+ }
+
+ for (inc = 0u; inc < byte_length; ++inc)
+ {
+ if ((inc > 1u) && (0u == (inc % 16u)))
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+ }
+ snprintf((char *)display_buffer, sizeof(display_buffer), "%02x ",
+ in_buffer[inc]);
+ MSS_UART_polled_tx_string(g_uart, display_buffer);
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ Converts ASCII values to HEX values
+ */
+static void ascii_to_hex
+(
+ uint8_t * in_buffer,
+ uint32_t byte_length
+)
+{
+ uint32_t inc;
+
+ for (inc = 0u; inc < byte_length; inc++)
+ {
+ if ((in_buffer[inc] <= 0x39u) && (in_buffer[inc] >= 0x30u))
+ {
+ in_buffer[inc] = in_buffer[inc] - 0x30u;
+ }
+ else if ((in_buffer[inc] <= 0x5Au) && (in_buffer[inc] >= 0x41u))
+ {
+ in_buffer[inc] = 0x0Au + in_buffer[inc] - 0x41u;
+ }
+ else if ((in_buffer[inc] <= 0x7Au) && (in_buffer[inc] >= 0x61u))
+ {
+ in_buffer[inc] = 0x0au + (in_buffer[inc] - 0x61u);
+ }
+ else
+ {
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ Display the Option to continue or exit.
+ */
+static void display_option(void)
+{
+ uint8_t rx_size=0;
+ uint8_t rx_buff[1];
+
+ /*----------------------------------------------------------------------
+ Read the Data from CAN channel and Transmit Through UART1
+ */
+ check_rx_buffer();
+ can1_check_rx_buffer();
+
+ MSS_UART_polled_tx_string (g_uart, g_separator);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r Select the Option "
+ "to proceed further \n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)" Press Key '7' to send "
+ " data.\n\r");
+ MSS_UART_polled_tx_string (g_uart, g_separator);
+ do
+ {
+ /* Start command line interface if any key is pressed. */
+ rx_size = MSS_UART_get_rx(g_uart, rx_buff, sizeof(rx_buff));
+ if (rx_size > 0u)
+ {
+ switch(rx_buff[0])
+ {
+ case '7':
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ } while (rx_buff[0]!= '7');
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart2/u54_2.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart2/u54_2.c
new file mode 100644
index 00000000..2e8c0501
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart2/u54_2.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_2
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h2 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart2(U54_2 processor).
+ * Application code running on hart2 is placed here
+ *
+ * The hart2 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart
+ */
+void u54_2(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart2 Software interrupt handler */
+void Software_h2_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h2++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart3/u54_3.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart3/u54_3.c
new file mode 100644
index 00000000..2ec3349a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart3/u54_3.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_3
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h3 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart3(U54_3 processor).
+ * Application code running on hart3 is placed here
+ *
+ * The hart3 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart.
+ */
+void u54_3(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ }while(0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart3 software interrupt handler */
+void Software_h3_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h3++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart4/u54_4.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart4/u54_4.c
new file mode 100644
index 00000000..d70724e8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/hart4/u54_4.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_4
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h4 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart4(U54_4 processor).
+ * Application code running on hart4 is placed here
+ *
+ * The hart4 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart.
+ */
+void u54_4(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart4 software interrupt handler */
+void Software_h4_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h4++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/application/inc/common.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/inc/common.h
new file mode 100644
index 00000000..7c9b923a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/application/inc/common.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef COMMON_H_
+#define COMMON_H_
+
+#include
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+typedef enum COMMAND_TYPE_
+{
+ CLEAR_COMMANDS = 0x00, /*!< 0 default behavior */
+ START_HART1_U_MODE = 0x01, /*!< 1 u mode */
+ START_HART2_S_MODE = 0x02, /*!< 2 s mode */
+} COMMAND_TYPE;
+
+
+typedef enum MODE_CHOICE_
+{
+ M_MODE = 0x00, /*!< 0 m mode */
+ S_MODE = 0x01, /*!< s mode */
+} MODE_CHOICE;
+
+
+typedef struct HART_SHARED_DATA_
+{
+ uint64_t init_marker;
+ volatile long mutex_uart0;
+ mss_uart_instance_t *g_mss_uart0_lo;
+} HART_SHARED_DATA;
+
+/**
+ * extern variables
+ */
+
+/**
+ * functions
+ */
+void jump_to_application(HLS_DATA* hls, MODE_CHOICE mode_choice, uint64_t next_addr);
+void
+uart_tx_with_mutex
+(
+ mss_uart_instance_t * this_uart,
+ uint64_t mutex_addr,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+void
+uart_tx_string_with_mutex
+(
+ mss_uart_instance_t * this_uart,
+ uint64_t mutex_addr,
+ const uint8_t * pbuff
+);
+
+#endif /* COMMON_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
new file mode 100644
index 00000000..7e0a4bc5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
@@ -0,0 +1,4024 @@
+
+
+ 2021.1
+ ICICLE_MSS
+ MPFS250T_ES
+ FCVG484
+ 06-22-2021_18:26:34
+ 0.5.3
+
+
+
+
+
+
+ 0x1
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0xB
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x4
+
+
+
+
+
+
+ 0x00
+ 0x0
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+
+
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0
+
+
+ 220
+
+
+ 0
+
+
+ 511
+
+
+
+
+
+
+
+
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0xF
+ 0xF
+
+
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+
+
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0xC
+ 0xC
+ 0x8
+ 0x8
+
+
+ 0x2
+ 0x2
+ 0x2
+ 0x2
+ 0x7
+ 0x7
+ 0x7
+ 0xF
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xD
+ 0x00
+ 0xA
+ 0x0
+ 0x4
+ 0x0
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x7
+ 0x00
+ 0x9
+ 0x0
+ 0x8
+ 0x0
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x3F
+ 0x00
+ 0x3F
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x3F
+ 0x00
+ 0x3F
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x2
+ 0x9
+ 0x1
+ 0x1
+ 0x00
+ 0x1
+ 0x1
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x14
+ 0x0
+ 0x2
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x7
+ 0x7
+ 0x7
+ 0x0
+ 0x0
+ 0x0
+ 0x4
+ 0x7
+ 0x7
+ 0x3
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x7
+ 0x7
+ 0x7
+ 0x0
+ 0x0
+ 0x0
+ 0x4
+ 0x7
+ 0x7
+ 0x3
+ 0x0
+
+
+ 0x8
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x0
+
+
+
+
+
+
+
+
+
+
+ 0x0
+ 0x3
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0xf000
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x0
+ 0x0
+
+
+ 0xFF000000
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x2
+ 0x5
+ 0x0
+ 0x7F
+ 0x1F
+
+
+ 0x02
+
+
+
+
+
+
+ 0x2
+ 0x2
+ 0x1
+ 0x0
+ 0xC
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x6
+
+
+ 0x6
+
+
+ 0x2
+
+
+ 0x2
+
+
+ 0x5
+
+
+ 0x5
+
+
+ 0x7
+
+
+ 0x7
+
+
+ 0x7
+
+
+ 0x3
+
+
+ 0x4
+
+
+ 0x3
+
+
+ 0x4
+
+
+ 0x8000
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+
+
+
+
+ 0x4
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x2
+ 0x2
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x4
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x7F80
+ 0x0
+ 0x1
+
+
+ 0x7030
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x7FB0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x1
+
+
+ 0x7FA0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+
+
+ 0x00001D
+
+
+ 0x00000000
+
+
+ 0x00000004
+
+
+ 0x0000000A
+
+
+ 0x00C2CA
+
+
+ 0x0
+
+
+ 0x9140F38D
+
+
+ 0x75955134
+
+
+ 0x71B69961
+
+
+ 0x000
+
+
+ 0x440C2040
+
+
+ 0x02481C61
+
+
+ 0x00000000
+
+
+ 0x00000140
+
+
+ 0x000000A0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x6
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x00000001
+
+
+ 0x00000016
+
+
+ 0x00000016
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000005
+
+
+ 0x00000006
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000004
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000006
+
+
+ 0x00000036
+
+
+ 0x00000036
+
+
+ 0x00000036
+
+
+ 0x0
+
+
+ 0x81881881
+
+
+ 0x00008818
+
+
+ 0xa92a92a9
+
+
+ 0x00002a92
+
+
+ 0xc28c28c2
+
+
+ 0x00008c28
+
+
+ 0xea2ea2ea
+
+
+ 0x00002ea2
+
+
+ 0x03903903
+
+
+ 0x00009039
+
+
+ 0x2b32b32b
+
+
+ 0x000032b3
+
+
+ 0x44944944
+
+
+ 0x00009449
+
+
+ 0x6c36c36c
+
+
+ 0x000036c3
+
+
+ 0x85985985
+
+
+ 0x00009859
+
+
+ 0xad3ad3ad
+
+
+ 0x00003ad3
+
+
+ 0xc69c69c6
+
+
+ 0x00009c69
+
+
+ 0xee3ee3ee
+
+
+ 0x00003ee3
+
+
+ 0x07a07a07
+
+
+ 0x0000a07a
+
+
+ 0x2f42f42f
+
+
+ 0x000042f4
+
+
+ 0x48a48a48
+
+
+ 0x0000a48a
+
+
+ 0x70470470
+
+
+ 0x00004704
+
+
+ 0x00000000
+
+
+ 0x00000048
+
+
+ 0x0000002C
+
+
+ 0x00000020
+
+
+ 0x00000004
+
+
+ 0x00000010
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x22
+
+
+ 0xF
+
+
+ 0x8
+
+
+ 0x11
+
+
+ 0x33
+
+
+ 0x20
+
+
+ 0x130
+
+
+ 0x8
+
+
+ 0x10
+
+
+ 0x8
+
+
+ 0x0
+
+
+ 0x6
+
+
+ 0x1F
+
+
+ 0x5
+
+
+ 0xF
+
+
+ 0xF
+
+
+ 0xF
+
+
+ 0x1F
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x7
+
+
+ 0xC
+
+
+ 0x0
+
+
+ 0x6
+
+
+ 0x0
+
+
+ 0x2
+
+
+ 0x0
+
+
+ 0xC34
+
+
+ 0x27100
+
+
+ 0xA
+
+
+ 0x10
+
+
+ 0x3
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0xC
+
+
+ 0x5
+
+
+ 0x00000200
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x27100
+
+
+ 0x0
+
+
+ 0x400
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x640
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x28
+
+
+ 0x8
+
+
+ 0xA
+
+
+ 0x00000000
+
+
+ 0x8
+
+
+ 0xE
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x2
+
+
+ 0x4
+
+
+ 0x18
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x320
+
+
+ 0x12
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000008
+
+
+ 0x0000000b
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x000000FF
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x15
+
+
+ 0x6
+
+
+ 0x3
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x7FFFFFFF
+
+
+ 0x0
+
+
+ 0x7FFFFFFF
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x8001
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x3F
+
+
+ 0x3F
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x18
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+
+
+
+
+
+
+ 125000000
+
+
+ 600000000
+
+
+ 600000000
+
+
+ 1000000
+
+
+ 300000000
+
+
+ 150000000
+
+
+
+
+
+
+ 0x0
+ 0x1
+ 0x2
+
+
+ 0x7D
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x40
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x5
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x4B
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x60
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x2
+ 0x4
+ 0x6
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x14
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ DDR3
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x5
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x80
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x8
+ 0x10
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x0
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+ 0x3
+ 0x0
+ 0x7
+ 0x0
+ 0xF
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_ddr_pll.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_ddr_pll.h
new file mode 100644
index 00000000..f7b08bbc
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_ddr_pll.h
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_clk_ddr_pll.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_CLK_DDR_PLL_H_
+#define HW_CLK_DDR_PLL_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_DDR_SOFT_RESET)
+/*This is a compulsory register for all SCB slaves and must be at the same
+offset in all slaves to facilitate global soft reset of all SCB registers with
+a single broadcast write from the SCB master. */
+#define LIBERO_SETTING_DDR_SOFT_RESET 0x00000000UL
+ /* NV_MAP [0:1] RST */
+ /* V_MAP [1:1] RST */
+ /* PERIPH [8:1] RST */
+ /* BLOCKID [16:16] ID */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_CTRL)
+/*PLL control register */
+#define LIBERO_SETTING_DDR_PLL_CTRL 0x0100003FUL
+ /* REG_POWERDOWN_B [0:1] RW value= 0x1 */
+ /* REG_RFDIV_EN [1:1] RW value= 0x1 */
+ /* REG_DIVQ0_EN [2:1] RW value= 0x1 */
+ /* REG_DIVQ1_EN [3:1] RW value= 0x1 */
+ /* REG_DIVQ2_EN [4:1] RW value= 0x1 */
+ /* REG_DIVQ3_EN [5:1] RW value= 0x1 */
+ /* REG_RFCLK_SEL [6:1] RW value= 0x0 */
+ /* RESETONLOCK [7:1] RW value= 0x0 */
+ /* BYPCK_SEL [8:4] RW value= 0x0 */
+ /* REG_BYPASS_GO_B [12:1] RW value= 0x0 */
+ /* RESERVE10 [13:3] RSVD */
+ /* REG_BYPASSPRE [16:4] RW value= 0x0 */
+ /* REG_BYPASSPOST [20:4] RW value= 0x0 */
+ /* LP_REQUIRES_LOCK [24:1] RW value= 0x1 */
+ /* LOCK [25:1] RO */
+ /* LOCK_INT_EN [26:1] RW value= 0x0 */
+ /* UNLOCK_INT_EN [27:1] RW value= 0x0 */
+ /* LOCK_INT [28:1] SW1C */
+ /* UNLOCK_INT [29:1] SW1C */
+ /* RESERVE11 [30:1] RSVD */
+ /* LOCK_B [31:1] RO */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_REF_FB)
+/*PLL reference and feedback registers */
+#define LIBERO_SETTING_DDR_PLL_REF_FB 0x00000500UL
+ /* FSE_B [0:1] RW value= 0x0 */
+ /* FBCK_SEL [1:2] RW value= 0x0 */
+ /* FOUTFB_SELMUX_EN [3:1] RW value= 0x0 */
+ /* RESERVE12 [4:4] RSVD */
+ /* RFDIV [8:6] RW value= 0x5 */
+ /* RESERVE13 [14:2] RSVD */
+ /* RESERVE14 [16:12] RSVD */
+ /* RESERVE15 [28:4] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_FRACN)
+/*PLL fractional register */
+#define LIBERO_SETTING_DDR_PLL_FRACN 0x00000000UL
+ /* FRACN_EN [0:1] RW value= 0x0 */
+ /* FRACN_DAC_EN [1:1] RW value= 0x0 */
+ /* RESERVE16 [2:6] RSVD */
+ /* RESERVE17 [8:24] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_DIV_0_1)
+/*PLL 0/1 division registers */
+#define LIBERO_SETTING_DDR_PLL_DIV_0_1 0x02000100UL
+ /* VCO0PH_SEL [0:3] RO */
+ /* DIV0_START [3:3] RW value= 0x0 */
+ /* RESERVE18 [6:2] RSVD */
+ /* POST0DIV [8:7] RW value= 0x1 */
+ /* RESERVE19 [15:1] RSVD */
+ /* VCO1PH_SEL [16:3] RO */
+ /* DIV1_START [19:3] RW value= 0x0 */
+ /* RESERVE20 [22:2] RSVD */
+ /* POST1DIV [24:7] RW value= 0x2 */
+ /* RESERVE21 [31:1] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_DIV_2_3)
+/*PLL 2/3 division registers */
+#define LIBERO_SETTING_DDR_PLL_DIV_2_3 0x01000100UL
+ /* VCO2PH_SEL [0:3] RO */
+ /* DIV2_START [3:3] RW value= 0x0 */
+ /* RESERVE22 [6:2] RSVD */
+ /* POST2DIV [8:7] RW value= 0x1 */
+ /* RESERVE23 [15:1] RSVD */
+ /* VCO3PH_SEL [16:3] RO */
+ /* DIV3_START [19:3] RW value= 0x0 */
+ /* RESERVE24 [22:2] RSVD */
+ /* POST3DIV [24:7] RW value= 0x1 */
+ /* CKPOST3_SEL [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_CTRL2)
+/*PLL control register */
+#define LIBERO_SETTING_DDR_PLL_CTRL2 0x00001020UL
+ /* BWI [0:2] RW value= 0x0 */
+ /* BWP [2:2] RW value= 0x0 */
+ /* IREF_EN [4:1] RW value= 0x0 */
+ /* IREF_TOGGLE [5:1] RW value= 0x1 */
+ /* RESERVE25 [6:3] RSVD */
+ /* LOCKCNT [9:4] RW value= 0x8 */
+ /* RESERVE26 [13:4] RSVD */
+ /* ATEST_EN [17:1] RW value= 0x0 */
+ /* ATEST_SEL [18:3] RW value= 0x0 */
+ /* RESERVE27 [21:11] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_CAL)
+/*PLL calibration register */
+#define LIBERO_SETTING_DDR_PLL_CAL 0x00000D06UL
+ /* DSKEWCALCNT [0:3] RW value= 0x6 */
+ /* DSKEWCAL_EN [3:1] RW value= 0x0 */
+ /* DSKEWCALBYP [4:1] RW value= 0x0 */
+ /* RESERVE28 [5:3] RSVD */
+ /* DSKEWCALIN [8:7] RW value= 0xd */
+ /* RESERVE29 [15:1] RSVD */
+ /* DSKEWCALOUT [16:7] RO */
+ /* RESERVE30 [23:9] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_PLL_PHADJ)
+/*PLL phase registers */
+#define LIBERO_SETTING_DDR_PLL_PHADJ 0x00005003UL
+ /* PLL_REG_SYNCREFDIV_EN [0:1] RW value= 0x1 */
+ /* PLL_REG_ENABLE_SYNCREFDIV [1:1] RW value= 0x1 */
+ /* REG_OUT0_PHSINIT [2:3] RW value= 0x0 */
+ /* REG_OUT1_PHSINIT [5:3] RW value= 0x0 */
+ /* REG_OUT2_PHSINIT [8:3] RW value= 0x0 */
+ /* REG_OUT3_PHSINIT [11:3] RW value= 0x2 */
+ /* REG_LOADPHS_B [14:1] RW value= 0x1 */
+ /* RESERVE31 [15:17] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_SSCG_REG_0)
+/*SSCG registers 0 */
+#define LIBERO_SETTING_DDR_SSCG_REG_0 0x00000000UL
+ /* DIVVAL [0:6] RW value= 0x0 */
+ /* FRACIN [6:24] RW value= 0x0 */
+ /* RESERVE00 [30:2] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_SSCG_REG_1)
+/*SSCG registers 1 */
+#define LIBERO_SETTING_DDR_SSCG_REG_1 0x00000000UL
+ /* DOWNSPREAD [0:1] RW value= 0x0 */
+ /* SSMD [1:5] RW value= 0x0 */
+ /* FRACMOD [6:24] RO */
+ /* RESERVE01 [30:2] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_SSCG_REG_2)
+/*SSCG registers 2 */
+#define LIBERO_SETTING_DDR_SSCG_REG_2 0x00000080UL
+ /* INTIN [0:12] RW value= 0x80 */
+ /* INTMOD [12:12] RO */
+ /* RESERVE02 [24:8] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DDR_SSCG_REG_3)
+/*SSCG registers 3 */
+#define LIBERO_SETTING_DDR_SSCG_REG_3 0x00000001UL
+ /* SSE_B [0:1] RW value= 0x1 */
+ /* SEL_EXTWAVE [1:2] RW value= 0x0 */
+ /* EXT_MAXADDR [3:8] RW value= 0x0 */
+ /* TBLADDR [11:8] RO */
+ /* RANDOM_FILTER [19:1] RW value= 0x0 */
+ /* RANDOM_SEL [20:2] RW value= 0x0 */
+ /* RESERVE03 [22:1] RSVD */
+ /* RESERVE04 [23:9] RSVD */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_CLK_DDR_PLL_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_mss_cfm.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_mss_cfm.h
new file mode 100644
index 00000000..23b11b70
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_mss_cfm.h
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_clk_mss_cfm.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_CLK_MSS_CFM_H_
+#define HW_CLK_MSS_CFM_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MSS_BCLKMUX)
+/*Input mux selections */
+#define LIBERO_SETTING_MSS_BCLKMUX 0x00000208UL
+ /* BCLK0_SEL [0:5] RW value= 0x8 */
+ /* BCLK1_SEL [5:5] RW value= 0x10 */
+ /* BCLK2_SEL [10:5] RW value= 0x0 */
+ /* BCLK3_SEL [15:5] RW value= 0x0 */
+ /* BCLK4_SEL [20:5] RW value= 0x0 */
+ /* BCLK5_SEL [25:5] RW value= 0x0 */
+ /* RESERVED [30:2] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_CKMUX)
+/*Input mux selections */
+#define LIBERO_SETTING_MSS_PLL_CKMUX 0x00000155UL
+ /* CLK_IN_MAC_TSU_SEL [0:2] RW value= 0x1 */
+ /* PLL0_RFCLK0_SEL [2:2] RW value= 0x1 */
+ /* PLL0_RFCLK1_SEL [4:2] RW value= 0x1 */
+ /* PLL1_RFCLK0_SEL [6:2] RW value= 0x1 */
+ /* PLL1_RFCLK1_SEL [8:2] RW value= 0x1 */
+ /* PLL1_FDR_SEL [10:5] RW value= 0x0 */
+ /* RESERVED [15:17] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_MSSCLKMUX)
+/*MSS Clock mux selections */
+#define LIBERO_SETTING_MSS_MSSCLKMUX 0x00000003UL
+ /* MSSCLK_MUX_SEL [0:2] RW value= 0x3 */
+ /* MSSCLK_MUX_MD [2:2] RW value= 0x0 */
+ /* CLK_STANDBY_SEL [4:1] RW value= 0x0 */
+ /* RESERVED [5:27] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_SPARE0)
+/*spare logic */
+#define LIBERO_SETTING_MSS_SPARE0 0x00000000UL
+ /* SPARE0 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_FMETER_ADDR)
+/*Frequency_meter_address_selections */
+#define LIBERO_SETTING_MSS_FMETER_ADDR 0x00000000UL
+ /* ADDR10 [0:2] RSVD */
+ /* ADDR [2:4] RW value= 0x0 */
+ /* RESERVE18 [6:26] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_FMETER_DATAW)
+/*Frequency_meter_data_write */
+#define LIBERO_SETTING_MSS_FMETER_DATAW 0x00000000UL
+ /* DATA [0:24] RW value= 0x0 */
+ /* STROBE [24:1] W1P */
+ /* RESERVE19 [25:7] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_FMETER_DATAR)
+/*Frequency_meter_data_read */
+#define LIBERO_SETTING_MSS_FMETER_DATAR 0x00000000UL
+ /* DATA [0:24] RO */
+ /* RESERVE20 [24:8] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_IMIRROR_TRIM)
+/*Imirror TRIM Bits */
+#define LIBERO_SETTING_MSS_IMIRROR_TRIM 0x00000000UL
+ /* BG_CODE [0:3] RW value= 0x0 */
+ /* CC_CODE [3:8] RW value= 0x0 */
+ /* RESERVE21 [11:21] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_TEST_CTRL)
+/*Test MUX Controls */
+#define LIBERO_SETTING_MSS_TEST_CTRL 0x00000000UL
+ /* OSC_ENABLE [0:4] RW value= 0x0 */
+ /* ATEST_EN [4:1] RW value= 0x0 */
+ /* ATEST_SEL [5:5] RW value= 0x0 */
+ /* DTEST_EN [10:1] RW value= 0x0 */
+ /* DTEST_SEL [11:5] RW value= 0x0 */
+ /* RESERVE22 [16:16] RSVD */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_CLK_MSS_CFM_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_mss_pll.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_mss_pll.h
new file mode 100644
index 00000000..7f4d2e66
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_mss_pll.h
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_clk_mss_pll.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_CLK_MSS_PLL_H_
+#define HW_CLK_MSS_PLL_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MSS_PLL_CTRL)
+/*PLL control register */
+#define LIBERO_SETTING_MSS_PLL_CTRL 0x01000037UL
+ /* REG_POWERDOWN_B [0:1] RW value= 0x1 */
+ /* REG_RFDIV_EN [1:1] RW value= 0x1 */
+ /* REG_DIVQ0_EN [2:1] RW value= 0x1 */
+ /* REG_DIVQ1_EN [3:1] RW value= 0x0 */
+ /* REG_DIVQ2_EN [4:1] RW value= 0x1 */
+ /* REG_DIVQ3_EN [5:1] RW value= 0x1 */
+ /* REG_RFCLK_SEL [6:1] RW value= 0x0 */
+ /* RESETONLOCK [7:1] RW value= 0x0 */
+ /* BYPCK_SEL [8:4] RW value= 0x0 */
+ /* REG_BYPASS_GO_B [12:1] RW value= 0x0 */
+ /* RESERVE10 [13:3] RSVD */
+ /* REG_BYPASSPRE [16:4] RW value= 0x0 */
+ /* REG_BYPASSPOST [20:4] RW value= 0x0 */
+ /* LP_REQUIRES_LOCK [24:1] RW value= 0x1 */
+ /* LOCK [25:1] RO */
+ /* LOCK_INT_EN [26:1] RW value= 0x0 */
+ /* UNLOCK_INT_EN [27:1] RW value= 0x0 */
+ /* LOCK_INT [28:1] SW1C */
+ /* UNLOCK_INT [29:1] SW1C */
+ /* RESERVE11 [30:1] RSVD */
+ /* LOCK_B [31:1] RO */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_REF_FB)
+/*PLL reference and feedback registers */
+#define LIBERO_SETTING_MSS_PLL_REF_FB 0x00000500UL
+ /* FSE_B [0:1] RW value= 0x0 */
+ /* FBCK_SEL [1:2] RW value= 0x0 */
+ /* FOUTFB_SELMUX_EN [3:1] RW value= 0x0 */
+ /* RESERVE12 [4:4] RSVD */
+ /* RFDIV [8:6] RW value= 0x5 */
+ /* RESERVE13 [14:2] RSVD */
+ /* RESERVE14 [16:12] RSVD */
+ /* RESERVE15 [28:4] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_FRACN)
+/*PLL fractional register */
+#define LIBERO_SETTING_MSS_PLL_FRACN 0x00000000UL
+ /* FRACN_EN [0:1] RW value= 0x0 */
+ /* FRACN_DAC_EN [1:1] RW value= 0x0 */
+ /* RESERVE16 [2:6] RSVD */
+ /* RESERVE17 [8:24] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_DIV_0_1)
+/*PLL 0/1 division registers */
+#define LIBERO_SETTING_MSS_PLL_DIV_0_1 0x01000100UL
+ /* VCO0PH_SEL [0:3] RO */
+ /* DIV0_START [3:3] RW value= 0x0 */
+ /* RESERVE18 [6:2] RSVD */
+ /* POST0DIV [8:7] RW value= 0x1 */
+ /* RESERVE19 [15:1] RSVD */
+ /* VCO1PH_SEL [16:3] RO */
+ /* DIV1_START [19:3] RW value= 0x0 */
+ /* RESERVE20 [22:2] RSVD */
+ /* POST1DIV [24:7] RW value= 0x1 */
+ /* RESERVE21 [31:1] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_DIV_2_3)
+/*PLL 2/3 division registers */
+#define LIBERO_SETTING_MSS_PLL_DIV_2_3 0x4B000300UL
+ /* VCO2PH_SEL [0:3] RO */
+ /* DIV2_START [3:3] RW value= 0x0 */
+ /* RESERVE22 [6:2] RSVD */
+ /* POST2DIV [8:7] RW value= 0x3 */
+ /* RESERVE23 [15:1] RSVD */
+ /* VCO3PH_SEL [16:3] RO */
+ /* DIV3_START [19:3] RW value= 0x0 */
+ /* RESERVE24 [22:2] RSVD */
+ /* POST3DIV [24:7] RW value= 0x4B */
+ /* CKPOST3_SEL [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_CTRL2)
+/*PLL control register */
+#define LIBERO_SETTING_MSS_PLL_CTRL2 0x00001020UL
+ /* BWI [0:2] RW value= 0x0 */
+ /* BWP [2:2] RW value= 0x0 */
+ /* IREF_EN [4:1] RW value= 0x0 */
+ /* IREF_TOGGLE [5:1] RW value= 0x1 */
+ /* RESERVE25 [6:3] RSVD */
+ /* LOCKCNT [9:4] RW value= 0x8 */
+ /* RESERVE26 [13:4] RSVD */
+ /* ATEST_EN [17:1] RW value= 0x0 */
+ /* ATEST_SEL [18:3] RW value= 0x0 */
+ /* RESERVE27 [21:11] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_CAL)
+/*PLL calibration register */
+#define LIBERO_SETTING_MSS_PLL_CAL 0x00000D06UL
+ /* DSKEWCALCNT [0:3] RW value= 0x6 */
+ /* DSKEWCAL_EN [3:1] RW value= 0x0 */
+ /* DSKEWCALBYP [4:1] RW value= 0x0 */
+ /* RESERVE28 [5:3] RSVD */
+ /* DSKEWCALIN [8:7] RW value= 0xd */
+ /* RESERVE29 [15:1] RSVD */
+ /* DSKEWCALOUT [16:7] RO */
+ /* RESERVE30 [23:9] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_PLL_PHADJ)
+/*PLL phase registers */
+#define LIBERO_SETTING_MSS_PLL_PHADJ 0x00004003UL
+ /* PLL_REG_SYNCREFDIV_EN [0:1] RW value= 0x1 */
+ /* PLL_REG_ENABLE_SYNCREFDIV [1:1] RW value= 0x1 */
+ /* REG_OUT0_PHSINIT [2:3] RW value= 0x0 */
+ /* REG_OUT1_PHSINIT [5:3] RW value= 0x0 */
+ /* REG_OUT2_PHSINIT [8:3] RW value= 0x0 */
+ /* REG_OUT3_PHSINIT [11:3] RW value= 0x8 */
+ /* REG_LOADPHS_B [14:1] RW value= 0x0 */
+ /* RESERVE31 [15:17] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_SSCG_REG_0)
+/*SSCG registers 0 */
+#define LIBERO_SETTING_MSS_SSCG_REG_0 0x00000000UL
+ /* DIVVAL [0:6] RW value= 0x0 */
+ /* FRACIN [6:24] RW value= 0x0 */
+ /* RESERVE00 [30:2] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_SSCG_REG_1)
+/*SSCG registers 1 */
+#define LIBERO_SETTING_MSS_SSCG_REG_1 0x00000000UL
+ /* DOWNSPREAD [0:1] RW value= 0x0 */
+ /* SSMD [1:5] RW value= 0x0 */
+ /* FRACMOD [6:24] RO */
+ /* RESERVE01 [30:2] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_SSCG_REG_2)
+/*SSCG registers 2 */
+#define LIBERO_SETTING_MSS_SSCG_REG_2 0x00000060UL
+ /* INTIN [0:12] RW value= 0x60 */
+ /* INTMOD [12:12] RO */
+ /* RESERVE02 [24:8] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_MSS_SSCG_REG_3)
+/*SSCG registers 3 */
+#define LIBERO_SETTING_MSS_SSCG_REG_3 0x00000001UL
+ /* SSE_B [0:1] RW value= 0x1 */
+ /* SEL_EXTWAVE [1:2] RW value= 0x0 */
+ /* EXT_MAXADDR [3:8] RW value= 0x0 */
+ /* TBLADDR [11:8] RO */
+ /* RANDOM_FILTER [19:1] RW value= 0x0 */
+ /* RANDOM_SEL [20:2] RW value= 0x0 */
+ /* RESERVE03 [22:1] RSVD */
+ /* RESERVE04 [23:9] RSVD */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_CLK_MSS_PLL_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sgmii_cfm.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sgmii_cfm.h
new file mode 100644
index 00000000..49748e25
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sgmii_cfm.h
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_clk_sgmii_cfm.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_CLK_SGMII_CFM_H_
+#define HW_CLK_SGMII_CFM_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_SGMII_REFCLKMUX)
+/*Input mux selections */
+#define LIBERO_SETTING_SGMII_REFCLKMUX 0x00000005UL
+ /* PLL0_RFCLK0_SEL [0:2] RW value= 0x1 */
+ /* PLL0_RFCLK1_SEL [2:2] RW value= 0x1 */
+ /* RESERVED [4:28] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_SGMII_CLKMUX)
+/*sgmii clk mux */
+#define LIBERO_SETTING_SGMII_SGMII_CLKMUX 0x00000005UL
+ /* SGMII_CLKMUX [0:32] RW value= 0x5 */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_SPARE0)
+/*spare logic */
+#define LIBERO_SETTING_SGMII_SPARE0 0x00000000UL
+ /* RESERVED [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_CLK_XCVR)
+/*Clock_Receiver */
+#define LIBERO_SETTING_SGMII_CLK_XCVR 0x00002C30UL
+ /* EN_UDRIVE_P [0:1] RW value= 0x0 */
+ /* EN_INS_HYST_P [1:1] RW value= 0x0 */
+ /* EN_TERM_P [2:2] RW value= 0x0 */
+ /* EN_RXMODE_P [4:2] RW value= 0x3 */
+ /* EN_UDRIVE_N [6:1] RW value= 0x0 */
+ /* EN_INS_HYST_N [7:1] RW value= 0x0 */
+ /* EN_TERM_N [8:2] RW value= 0x0 */
+ /* EN_RXMODE_N [10:2] RW value= 0x3 */
+ /* CLKBUF_EN_PULLUP [12:1] RW value= 0x0 */
+ /* EN_RDIFF [13:1] RW value= 0x1 */
+ /* RESERVED [14:18] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_TEST_CTRL)
+/*Test MUX Controls */
+#define LIBERO_SETTING_SGMII_TEST_CTRL 0x00000000UL
+ /* OSC_ENABLE [0:4] RW value= 0x0 */
+ /* ATEST_EN [4:1] RW value= 0x0 */
+ /* ATEST_SEL [5:5] RW value= 0x0 */
+ /* DTEST_EN [10:1] RW value= 0x0 */
+ /* DTEST_SEL [11:5] RW value= 0x0 */
+ /* RESERVE22 [16:16] RSVD */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_CLK_SGMII_CFM_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sgmii_pll.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sgmii_pll.h
new file mode 100644
index 00000000..ec9cd37b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sgmii_pll.h
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_clk_sgmii_pll.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_CLK_SGMII_PLL_H_
+#define HW_CLK_SGMII_PLL_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_SGMII_SOFT_RESET)
+/*This is a compulsory register for all SCB slaves and must be at the same
+offset in all slaves to facilitate global soft reset of all SCB registers with
+a single broadcast write from the SCB master. */
+#define LIBERO_SETTING_SGMII_SOFT_RESET 0x00000000UL
+ /* NV_MAP [0:1] RST */
+ /* V_MAP [1:1] RST */
+ /* PERIPH [8:1] RST */
+ /* BLOCKID [16:16] ID */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_CTRL)
+/*PLL control register */
+#define LIBERO_SETTING_SGMII_PLL_CTRL 0x0100003FUL
+ /* REG_POWERDOWN_B [0:1] RW value= 0x1 */
+ /* REG_RFDIV_EN [1:1] RW value= 0x1 */
+ /* REG_DIVQ0_EN [2:1] RW value= 0x1 */
+ /* REG_DIVQ1_EN [3:1] RW value= 0x1 */
+ /* REG_DIVQ2_EN [4:1] RW value= 0x1 */
+ /* REG_DIVQ3_EN [5:1] RW value= 0x1 */
+ /* REG_RFCLK_SEL [6:1] RW value= 0x0 */
+ /* RESETONLOCK [7:1] RW value= 0x0 */
+ /* BYPCK_SEL [8:4] RW value= 0x0 */
+ /* REG_BYPASS_GO_B [12:1] RW value= 0x0 */
+ /* RESERVE10 [13:3] RSVD */
+ /* REG_BYPASSPRE [16:4] RW value= 0x0 */
+ /* REG_BYPASSPOST [20:4] RW value= 0x0 */
+ /* LP_REQUIRES_LOCK [24:1] RW value= 0x1 */
+ /* LOCK [25:1] RO */
+ /* LOCK_INT_EN [26:1] RW value= 0x0 */
+ /* UNLOCK_INT_EN [27:1] RW value= 0x0 */
+ /* LOCK_INT [28:1] SW1C */
+ /* UNLOCK_INT [29:1] SW1C */
+ /* RESERVE11 [30:1] RSVD */
+ /* LOCK_B [31:1] RO */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_REF_FB)
+/*PLL reference and feedback registers */
+#define LIBERO_SETTING_SGMII_PLL_REF_FB 0x00000100UL
+ /* FSE_B [0:1] RW value= 0x0 */
+ /* FBCK_SEL [1:2] RW value= 0x0 */
+ /* FOUTFB_SELMUX_EN [3:1] RW value= 0x0 */
+ /* RESERVE12 [4:4] RSVD */
+ /* RFDIV [8:6] RW value= 0x1 */
+ /* RESERVE13 [14:2] RSVD */
+ /* RESERVE14 [16:12] RSVD */
+ /* RESERVE15 [28:4] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_FRACN)
+/*PLL fractional register */
+#define LIBERO_SETTING_SGMII_PLL_FRACN 0x00000000UL
+ /* FRACN_EN [0:1] RW value= 0x0 */
+ /* FRACN_DAC_EN [1:1] RW value= 0x0 */
+ /* RESERVE16 [2:6] RSVD */
+ /* RESERVE17 [8:24] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_DIV_0_1)
+/*PLL 0/1 division registers */
+#define LIBERO_SETTING_SGMII_PLL_DIV_0_1 0x01000100UL
+ /* VCO0PH_SEL [0:3] RO */
+ /* DIV0_START [3:3] RW value= 0x0 */
+ /* RESERVE18 [6:2] RSVD */
+ /* POST0DIV [8:7] RW value= 0x1 */
+ /* RESERVE19 [15:1] RSVD */
+ /* VCO1PH_SEL [16:3] RO */
+ /* DIV1_START [19:3] RW value= 0x0 */
+ /* RESERVE20 [22:2] RSVD */
+ /* POST1DIV [24:7] RW value= 0x1 */
+ /* RESERVE21 [31:1] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_DIV_2_3)
+/*PLL 2/3 division registers */
+#define LIBERO_SETTING_SGMII_PLL_DIV_2_3 0x01000100UL
+ /* VCO2PH_SEL [0:3] RO */
+ /* DIV2_START [3:3] RW value= 0x0 */
+ /* RESERVE22 [6:2] RSVD */
+ /* POST2DIV [8:7] RW value= 0x1 */
+ /* RESERVE23 [15:1] RSVD */
+ /* VCO3PH_SEL [16:3] RO */
+ /* DIV3_START [19:3] RW value= 0x0 */
+ /* RESERVE24 [22:2] RSVD */
+ /* POST3DIV [24:7] RW value= 0x1 */
+ /* CKPOST3_SEL [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_CTRL2)
+/*PLL control register */
+#define LIBERO_SETTING_SGMII_PLL_CTRL2 0x00001020UL
+ /* BWI [0:2] RW value= 0x0 */
+ /* BWP [2:2] RW value= 0x0 */
+ /* IREF_EN [4:1] RW value= 0x0 */
+ /* IREF_TOGGLE [5:1] RW value= 0x1 */
+ /* RESERVE25 [6:3] RSVD */
+ /* LOCKCNT [9:4] RW value= 0x8 */
+ /* RESERVE26 [13:4] RSVD */
+ /* ATEST_EN [17:1] RW value= 0x0 */
+ /* ATEST_SEL [18:3] RW value= 0x0 */
+ /* RESERVE27 [21:11] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_CAL)
+/*PLL calibration register */
+#define LIBERO_SETTING_SGMII_PLL_CAL 0x00000D06UL
+ /* DSKEWCALCNT [0:3] RW value= 0x6 */
+ /* DSKEWCAL_EN [3:1] RW value= 0x0 */
+ /* DSKEWCALBYP [4:1] RW value= 0x0 */
+ /* RESERVE28 [5:3] RSVD */
+ /* DSKEWCALIN [8:7] RW value= 0xd */
+ /* RESERVE29 [15:1] RSVD */
+ /* DSKEWCALOUT [16:7] RO */
+ /* RESERVE30 [23:9] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_PLL_PHADJ)
+/*PLL phase registers */
+#define LIBERO_SETTING_SGMII_PLL_PHADJ 0x00007443UL
+ /* PLL_REG_SYNCREFDIV_EN [0:1] RW value= 0x1 */
+ /* PLL_REG_ENABLE_SYNCREFDIV [1:1] RW value= 0x1 */
+ /* REG_OUT0_PHSINIT [2:3] RW value= 0x0 */
+ /* REG_OUT1_PHSINIT [5:3] RW value= 0x2 */
+ /* REG_OUT2_PHSINIT [8:3] RW value= 0x4 */
+ /* REG_OUT3_PHSINIT [11:3] RW value= 0x6 */
+ /* REG_LOADPHS_B [14:1] RW value= 0x1 */
+ /* RESERVE31 [15:17] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_0)
+/*SSCG registers 0 */
+#define LIBERO_SETTING_SGMII_SSCG_REG_0 0x00000000UL
+ /* DIVVAL [0:6] RW value= 0x0 */
+ /* FRACIN [6:24] RW value= 0x0 */
+ /* RESERVE00 [30:2] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_1)
+/*SSCG registers 1 */
+#define LIBERO_SETTING_SGMII_SSCG_REG_1 0x00000000UL
+ /* DOWNSPREAD [0:1] RW value= 0x0 */
+ /* SSMD [1:5] RW value= 0x0 */
+ /* FRACMOD [6:24] RO */
+ /* RESERVE01 [30:2] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_2)
+/*SSCG registers 2 */
+#define LIBERO_SETTING_SGMII_SSCG_REG_2 0x00000014UL
+ /* INTIN [0:12] RW value= 0x14 */
+ /* INTMOD [12:12] RO */
+ /* RESERVE02 [24:8] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_3)
+/*SSCG registers 3 */
+#define LIBERO_SETTING_SGMII_SSCG_REG_3 0x00000001UL
+ /* SSE_B [0:1] RW value= 0x1 */
+ /* SEL_EXTWAVE [1:2] RW value= 0x0 */
+ /* EXT_MAXADDR [3:8] RW value= 0x0 */
+ /* TBLADDR [11:8] RO */
+ /* RANDOM_FILTER [19:1] RW value= 0x0 */
+ /* RANDOM_SEL [20:2] RW value= 0x0 */
+ /* RESERVE03 [22:1] RSVD */
+ /* RESERVE04 [23:9] RSVD */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_CLK_SGMII_PLL_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sysreg.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sysreg.h
new file mode 100644
index 00000000..7164d99b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_clk_sysreg.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_clk_sysreg.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_CLK_SYSREG_H_
+#define HW_CLK_SYSREG_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MSS_CLOCK_CONFIG_CR)
+/*Master clock config (00=/1 01=/2 10=/4 11=/8 ) */
+#define LIBERO_SETTING_MSS_CLOCK_CONFIG_CR 0x00000024UL
+ /* DIVIDER_CPU [0:2] RW value= 0x0 */
+ /* DIVIDER_AXI [2:2] RW value= 0x1 */
+ /* DIVIDER_APB_AHB [4:2] RW value= 0x2 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_RTC_CLOCK_CR)
+/*RTC clock divider */
+#define LIBERO_SETTING_MSS_RTC_CLOCK_CR 0x0000007DUL
+ /* PERIOD [0:12] RW value= 0x7D */
+#endif
+#if !defined (LIBERO_SETTING_MSS_ENVM_CR)
+/*ENVM AHB Controller setup - - Clock period = (Value+1) * (1000/AHBFREQMHZ)
+e.g. 7 will generate a 40ns period 25MHz clock if the AHB clock is 200MHz */
+#define LIBERO_SETTING_MSS_ENVM_CR 0x40050006UL
+ /* CLOCK_PERIOD [0:6] RW value= 0x6 */
+ /* CLOCK_CONTINUOUS [8:1] RW value= 0x0 */
+ /* CLOCK_SUPPRESS [9:1] RW value= 0x0 */
+ /* READAHEAD [16:1] RW value= 0x1 */
+ /* SLOWREAD [17:1] RW value= 0x0 */
+ /* INTERRUPT_ENABLE [18:1] RW value= 0x1 */
+ /* TIMER [24:8] RW value= 0x40 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_CLK_SYSREG_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_mss_clks.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_mss_clks.h
new file mode 100644
index 00000000..e6ff52ff
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/clocks/hw_mss_clks.h
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mss_clks.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MSS_CLKS_H_
+#define HW_MSS_CLKS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK)
+/*Ref Clock rate in MHz */
+#define LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK 125000000
+ /* MSS_EXT_SGMII_REF_CLK [0:32] RW value= 125000000 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_COREPLEX_CPU_CLK)
+/*CPU Clock rate in MHz */
+#define LIBERO_SETTING_MSS_COREPLEX_CPU_CLK 600000000
+ /* MSS_COREPLEX_CPU_CLK [0:32] RW value= 600000000 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_SYSTEM_CLK)
+/*System Clock rate in MHz static power. */
+#define LIBERO_SETTING_MSS_SYSTEM_CLK 600000000
+ /* MSS_SYSTEM_CLK [0:32] RW value= 600000000 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_RTC_TOGGLE_CLK)
+/*RTC toggle Clock rate in MHz static power. */
+#define LIBERO_SETTING_MSS_RTC_TOGGLE_CLK 1000000
+ /* MSS_RTC_TOGGLE_CLK [0:32] RW value= 1000000 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_AXI_CLK)
+/*AXI Clock rate in MHz static power. */
+#define LIBERO_SETTING_MSS_AXI_CLK 300000000
+ /* MSS_AXI_CLK [0:32] RW value= 300000000 */
+#endif
+#if !defined (LIBERO_SETTING_MSS_APB_AHB_CLK)
+/*AXI Clock rate in MHz static power. */
+#define LIBERO_SETTING_MSS_APB_AHB_CLK 150000000
+ /* MSS_APB_AHB_CLK [0:32] RW value= 150000000 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MSS_CLKS_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_io_bank.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_io_bank.h
new file mode 100644
index 00000000..ecbbe921
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_io_bank.h
@@ -0,0 +1,512 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_ddr_io_bank.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_DDR_IO_BANK_H_
+#define HW_DDR_IO_BANK_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_DPC_BITS)
+/*DPC Bits Register */
+#define LIBERO_SETTING_DPC_BITS 0x0004C422UL
+ /* DPC_VS [0:4] RW value= 0x2 */
+ /* DPC_VRGEN_H [4:6] RW value= 0x2 */
+ /* DPC_VRGEN_EN_H [10:1] RW value= 0x1 */
+ /* DPC_MOVE_EN_H [11:1] RW value= 0x0 */
+ /* DPC_VRGEN_V [12:6] RW value= 0xC */
+ /* DPC_VRGEN_EN_V [18:1] RW value= 0x1 */
+ /* DPC_MOVE_EN_V [19:1] RW value= 0x0 */
+ /* RESERVE01 [20:12] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_DQ)
+/*Need to be set by software in all modes but OFF mode. Decoding options should
+follow ODT_STR table, depends on drive STR setting */
+#define LIBERO_SETTING_RPC_ODT_DQ 0x00000006UL
+ /* RPC_ODT_DQ [0:32] RW value= 0x6 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_DQS)
+/*Need to be set by software in all modes but OFF mode. Decoding options should
+follow ODT_STR table, depends on drive STR setting */
+#define LIBERO_SETTING_RPC_ODT_DQS 0x00000006UL
+ /* RPC_ODT_DQS [0:32] RW value= 0x6 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_ADDCMD)
+/*Need to be set by software in all modes but OFF mode. Decoding options should
+follow ODT_STR table, depends on drive STR setting */
+#define LIBERO_SETTING_RPC_ODT_ADDCMD 0x00000002UL
+ /* RPC_ODT_ADDCMD [0:32] RW value= 0x2 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_CLK)
+/*Need to be set by software in all modes but OFF mode. Decoding options should
+follow ODT_STR table, depends on drive STR setting */
+#define LIBERO_SETTING_RPC_ODT_CLK 0x00000002UL
+ /* RPC_ODT_CLK [0:32] RW value= 0x2 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_DQ)
+/*0x2000 73A8 (rpc10_ODT) */
+#define LIBERO_SETTING_RPC_ODT_STATIC_DQ 0x00000005UL
+ /* RPC_ODT_STATIC_DQ [0:32] RW value= 0x5 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_DQS)
+/*0x2000 73AC (rpc11_ODT) */
+#define LIBERO_SETTING_RPC_ODT_STATIC_DQS 0x00000005UL
+ /* RPC_ODT_STATIC_DQS [0:32] RW value= 0x5 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_ADDCMD)
+/*0x2000 739C (rpc7_ODT) */
+#define LIBERO_SETTING_RPC_ODT_STATIC_ADDCMD 0x00000007UL
+ /* RPC_ODT_STATIC_ADDCMD [0:32] RW value= 0x7 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_CLKP)
+/*0x2000 73A4 (rpc9_ODT) */
+#define LIBERO_SETTING_RPC_ODT_STATIC_CLKP 0x00000007UL
+ /* RPC_ODT_STATIC_CLKP [0:32] RW value= 0x7 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_CLKN)
+/*0x2000 73A0 (rpc8_ODT) */
+#define LIBERO_SETTING_RPC_ODT_STATIC_CLKN 0x00000007UL
+ /* RPC_ODT_STATIC_CLKN [0:32] RW value= 0x7 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_IBUFMD_ADDCMD)
+/*0x2000 757C (rpc95) */
+#define LIBERO_SETTING_RPC_IBUFMD_ADDCMD 0x00000003UL
+ /* RPC_IBUFMD_ADDCMD [0:32] RW value= 0x3 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_IBUFMD_CLK)
+/*0x2000 7580 (rpc96) */
+#define LIBERO_SETTING_RPC_IBUFMD_CLK 0x00000004UL
+ /* RPC_IBUFMD_CLK [0:32] RW value= 0x4 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_IBUFMD_DQ)
+/*0x2000 7584 (rpc97) */
+#define LIBERO_SETTING_RPC_IBUFMD_DQ 0x00000003UL
+ /* RPC_IBUFMD_DQ [0:32] RW value= 0x3 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_IBUFMD_DQS)
+/*0x2000 7588 (rpc98) */
+#define LIBERO_SETTING_RPC_IBUFMD_DQS 0x00000004UL
+ /* RPC_IBUFMD_DQS [0:32] RW value= 0x4 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_SPARE0_DQ)
+/*bits 15:14 connect to pc_ibufmx DQ/DQS/DM bits 13:12 connect to pc_ibufmx
+CA/CK Check at ioa pc bit */
+#define LIBERO_SETTING_RPC_SPARE0_DQ 0x00008000UL
+ /* RPC_SPARE0_DQ [0:32] RW value= 0x8000 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9 0x00000F00UL
+ /* MSS_DDR_CK0 [0:1] RW value= 0x0 */
+ /* MSS_DDR_CK_N0 [1:1] RW value= 0x0 */
+ /* MSS_DDR_A0 [2:1] RW value= 0x0 */
+ /* MSS_DDR_A1 [3:1] RW value= 0x0 */
+ /* MSS_DDR_A2 [4:1] RW value= 0x0 */
+ /* MSS_DDR_A3 [5:1] RW value= 0x0 */
+ /* MSS_DDR_A4 [6:1] RW value= 0x0 */
+ /* MSS_DDR_A5 [7:1] RW value= 0x0 */
+ /* MSS_DDR_A6 [8:1] RW value= 0x1 */
+ /* MSS_DDR_A7 [9:1] RW value= 0x1 */
+ /* MSS_DDR_A8 [10:1] RW value= 0x1 */
+ /* MSS_DDR_A9 [11:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10 0x00000FFFUL
+ /* MSS_DDR_CK1 [0:1] RW value= 0x1 */
+ /* MSS_DDR_CK_N1 [1:1] RW value= 0x1 */
+ /* MSS_DDR_A10 [2:1] RW value= 0x1 */
+ /* MSS_DDR_A11 [3:1] RW value= 0x1 */
+ /* MSS_DDR_A12 [4:1] RW value= 0x1 */
+ /* MSS_DDR_A13 [5:1] RW value= 0x1 */
+ /* MSS_DDR_A14 [6:1] RW value= 0x1 */
+ /* MSS_DDR_A15 [7:1] RW value= 0x1 */
+ /* MSS_DDR_A16 [8:1] RW value= 0x1 */
+ /* MSS_DDR3_WE_N [9:1] RW value= 0x1 */
+ /* MSS_DDR_BA0 [10:1] RW value= 0x1 */
+ /* MSS_DDR_BA1 [11:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11 0x00000FE6UL
+ /* MSS_DDR_RAM_RST_N [0:1] RW value= 0x0 */
+ /* MSS_DDR_BG0 [1:1] RW value= 0x1 */
+ /* MSS_DDR_BG1 [2:1] RW value= 0x1 */
+ /* MSS_DDR_CS0 [3:1] RW value= 0x0 */
+ /* MSS_DDR_CKE0 [4:1] RW value= 0x0 */
+ /* MSS_DDR_ODT0 [5:1] RW value= 0x1 */
+ /* MSS_DDR_CS1 [6:1] RW value= 0x1 */
+ /* MSS_DDR_CKE1 [7:1] RW value= 0x1 */
+ /* MSS_DDR_ODT1 [8:1] RW value= 0x1 */
+ /* MSS_DDR_ACT_N [9:1] RW value= 0x1 */
+ /* MSS_DDR_PARITY [10:1] RW value= 0x1 */
+ /* MSS_DDR_ALERT_N [11:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_DATA0_OVRT12)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_DATA0_OVRT12 0x00000000UL
+ /* MSS_DDR_DQ0 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ1 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ2 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ3 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P0 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N0 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ4 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ5 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ6 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ7 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM0 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_DATA1_OVRT13)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_DATA1_OVRT13 0x00000000UL
+ /* MSS_DDR_DQ8 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ9 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ10 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ11 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P1 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N1 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ12 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ13 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ14 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ15 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM1 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_DATA2_OVRT14)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_DATA2_OVRT14 0x00000000UL
+ /* MSS_DDR_DQ16 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ17 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ18 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ19 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P2 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N2 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ20 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ21 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ22 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ23 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM2 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_DATA3_OVRT15)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_DATA3_OVRT15 0x00000000UL
+ /* MSS_DDR_DQ24 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ25 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ26 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ27 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P3 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N3 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ28 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ29 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ30 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ31 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM3 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC_EN_ECC_OVRT16)
+/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
+to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC_EN_ECC_OVRT16 0x0000007FUL
+ /* MSS_DDR_DQ32 [0:1] RW value= 0x1 */
+ /* MSS_DDR_DQ33 [1:1] RW value= 0x1 */
+ /* MSS_DDR_DQ34 [2:1] RW value= 0x1 */
+ /* MSS_DDR_DQ35 [3:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_P4 [4:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_N4 [5:1] RW value= 0x1 */
+ /* MSS_DDR_DM4 [6:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC235_WPD_ADD_CMD0)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC235_WPD_ADD_CMD0 0x00000000UL
+ /* MSS_DDR_CK0 [0:1] RW value= 0x0 */
+ /* MSS_DDR_CK_N0 [1:1] RW value= 0x0 */
+ /* MSS_DDR_A0 [2:1] RW value= 0x0 */
+ /* MSS_DDR_A1 [3:1] RW value= 0x0 */
+ /* MSS_DDR_A2 [4:1] RW value= 0x0 */
+ /* MSS_DDR_A3 [5:1] RW value= 0x0 */
+ /* MSS_DDR_A4 [6:1] RW value= 0x0 */
+ /* MSS_DDR_A5 [7:1] RW value= 0x0 */
+ /* MSS_DDR_A6 [8:1] RW value= 0x0 */
+ /* MSS_DDR_A7 [9:1] RW value= 0x0 */
+ /* MSS_DDR_A8 [10:1] RW value= 0x0 */
+ /* MSS_DDR_A9 [11:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC236_WPD_ADD_CMD1)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC236_WPD_ADD_CMD1 0x00000000UL
+ /* MSS_DDR_CK1 [0:1] RW value= 0x0 */
+ /* MSS_DDR_CK_N1 [1:1] RW value= 0x0 */
+ /* MSS_DDR_A10 [2:1] RW value= 0x0 */
+ /* MSS_DDR_A11 [3:1] RW value= 0x0 */
+ /* MSS_DDR_A12 [4:1] RW value= 0x0 */
+ /* MSS_DDR_A13 [5:1] RW value= 0x0 */
+ /* MSS_DDR_A14 [6:1] RW value= 0x0 */
+ /* MSS_DDR_A15 [7:1] RW value= 0x0 */
+ /* MSS_DDR_A16 [8:1] RW value= 0x0 */
+ /* MSS_DDR3_WE_N [9:1] RW value= 0x0 */
+ /* MSS_DDR_BA0 [10:1] RW value= 0x0 */
+ /* MSS_DDR_BA1 [11:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC237_WPD_ADD_CMD2)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. Note: For LPDDR4 need
+to over-ride MSS_DDR_ODT0 and MSS_DDR_ODT1 and eanble PU i.e. (set OVR_EN ==1 ,
+wpu == 0 , wpd == 1 ) */
+#define LIBERO_SETTING_RPC237_WPD_ADD_CMD2 0x00000120UL
+ /* MSS_DDR_RAM_RST_N [0:1] RW value= 0x0 */
+ /* MSS_DDR_BG0 [1:1] RW value= 0x0 */
+ /* MSS_DDR_BG1 [2:1] RW value= 0x0 */
+ /* MSS_DDR_CS0 [3:1] RW value= 0x0 */
+ /* MSS_DDR_CKE0 [4:1] RW value= 0x0 */
+ /* MSS_DDR_ODT0 [5:1] RW value= 0x1 */
+ /* MSS_DDR_CS1 [6:1] RW value= 0x0 */
+ /* MSS_DDR_CKE1 [7:1] RW value= 0x0 */
+ /* MSS_DDR_ODT1 [8:1] RW value= 0x1 */
+ /* MSS_DDR_ACT_N [9:1] RW value= 0x0 */
+ /* MSS_DDR_PARITY [10:1] RW value= 0x0 */
+ /* MSS_DDR_ALERT_N [11:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC238_WPD_DATA0)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC238_WPD_DATA0 0x00000000UL
+ /* MSS_DDR_DQ0 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ1 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ2 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ3 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P0 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N0 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ4 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ5 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ6 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ7 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM0 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC239_WPD_DATA1)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC239_WPD_DATA1 0x00000000UL
+ /* MSS_DDR_DQ8 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ9 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ10 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ11 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P1 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N1 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ12 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ13 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ14 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ15 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM1 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC240_WPD_DATA2)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC240_WPD_DATA2 0x00000000UL
+ /* MSS_DDR_DQ16 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ17 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ18 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ19 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P2 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N2 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ20 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ21 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ22 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ23 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM2 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC241_WPD_DATA3)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC241_WPD_DATA3 0x00000000UL
+ /* MSS_DDR_DQ24 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ25 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ26 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ27 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P3 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N3 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DQ28 [6:1] RW value= 0x0 */
+ /* MSS_DDR_DQ29 [7:1] RW value= 0x0 */
+ /* MSS_DDR_DQ30 [8:1] RW value= 0x0 */
+ /* MSS_DDR_DQ31 [9:1] RW value= 0x0 */
+ /* MSS_DDR_DM3 [10:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC242_WPD_ECC)
+/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC242_WPD_ECC 0x00000000UL
+ /* MSS_DDR_DQ32 [0:1] RW value= 0x0 */
+ /* MSS_DDR_DQ33 [1:1] RW value= 0x0 */
+ /* MSS_DDR_DQ34 [2:1] RW value= 0x0 */
+ /* MSS_DDR_DQ35 [3:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_P4 [4:1] RW value= 0x0 */
+ /* MSS_DDR_DQS_N4 [5:1] RW value= 0x0 */
+ /* MSS_DDR_DM4 [6:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RPC243_WPU_ADD_CMD0)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC243_WPU_ADD_CMD0 0x00000FFFUL
+ /* MSS_DDR_CK0 [0:1] RW value= 0x1 */
+ /* MSS_DDR_CK_N0 [1:1] RW value= 0x1 */
+ /* MSS_DDR_A0 [2:1] RW value= 0x1 */
+ /* MSS_DDR_A1 [3:1] RW value= 0x1 */
+ /* MSS_DDR_A2 [4:1] RW value= 0x1 */
+ /* MSS_DDR_A3 [5:1] RW value= 0x1 */
+ /* MSS_DDR_A4 [6:1] RW value= 0x1 */
+ /* MSS_DDR_A5 [7:1] RW value= 0x1 */
+ /* MSS_DDR_A6 [8:1] RW value= 0x1 */
+ /* MSS_DDR_A7 [9:1] RW value= 0x1 */
+ /* MSS_DDR_A8 [10:1] RW value= 0x1 */
+ /* MSS_DDR_A9 [11:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC244_WPU_ADD_CMD1)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC244_WPU_ADD_CMD1 0x00000FFFUL
+ /* MSS_DDR_CK1 [0:1] RW value= 0x1 */
+ /* MSS_DDR_CK_N1 [1:1] RW value= 0x1 */
+ /* MSS_DDR_A10 [2:1] RW value= 0x1 */
+ /* MSS_DDR_A11 [3:1] RW value= 0x1 */
+ /* MSS_DDR_A12 [4:1] RW value= 0x1 */
+ /* MSS_DDR_A13 [5:1] RW value= 0x1 */
+ /* MSS_DDR_A14 [6:1] RW value= 0x1 */
+ /* MSS_DDR_A15 [7:1] RW value= 0x1 */
+ /* MSS_DDR_A16 [8:1] RW value= 0x1 */
+ /* MSS_DDR3_WE_N [9:1] RW value= 0x1 */
+ /* MSS_DDR_BA0 [10:1] RW value= 0x1 */
+ /* MSS_DDR_BA1 [11:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC245_WPU_ADD_CMD2)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC245_WPU_ADD_CMD2 0x00000EDFUL
+ /* MSS_DDR_RAM_RST_N [0:1] RW value= 0x1 */
+ /* MSS_DDR_BG0 [1:1] RW value= 0x1 */
+ /* MSS_DDR_BG1 [2:1] RW value= 0x1 */
+ /* MSS_DDR_CS0 [3:1] RW value= 0x1 */
+ /* MSS_DDR_CKE0 [4:1] RW value= 0x1 */
+ /* MSS_DDR_ODT0 [5:1] RW value= 0x0 */
+ /* MSS_DDR_CS1 [6:1] RW value= 0x1 */
+ /* MSS_DDR_CKE1 [7:1] RW value= 0x1 */
+ /* MSS_DDR_ODT1 [8:1] RW value= 0x0 */
+ /* MSS_DDR_ACT_N [9:1] RW value= 0x1 */
+ /* MSS_DDR_PARITY [10:1] RW value= 0x1 */
+ /* MSS_DDR_ALERT_N [11:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC246_WPU_DATA0)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC246_WPU_DATA0 0x000007FFUL
+ /* MSS_DDR_DQ0 [0:1] RW value= 0x1 */
+ /* MSS_DDR_DQ1 [1:1] RW value= 0x1 */
+ /* MSS_DDR_DQ2 [2:1] RW value= 0x1 */
+ /* MSS_DDR_DQ3 [3:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_P0 [4:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_N0 [5:1] RW value= 0x1 */
+ /* MSS_DDR_DQ4 [6:1] RW value= 0x1 */
+ /* MSS_DDR_DQ5 [7:1] RW value= 0x1 */
+ /* MSS_DDR_DQ6 [8:1] RW value= 0x1 */
+ /* MSS_DDR_DQ7 [9:1] RW value= 0x1 */
+ /* MSS_DDR_DM0 [10:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC247_WPU_DATA1)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC247_WPU_DATA1 0x000007FFUL
+ /* MSS_DDR_DQ8 [0:1] RW value= 0x1 */
+ /* MSS_DDR_DQ9 [1:1] RW value= 0x1 */
+ /* MSS_DDR_DQ10 [2:1] RW value= 0x1 */
+ /* MSS_DDR_DQ11 [3:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_P1 [4:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_N1 [5:1] RW value= 0x1 */
+ /* MSS_DDR_DQ12 [6:1] RW value= 0x1 */
+ /* MSS_DDR_DQ13 [7:1] RW value= 0x1 */
+ /* MSS_DDR_DQ14 [8:1] RW value= 0x1 */
+ /* MSS_DDR_DQ15 [9:1] RW value= 0x1 */
+ /* MSS_DDR_DM1 [10:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC248_WPU_DATA2)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC248_WPU_DATA2 0x000007FFUL
+ /* MSS_DDR_DQ16 [0:1] RW value= 0x1 */
+ /* MSS_DDR_DQ17 [1:1] RW value= 0x1 */
+ /* MSS_DDR_DQ18 [2:1] RW value= 0x1 */
+ /* MSS_DDR_DQ19 [3:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_P2 [4:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_N2 [5:1] RW value= 0x1 */
+ /* MSS_DDR_DQ20 [6:1] RW value= 0x1 */
+ /* MSS_DDR_DQ21 [7:1] RW value= 0x1 */
+ /* MSS_DDR_DQ22 [8:1] RW value= 0x1 */
+ /* MSS_DDR_DQ23 [9:1] RW value= 0x1 */
+ /* MSS_DDR_DM2 [10:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC249_WPU_DATA3)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC249_WPU_DATA3 0x000007FFUL
+ /* MSS_DDR_DQ24 [0:1] RW value= 0x1 */
+ /* MSS_DDR_DQ25 [1:1] RW value= 0x1 */
+ /* MSS_DDR_DQ26 [2:1] RW value= 0x1 */
+ /* MSS_DDR_DQ27 [3:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_P3 [4:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_N3 [5:1] RW value= 0x1 */
+ /* MSS_DDR_DQ28 [6:1] RW value= 0x1 */
+ /* MSS_DDR_DQ29 [7:1] RW value= 0x1 */
+ /* MSS_DDR_DQ30 [8:1] RW value= 0x1 */
+ /* MSS_DDR_DQ31 [9:1] RW value= 0x1 */
+ /* MSS_DDR_DM3 [10:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_RPC250_WPU_ECC)
+/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
+corresponding IOG lane, starting from p_pair0 to n_pair5. */
+#define LIBERO_SETTING_RPC250_WPU_ECC 0x0000007FUL
+ /* MSS_DDR_DQ32 [0:1] RW value= 0x1 */
+ /* MSS_DDR_DQ33 [1:1] RW value= 0x1 */
+ /* MSS_DDR_DQ34 [2:1] RW value= 0x1 */
+ /* MSS_DDR_DQ35 [3:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_P4 [4:1] RW value= 0x1 */
+ /* MSS_DDR_DQS_N4 [5:1] RW value= 0x1 */
+ /* MSS_DDR_DM4 [6:1] RW value= 0x1 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_DDR_IO_BANK_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_mode.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_mode.h
new file mode 100644
index 00000000..5adc0522
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_mode.h
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_ddr_mode.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_DDR_MODE_H_
+#define HW_DDR_MODE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_DDRPHY_MODE)
+/*DDRPHY MODE (binary)- 000 ddr3, 001 ddr33L, 010 ddr4, 011 LPDDR3, 100 LPDDR4,
+111 OFF_MODE */
+#define LIBERO_SETTING_DDRPHY_MODE 0x00014B24UL
+ /* DDRMODE [0:3] RW value= 0x4 */
+ /* ECC [3:1] RW value= 0x0 */
+ /* CRC [4:1] RW value= 0x0 */
+ /* BUS_WIDTH [5:3] RW value= 0x1 */
+ /* DMI_DBI [8:1] RW value= 0x1 */
+ /* DQ_DRIVE [9:2] RW value= 0x1 */
+ /* DQS_DRIVE [11:2] RW value= 0x1 */
+ /* ADD_CMD_DRIVE [13:2] RW value= 0x2 */
+ /* CLOCK_OUT_DRIVE [15:2] RW value= 0x2 */
+ /* DQ_TERMINATION [17:2] RW value= 0x0 */
+ /* DQS_TERMINATION [19:2] RW value= 0x0 */
+ /* ADD_CMD_INPUT_PIN_TERMINATION [21:2] RW value= 0x0 */
+ /* PRESET_ODT_CLK [23:2] RW value= 0x0 */
+ /* POWER_DOWN [25:1] RW value= 0x0 */
+ /* RANK [26:1] RW value= 0x0 */
+ /* RESERVED [27:5] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DATA_LANES_USED)
+/*number of lanes used for data- does not include ECC, infer from mode register
+*/
+#define LIBERO_SETTING_DATA_LANES_USED 0x00000004UL
+ /* DATA_LANES [0:3] RW value= 0x4 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_DDR_MODE_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_off_mode.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_off_mode.h
new file mode 100644
index 00000000..a41f5025
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_off_mode.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_ddr_off_mode.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_DDR_OFF_MODE_H_
+#define HW_DDR_OFF_MODE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_DDRPHY_MODE_OFF)
+/*DDRPHY MODE Register, ddr off */
+#define LIBERO_SETTING_DDRPHY_MODE_OFF 0x00000000UL
+ /* DDRMODE [0:3] RW value= 0x0 */
+ /* ECC [3:1] RW value= 0x0 */
+ /* CRC [4:1] RW value= 0x0 */
+ /* BUS_WIDTH [5:3] RW value= 0x0 */
+ /* DMI_DBI [8:1] RW value= 0x0 */
+ /* DQ_DRIVE [9:2] RW value= 0x0 */
+ /* DQS_DRIVE [11:2] RW value= 0x0 */
+ /* ADD_CMD_DRIVE [13:2] RW value= 0x0 */
+ /* CLOCK_OUT_DRIVE [15:2] RW value= 0x0 */
+ /* DQ_TERMINATION [17:2] RW value= 0x0 */
+ /* DQS_TERMINATION [19:2] RW value= 0x0 */
+ /* ADD_CMD_INPUT_PIN_TERMINATION [21:2] RW value= 0x0 */
+ /* PRESET_ODT_CLK [23:2] RW value= 0x0 */
+ /* POWER_DOWN [25:1] RW value= 0x0 */
+ /* RANK [26:1] RW value= 0x0 */
+ /* RESERVED [27:5] RSVD */
+#endif
+#if !defined (LIBERO_SETTING_DPC_BITS_OFF_MODE)
+/*DPC Bits Register off mode */
+#define LIBERO_SETTING_DPC_BITS_OFF_MODE 0x00000000UL
+ /* DPC_VS [0:4] RW value= 0x0 */
+ /* DPC_VRGEN_H [4:6] RW value= 0x0 */
+ /* DPC_VRGEN_EN_H [10:1] RW value= 0x0 */
+ /* DPC_MOVE_EN_H [11:1] RW value= 0x0 */
+ /* DPC_VRGEN_V [12:6] RW value= 0x0 */
+ /* DPC_VRGEN_EN_V [18:1] RW value= 0x0 */
+ /* DPC_MOVE_EN_V [19:1] RW value= 0x0 */
+ /* RESERVE01 [20:12] RSVD */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_DDR_OFF_MODE_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_options.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_options.h
new file mode 100644
index 00000000..56c5ba90
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_options.h
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_ddr_options.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_DDR_OPTIONS_H_
+#define HW_DDR_OPTIONS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_CA_BUS_RX_OFF_POST_TRAINING)
+/*Tip config: Referenced receivers in the CA bus are turned on for CA training.
+These burn static power.(0x01 => turn off ; 0x00 => no action ) */
+#define LIBERO_SETTING_CA_BUS_RX_OFF_POST_TRAINING 0x00000001UL
+ /* CA_BUS_RX_OFF_POST_TRAINING [0:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_USER_INPUT_PHY_RANKS_TO_TRAIN)
+/*Tip config: 1 => 1 rank, 3 => 2 ranks */
+#define LIBERO_SETTING_USER_INPUT_PHY_RANKS_TO_TRAIN 0x00000001UL
+ /* USER_INPUT_PHY_RANKS_TO_TRAIN [0:2] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_TRAINING_SKIP_SETTING)
+/*Tip config: Pick what trainings we want performed by the TIP, default is 0x1F
+*/
+#define LIBERO_SETTING_TRAINING_SKIP_SETTING 0x00000002UL
+ /* SKIP_BCLKSCLK_TIP_TRAINING [0:1] RW value= 0x0 */
+ /* SKIP_ADDCMD_TIP_TRAINING [1:1] RW value= 0x1 */
+ /* SKIP_WRLVL_TIP_TRAINING [2:1] RW value= 0x0 */
+ /* SKIP_RDGATE_TIP_TRAINING [3:1] RW value= 0x0 */
+ /* SKIP_DQ_DQS_OPT_TIP_TRAINING [4:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_TIP_CFG_PARAMS)
+/*Tip config: default: 0x2,0x4,0x0,0x1F,0x1F */
+#define LIBERO_SETTING_TIP_CFG_PARAMS 0x07CFE02AUL
+ /* ADDCMD_OFFSET [0:3] RW value= 0x2 */
+ /* BCKLSCLK_OFFSET [3:3] RW value= 0x5 */
+ /* WRCALIB_WRITE_COUNT [6:7] RW value= 0x0 */
+ /* READ_GATE_MIN_READS [13:8] RW value= 0x7F */
+ /* ADDRCMD_WAIT_COUNT [22:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_TIP_CONFIG_PARAMS_BCLK_VCOPHS_OFFSET)
+/*in simulation we need to set this to 2, for hardware it will be dependent on
+the trace lengths */
+#define LIBERO_SETTING_TIP_CONFIG_PARAMS_BCLK_VCOPHS_OFFSET 0x00000002UL
+ /* TIP_CONFIG_PARAMS_BCLK_VCOPHS [0:32] RW value= 0x02 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_DDR_OPTIONS_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_segs.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_segs.h
new file mode 100644
index 00000000..8dadf698
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddr_segs.h
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_ddr_segs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_DDR_SEGS_H_
+#define HW_DDR_SEGS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_SEG0_0)
+/*Cached access at 0x00_8000_0000 (-0x80+0x00) */
+#define LIBERO_SETTING_SEG0_0 0x80007F80UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7F80 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_SEG0_1)
+/*Cached access at 0x10_0000_000 */
+#define LIBERO_SETTING_SEG0_1 0x80007030UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7030 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_SEG0_2)
+/*not used */
+#define LIBERO_SETTING_SEG0_2 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG0_3)
+/*not used */
+#define LIBERO_SETTING_SEG0_3 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG0_4)
+/*not used */
+#define LIBERO_SETTING_SEG0_4 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG0_5)
+/*not used */
+#define LIBERO_SETTING_SEG0_5 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:6] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG0_6)
+/*not used */
+#define LIBERO_SETTING_SEG0_6 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG0_7)
+/*not used */
+#define LIBERO_SETTING_SEG0_7 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_0)
+/*not used */
+#define LIBERO_SETTING_SEG1_0 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_1)
+/*not used */
+#define LIBERO_SETTING_SEG1_1 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_2)
+/*Non-Cached access at 0x00_c000_0000 */
+#define LIBERO_SETTING_SEG1_2 0x80007FB0UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7FB0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_3)
+/*Non-Cached access at 0x14_0000_0000 */
+#define LIBERO_SETTING_SEG1_3 0x80000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_4)
+/*Non-Cached WCB access at 0x00_d000_0000 */
+#define LIBERO_SETTING_SEG1_4 0x80007FA0UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7FA0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_5)
+/*Non-Cached WCB 0x18_0000_0000 */
+#define LIBERO_SETTING_SEG1_5 0x80000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:6] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_6)
+/*Trace - Trace not in use here so can be left as 0 */
+#define LIBERO_SETTING_SEG1_6 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SEG1_7)
+/*not used */
+#define LIBERO_SETTING_SEG1_7 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_DDR_SEGS_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddrc.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddrc.h
new file mode 100644
index 00000000..e7744420
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/ddr/hw_ddrc.h
@@ -0,0 +1,1887 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_ddrc.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_DDRC_H_
+#define HW_DDRC_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_CFG_MANUAL_ADDRESS_MAP)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_MANUAL_ADDRESS_MAP 0x00000000UL
+ /* CFG_MANUAL_ADDRESS_MAP [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CHIPADDR_MAP)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_CHIPADDR_MAP 0x0000001DUL
+ /* CFG_CHIPADDR_MAP [0:32] RW value= 0x00001D */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CIDADDR_MAP)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_CIDADDR_MAP 0x00000000UL
+ /* CFG_CIDADDR_MAP [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_LOW)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_LOW 0x00000004UL
+ /* CFG_MB_AUTOPCH_COL_BIT_POS_LOW [0:32] RW value= 0x00000004 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH 0x0000000AUL
+ /* CFG_MB_AUTOPCH_COL_BIT_POS_HIGH [0:32] RW value= 0x0000000A */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BANKADDR_MAP_0)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_BANKADDR_MAP_0 0x0000C2CAUL
+ /* CFG_BANKADDR_MAP_0 [0:32] RW value= 0x00C2CA */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BANKADDR_MAP_1)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_BANKADDR_MAP_1 0x00000000UL
+ /* CFG_BANKADDR_MAP_1 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ROWADDR_MAP_0)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_ROWADDR_MAP_0 0x9140F38DUL
+ /* CFG_ROWADDR_MAP_0 [0:32] RW value= 0x9140F38D */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ROWADDR_MAP_1)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_ROWADDR_MAP_1 0x75955134UL
+ /* CFG_ROWADDR_MAP_1 [0:32] RW value= 0x75955134 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ROWADDR_MAP_2)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_ROWADDR_MAP_2 0x71B69961UL
+ /* CFG_ROWADDR_MAP_2 [0:32] RW value= 0x71B69961 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ROWADDR_MAP_3)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_ROWADDR_MAP_3 0x00000000UL
+ /* CFG_ROWADDR_MAP_3 [0:32] RW value= 0x000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_COLADDR_MAP_0)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_COLADDR_MAP_0 0x440C2040UL
+ /* CFG_COLADDR_MAP_0 [0:32] RW value= 0x440C2040 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_COLADDR_MAP_1)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_COLADDR_MAP_1 0x02481C61UL
+ /* CFG_COLADDR_MAP_1 [0:32] RW value= 0x02481C61 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_COLADDR_MAP_2)
+/*IP Blk = ADDR_MAP Access=RW */
+#define LIBERO_SETTING_CFG_COLADDR_MAP_2 0x00000000UL
+ /* CFG_COLADDR_MAP_2 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_VRCG_ENABLE)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_VRCG_ENABLE 0x00000140UL
+ /* CFG_VRCG_ENABLE [0:32] RW value= 0x00000140 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_VRCG_DISABLE)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_VRCG_DISABLE 0x000000A0UL
+ /* CFG_VRCG_DISABLE [0:32] RW value= 0x000000A0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WRITE_LATENCY_SET)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_WRITE_LATENCY_SET 0x00000000UL
+ /* CFG_WRITE_LATENCY_SET [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_THERMAL_OFFSET)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_THERMAL_OFFSET 0x00000000UL
+ /* CFG_THERMAL_OFFSET [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_SOC_ODT)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_SOC_ODT 0x00000006UL
+ /* CFG_SOC_ODT [0:32] RW value= 0x6 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODTE_CK)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_ODTE_CK 0x00000000UL
+ /* CFG_ODTE_CK [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODTE_CS)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_ODTE_CS 0x00000000UL
+ /* CFG_ODTE_CS [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODTD_CA)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_ODTD_CA 0x00000000UL
+ /* CFG_ODTD_CA [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_LPDDR4_FSP_OP)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_LPDDR4_FSP_OP 0x00000001UL
+ /* CFG_LPDDR4_FSP_OP [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_GENERATE_REFRESH_ON_SRX)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_GENERATE_REFRESH_ON_SRX 0x00000001UL
+ /* CFG_GENERATE_REFRESH_ON_SRX [0:32] RW value= 0x00000001 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DBI_CL)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_DBI_CL 0x00000016UL
+ /* CFG_DBI_CL [0:32] RW value= 0x00000016 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_NON_DBI_CL)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_CFG_NON_DBI_CL 0x00000016UL
+ /* CFG_NON_DBI_CL [0:32] RW value= 0x00000016 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_FORCE_WRITE_DATA_0)
+/*IP Blk = MC_BASE3 Access=RW */
+#define LIBERO_SETTING_INIT_FORCE_WRITE_DATA_0 0x00000000UL
+ /* INIT_FORCE_WRITE_DATA_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WRITE_CRC)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WRITE_CRC 0x00000000UL
+ /* CFG_WRITE_CRC [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MPR_READ_FORMAT)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_MPR_READ_FORMAT 0x00000000UL
+ /* CFG_MPR_READ_FORMAT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WR_CMD_LAT_CRC_DM)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WR_CMD_LAT_CRC_DM 0x00000000UL
+ /* CFG_WR_CMD_LAT_CRC_DM [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_FINE_GRAN_REF_MODE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_FINE_GRAN_REF_MODE 0x00000000UL
+ /* CFG_FINE_GRAN_REF_MODE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TEMP_SENSOR_READOUT)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_TEMP_SENSOR_READOUT 0x00000000UL
+ /* CFG_TEMP_SENSOR_READOUT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PER_DRAM_ADDR_EN)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_PER_DRAM_ADDR_EN 0x00000000UL
+ /* CFG_PER_DRAM_ADDR_EN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_GEARDOWN_MODE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_GEARDOWN_MODE 0x00000000UL
+ /* CFG_GEARDOWN_MODE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WR_PREAMBLE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WR_PREAMBLE 0x00000001UL
+ /* CFG_WR_PREAMBLE [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RD_PREAMBLE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RD_PREAMBLE 0x00000000UL
+ /* CFG_RD_PREAMBLE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RD_PREAMB_TRN_MODE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RD_PREAMB_TRN_MODE 0x00000000UL
+ /* CFG_RD_PREAMB_TRN_MODE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_SR_ABORT)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_SR_ABORT 0x00000000UL
+ /* CFG_SR_ABORT [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CS_TO_CMDADDR_LATENCY)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_CS_TO_CMDADDR_LATENCY 0x00000000UL
+ /* CFG_CS_TO_CMDADDR_LATENCY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_INT_VREF_MON)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_INT_VREF_MON 0x00000000UL
+ /* CFG_INT_VREF_MON [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TEMP_CTRL_REF_MODE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_TEMP_CTRL_REF_MODE 0x00000000UL
+ /* CFG_TEMP_CTRL_REF_MODE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TEMP_CTRL_REF_RANGE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_TEMP_CTRL_REF_RANGE 0x00000000UL
+ /* CFG_TEMP_CTRL_REF_RANGE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MAX_PWR_DOWN_MODE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_MAX_PWR_DOWN_MODE 0x00000000UL
+ /* CFG_MAX_PWR_DOWN_MODE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_READ_DBI)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_READ_DBI 0x00000000UL
+ /* CFG_READ_DBI [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WRITE_DBI)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WRITE_DBI 0x00000000UL
+ /* CFG_WRITE_DBI [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DATA_MASK)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_DATA_MASK 0x00000001UL
+ /* CFG_DATA_MASK [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CA_PARITY_PERSIST_ERR)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_CA_PARITY_PERSIST_ERR 0x00000000UL
+ /* CFG_CA_PARITY_PERSIST_ERR [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RTT_PARK)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RTT_PARK 0x00000000UL
+ /* CFG_RTT_PARK [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_INBUF_4_PD)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_INBUF_4_PD 0x00000000UL
+ /* CFG_ODT_INBUF_4_PD [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CA_PARITY_ERR_STATUS)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_CA_PARITY_ERR_STATUS 0x00000000UL
+ /* CFG_CA_PARITY_ERR_STATUS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CRC_ERROR_CLEAR)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_CRC_ERROR_CLEAR 0x00000000UL
+ /* CFG_CRC_ERROR_CLEAR [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CA_PARITY_LATENCY)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_CA_PARITY_LATENCY 0x00000000UL
+ /* CFG_CA_PARITY_LATENCY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CCD_S)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_CCD_S 0x00000005UL
+ /* CFG_CCD_S [0:32] RW value= 0x00000005 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CCD_L)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_CCD_L 0x00000006UL
+ /* CFG_CCD_L [0:32] RW value= 0x00000006 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_VREFDQ_TRN_ENABLE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_VREFDQ_TRN_ENABLE 0x00000000UL
+ /* CFG_VREFDQ_TRN_ENABLE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_VREFDQ_TRN_RANGE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_VREFDQ_TRN_RANGE 0x00000000UL
+ /* CFG_VREFDQ_TRN_RANGE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_VREFDQ_TRN_VALUE)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_VREFDQ_TRN_VALUE 0x00000000UL
+ /* CFG_VREFDQ_TRN_VALUE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RRD_S)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RRD_S 0x00000004UL
+ /* CFG_RRD_S [0:32] RW value= 0x00000004 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RRD_L)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RRD_L 0x00000003UL
+ /* CFG_RRD_L [0:32] RW value= 0x00000003 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WTR_S)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WTR_S 0x00000003UL
+ /* CFG_WTR_S [0:32] RW value= 0x00000003 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WTR_L)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WTR_L 0x00000003UL
+ /* CFG_WTR_L [0:32] RW value= 0x00000003 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WTR_S_CRC_DM)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WTR_S_CRC_DM 0x00000003UL
+ /* CFG_WTR_S_CRC_DM [0:32] RW value= 0x00000003 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WTR_L_CRC_DM)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WTR_L_CRC_DM 0x00000003UL
+ /* CFG_WTR_L_CRC_DM [0:32] RW value= 0x00000003 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WR_CRC_DM)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_WR_CRC_DM 0x00000006UL
+ /* CFG_WR_CRC_DM [0:32] RW value= 0x00000006 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RFC1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RFC1 0x00000036UL
+ /* CFG_RFC1 [0:32] RW value= 0x00000036 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RFC2)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RFC2 0x00000036UL
+ /* CFG_RFC2 [0:32] RW value= 0x00000036 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RFC4)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RFC4 0x00000036UL
+ /* CFG_RFC4 [0:32] RW value= 0x00000036 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_NIBBLE_DEVICES)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_NIBBLE_DEVICES 0x00000000UL
+ /* CFG_NIBBLE_DEVICES [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_0 0x81881881UL
+ /* CFG_BIT_MAP_INDEX_CS0_0 [0:32] RW value= 0x81881881 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_1 0x00008818UL
+ /* CFG_BIT_MAP_INDEX_CS0_1 [0:32] RW value= 0x00008818 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_0 0xA92A92A9UL
+ /* CFG_BIT_MAP_INDEX_CS1_0 [0:32] RW value= 0xa92a92a9 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_1 0x00002A92UL
+ /* CFG_BIT_MAP_INDEX_CS1_1 [0:32] RW value= 0x00002a92 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_0 0xC28C28C2UL
+ /* CFG_BIT_MAP_INDEX_CS2_0 [0:32] RW value= 0xc28c28c2 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_1 0x00008C28UL
+ /* CFG_BIT_MAP_INDEX_CS2_1 [0:32] RW value= 0x00008c28 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_0 0xEA2EA2EAUL
+ /* CFG_BIT_MAP_INDEX_CS3_0 [0:32] RW value= 0xea2ea2ea */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_1 0x00002EA2UL
+ /* CFG_BIT_MAP_INDEX_CS3_1 [0:32] RW value= 0x00002ea2 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_0 0x03903903UL
+ /* CFG_BIT_MAP_INDEX_CS4_0 [0:32] RW value= 0x03903903 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_1 0x00009039UL
+ /* CFG_BIT_MAP_INDEX_CS4_1 [0:32] RW value= 0x00009039 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_0 0x2B32B32BUL
+ /* CFG_BIT_MAP_INDEX_CS5_0 [0:32] RW value= 0x2b32b32b */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_1 0x000032B3UL
+ /* CFG_BIT_MAP_INDEX_CS5_1 [0:32] RW value= 0x000032b3 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_0 0x44944944UL
+ /* CFG_BIT_MAP_INDEX_CS6_0 [0:32] RW value= 0x44944944 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_1 0x00009449UL
+ /* CFG_BIT_MAP_INDEX_CS6_1 [0:32] RW value= 0x00009449 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_0 0x6C36C36CUL
+ /* CFG_BIT_MAP_INDEX_CS7_0 [0:32] RW value= 0x6c36c36c */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_1 0x000036C3UL
+ /* CFG_BIT_MAP_INDEX_CS7_1 [0:32] RW value= 0x000036c3 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_0 0x85985985UL
+ /* CFG_BIT_MAP_INDEX_CS8_0 [0:32] RW value= 0x85985985 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_1 0x00009859UL
+ /* CFG_BIT_MAP_INDEX_CS8_1 [0:32] RW value= 0x00009859 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_0 0xAD3AD3ADUL
+ /* CFG_BIT_MAP_INDEX_CS9_0 [0:32] RW value= 0xad3ad3ad */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_1 0x00003AD3UL
+ /* CFG_BIT_MAP_INDEX_CS9_1 [0:32] RW value= 0x00003ad3 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_0 0xC69C69C6UL
+ /* CFG_BIT_MAP_INDEX_CS10_0 [0:32] RW value= 0xc69c69c6 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_1 0x00009C69UL
+ /* CFG_BIT_MAP_INDEX_CS10_1 [0:32] RW value= 0x00009c69 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_0 0xEE3EE3EEUL
+ /* CFG_BIT_MAP_INDEX_CS11_0 [0:32] RW value= 0xee3ee3ee */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_1 0x00003EE3UL
+ /* CFG_BIT_MAP_INDEX_CS11_1 [0:32] RW value= 0x00003ee3 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_0 0x07A07A07UL
+ /* CFG_BIT_MAP_INDEX_CS12_0 [0:32] RW value= 0x07a07a07 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_1 0x0000A07AUL
+ /* CFG_BIT_MAP_INDEX_CS12_1 [0:32] RW value= 0x0000a07a */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_0 0x2F42F42FUL
+ /* CFG_BIT_MAP_INDEX_CS13_0 [0:32] RW value= 0x2f42f42f */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_1 0x000042F4UL
+ /* CFG_BIT_MAP_INDEX_CS13_1 [0:32] RW value= 0x000042f4 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_0 0x48A48A48UL
+ /* CFG_BIT_MAP_INDEX_CS14_0 [0:32] RW value= 0x48a48a48 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_1 0x0000A48AUL
+ /* CFG_BIT_MAP_INDEX_CS14_1 [0:32] RW value= 0x0000a48a */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_0)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_0 0x70470470UL
+ /* CFG_BIT_MAP_INDEX_CS15_0 [0:32] RW value= 0x70470470 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_1 0x00004704UL
+ /* CFG_BIT_MAP_INDEX_CS15_1 [0:32] RW value= 0x00004704 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_NUM_LOGICAL_RANKS_PER_3DS)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_NUM_LOGICAL_RANKS_PER_3DS 0x00000000UL
+ /* CFG_NUM_LOGICAL_RANKS_PER_3DS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RFC_DLR1)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RFC_DLR1 0x00000048UL
+ /* CFG_RFC_DLR1 [0:32] RW value= 0x00000048 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RFC_DLR2)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RFC_DLR2 0x0000002CUL
+ /* CFG_RFC_DLR2 [0:32] RW value= 0x0000002C */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RFC_DLR4)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RFC_DLR4 0x00000020UL
+ /* CFG_RFC_DLR4 [0:32] RW value= 0x00000020 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RRD_DLR)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_RRD_DLR 0x00000004UL
+ /* CFG_RRD_DLR [0:32] RW value= 0x00000004 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_FAW_DLR)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_FAW_DLR 0x00000010UL
+ /* CFG_FAW_DLR [0:32] RW value= 0x00000010 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ADVANCE_ACTIVATE_READY)
+/*IP Blk = MC_BASE1 Access=RW */
+#define LIBERO_SETTING_CFG_ADVANCE_ACTIVATE_READY 0x00000000UL
+ /* CFG_ADVANCE_ACTIVATE_READY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CTRLR_SOFT_RESET_N)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CTRLR_SOFT_RESET_N 0x00000001UL
+ /* CTRLR_SOFT_RESET_N [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_LOOKAHEAD_PCH)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_LOOKAHEAD_PCH 0x00000000UL
+ /* CFG_LOOKAHEAD_PCH [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_LOOKAHEAD_ACT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_LOOKAHEAD_ACT 0x00000000UL
+ /* CFG_LOOKAHEAD_ACT [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_AUTOINIT_DISABLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_AUTOINIT_DISABLE 0x00000000UL
+ /* INIT_AUTOINIT_DISABLE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_FORCE_RESET)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_FORCE_RESET 0x00000000UL
+ /* INIT_FORCE_RESET [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_GEARDOWN_EN)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_GEARDOWN_EN 0x00000000UL
+ /* INIT_GEARDOWN_EN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_DISABLE_CKE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_DISABLE_CKE 0x00000000UL
+ /* INIT_DISABLE_CKE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_CS 0x00000000UL
+ /* INIT_CS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_PRECHARGE_ALL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_PRECHARGE_ALL 0x00000000UL
+ /* INIT_PRECHARGE_ALL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_REFRESH)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_REFRESH 0x00000000UL
+ /* INIT_REFRESH [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_ZQ_CAL_REQ)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_ZQ_CAL_REQ 0x00000000UL
+ /* INIT_ZQ_CAL_REQ [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_BL 0x00000000UL
+ /* CFG_BL [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CTRLR_INIT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CTRLR_INIT 0x00000000UL
+ /* CTRLR_INIT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AUTO_REF_EN)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_AUTO_REF_EN 0x00000001UL
+ /* CFG_AUTO_REF_EN [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RAS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RAS 0x00000022UL
+ /* CFG_RAS [0:32] RW value= 0x22 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RCD)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RCD 0x0000000FUL
+ /* CFG_RCD [0:32] RW value= 0xF */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RRD)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RRD 0x00000008UL
+ /* CFG_RRD [0:32] RW value= 0x8 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RP)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RP 0x00000011UL
+ /* CFG_RP [0:32] RW value= 0x11 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RC)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RC 0x00000033UL
+ /* CFG_RC [0:32] RW value= 0x33 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_FAW)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_FAW 0x00000020UL
+ /* CFG_FAW [0:32] RW value= 0x20 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RFC)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RFC 0x00000130UL
+ /* CFG_RFC [0:32] RW value= 0x130 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RTP)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RTP 0x00000008UL
+ /* CFG_RTP [0:32] RW value= 0x8 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WR 0x00000010UL
+ /* CFG_WR [0:32] RW value= 0x10 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WTR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WTR 0x00000008UL
+ /* CFG_WTR [0:32] RW value= 0x8 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PASR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_PASR 0x00000000UL
+ /* CFG_PASR [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_XP)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_XP 0x00000006UL
+ /* CFG_XP [0:32] RW value= 0x6 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_XSR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_XSR 0x0000001FUL
+ /* CFG_XSR [0:32] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CL 0x00000005UL
+ /* CFG_CL [0:32] RW value= 0x5 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_READ_TO_WRITE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_READ_TO_WRITE 0x0000000FUL
+ /* CFG_READ_TO_WRITE [0:32] RW value= 0xF */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WRITE_TO_WRITE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WRITE_TO_WRITE 0x0000000FUL
+ /* CFG_WRITE_TO_WRITE [0:32] RW value= 0xF */
+#endif
+#if !defined (LIBERO_SETTING_CFG_READ_TO_READ)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_READ_TO_READ 0x0000000FUL
+ /* CFG_READ_TO_READ [0:32] RW value= 0xF */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WRITE_TO_READ)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WRITE_TO_READ 0x0000001FUL
+ /* CFG_WRITE_TO_READ [0:32] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_CFG_READ_TO_WRITE_ODT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_READ_TO_WRITE_ODT 0x00000001UL
+ /* CFG_READ_TO_WRITE_ODT [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WRITE_TO_WRITE_ODT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WRITE_TO_WRITE_ODT 0x00000000UL
+ /* CFG_WRITE_TO_WRITE_ODT [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_READ_TO_READ_ODT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_READ_TO_READ_ODT 0x00000001UL
+ /* CFG_READ_TO_READ_ODT [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WRITE_TO_READ_ODT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WRITE_TO_READ_ODT 0x00000001UL
+ /* CFG_WRITE_TO_READ_ODT [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MIN_READ_IDLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MIN_READ_IDLE 0x00000007UL
+ /* CFG_MIN_READ_IDLE [0:32] RW value= 0x7 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MRD)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MRD 0x0000000CUL
+ /* CFG_MRD [0:32] RW value= 0xC */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_BT 0x00000000UL
+ /* CFG_BT [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_DS 0x00000006UL
+ /* CFG_DS [0:32] RW value= 0x6 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_QOFF)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_QOFF 0x00000000UL
+ /* CFG_QOFF [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RTT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RTT 0x00000002UL
+ /* CFG_RTT [0:32] RW value= 0x2 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DLL_DISABLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_DLL_DISABLE 0x00000000UL
+ /* CFG_DLL_DISABLE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_REF_PER)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_REF_PER 0x00000C34UL
+ /* CFG_REF_PER [0:32] RW value= 0xC34 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARTUP_DELAY)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_STARTUP_DELAY 0x00027100UL
+ /* CFG_STARTUP_DELAY [0:32] RW value= 0x27100 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEM_COLBITS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MEM_COLBITS 0x0000000AUL
+ /* CFG_MEM_COLBITS [0:32] RW value= 0xA */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEM_ROWBITS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MEM_ROWBITS 0x00000010UL
+ /* CFG_MEM_ROWBITS [0:32] RW value= 0x10 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEM_BANKBITS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MEM_BANKBITS 0x00000003UL
+ /* CFG_MEM_BANKBITS [0:32] RW value= 0x3 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS0)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS0 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS0 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS1)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS1 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS1 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS2)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS2 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS2 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS3)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS3 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS3 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS4)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS4 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS4 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS5)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS5 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS5 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS6)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS6 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS6 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_MAP_CS7)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_MAP_CS7 0x00000000UL
+ /* CFG_ODT_RD_MAP_CS7 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS0)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS0 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS0 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS1)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS1 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS1 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS2)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS2 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS2 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS3)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS3 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS3 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS4)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS4 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS4 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS5)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS5 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS5 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS6)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS6 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS6 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_MAP_CS7)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_MAP_CS7 0x00000000UL
+ /* CFG_ODT_WR_MAP_CS7 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_TURN_ON)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_TURN_ON 0x00000000UL
+ /* CFG_ODT_RD_TURN_ON [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_TURN_ON)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_TURN_ON 0x00000000UL
+ /* CFG_ODT_WR_TURN_ON [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_RD_TURN_OFF)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_RD_TURN_OFF 0x00000000UL
+ /* CFG_ODT_RD_TURN_OFF [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_WR_TURN_OFF)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_WR_TURN_OFF 0x00000000UL
+ /* CFG_ODT_WR_TURN_OFF [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_EMR3)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_EMR3 0x00000000UL
+ /* CFG_EMR3 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TWO_T)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_TWO_T 0x00000000UL
+ /* CFG_TWO_T [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TWO_T_SEL_CYCLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_TWO_T_SEL_CYCLE 0x00000001UL
+ /* CFG_TWO_T_SEL_CYCLE [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_REGDIMM)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_REGDIMM 0x00000000UL
+ /* CFG_REGDIMM [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MOD)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MOD 0x0000000CUL
+ /* CFG_MOD [0:32] RW value= 0xC */
+#endif
+#if !defined (LIBERO_SETTING_CFG_XS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_XS 0x00000005UL
+ /* CFG_XS [0:32] RW value= 0x5 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_XSDLL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_XSDLL 0x00000200UL
+ /* CFG_XSDLL [0:32] RW value= 0x00000200 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_XPR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_XPR 0x00000005UL
+ /* CFG_XPR [0:32] RW value= 0x5 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AL_MODE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_AL_MODE 0x00000000UL
+ /* CFG_AL_MODE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CWL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CWL 0x00000005UL
+ /* CFG_CWL [0:32] RW value= 0x5 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BL_MODE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_BL_MODE 0x00000000UL
+ /* CFG_BL_MODE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TDQS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_TDQS 0x00000000UL
+ /* CFG_TDQS [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RTT_WR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RTT_WR 0x00000000UL
+ /* CFG_RTT_WR [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_LP_ASR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_LP_ASR 0x00000000UL
+ /* CFG_LP_ASR [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AUTO_SR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_AUTO_SR 0x00000000UL
+ /* CFG_AUTO_SR [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_SRT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_SRT 0x00000000UL
+ /* CFG_SRT [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ADDR_MIRROR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ADDR_MIRROR 0x00000000UL
+ /* CFG_ADDR_MIRROR [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQ_CAL_TYPE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQ_CAL_TYPE 0x00000001UL
+ /* CFG_ZQ_CAL_TYPE [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQ_CAL_PER)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQ_CAL_PER 0x00027100UL
+ /* CFG_ZQ_CAL_PER [0:32] RW value= 0x27100 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AUTO_ZQ_CAL_EN)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_AUTO_ZQ_CAL_EN 0x00000000UL
+ /* CFG_AUTO_ZQ_CAL_EN [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEMORY_TYPE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MEMORY_TYPE 0x00000400UL
+ /* CFG_MEMORY_TYPE [0:32] RW value= 0x400 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ONLY_SRANK_CMDS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ONLY_SRANK_CMDS 0x00000000UL
+ /* CFG_ONLY_SRANK_CMDS [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_NUM_RANKS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_NUM_RANKS 0x00000001UL
+ /* CFG_NUM_RANKS [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_QUAD_RANK)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_QUAD_RANK 0x00000000UL
+ /* CFG_QUAD_RANK [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_EARLY_RANK_TO_WR_START)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_EARLY_RANK_TO_WR_START 0x00000000UL
+ /* CFG_EARLY_RANK_TO_WR_START [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_EARLY_RANK_TO_RD_START)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_EARLY_RANK_TO_RD_START 0x00000000UL
+ /* CFG_EARLY_RANK_TO_RD_START [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PASR_BANK)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_PASR_BANK 0x00000000UL
+ /* CFG_PASR_BANK [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PASR_SEG)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_PASR_SEG 0x00000000UL
+ /* CFG_PASR_SEG [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_MRR_MODE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_MRR_MODE 0x00000000UL
+ /* INIT_MRR_MODE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_MR_W_REQ)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_MR_W_REQ 0x00000000UL
+ /* INIT_MR_W_REQ [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_MR_ADDR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_MR_ADDR 0x00000000UL
+ /* INIT_MR_ADDR [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_MR_WR_DATA)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_MR_WR_DATA 0x00000000UL
+ /* INIT_MR_WR_DATA [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_MR_WR_MASK)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_MR_WR_MASK 0x00000000UL
+ /* INIT_MR_WR_MASK [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_NOP)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_NOP 0x00000000UL
+ /* INIT_NOP [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_INIT_DURATION)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_INIT_DURATION 0x00000640UL
+ /* CFG_INIT_DURATION [0:32] RW value= 0x640 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQINIT_CAL_DURATION)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQINIT_CAL_DURATION 0x00000000UL
+ /* CFG_ZQINIT_CAL_DURATION [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQ_CAL_L_DURATION)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQ_CAL_L_DURATION 0x00000000UL
+ /* CFG_ZQ_CAL_L_DURATION [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQ_CAL_S_DURATION)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQ_CAL_S_DURATION 0x00000000UL
+ /* CFG_ZQ_CAL_S_DURATION [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQ_CAL_R_DURATION)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQ_CAL_R_DURATION 0x00000028UL
+ /* CFG_ZQ_CAL_R_DURATION [0:32] RW value= 0x28 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MRR)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MRR 0x00000008UL
+ /* CFG_MRR [0:32] RW value= 0x8 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MRW)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MRW 0x0000000AUL
+ /* CFG_MRW [0:32] RW value= 0xA */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ODT_POWERDOWN)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ODT_POWERDOWN 0x00000000UL
+ /* CFG_ODT_POWERDOWN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WL 0x00000008UL
+ /* CFG_WL [0:32] RW value= 0x8 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RL 0x0000000EUL
+ /* CFG_RL [0:32] RW value= 0xE */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CAL_READ_PERIOD)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CAL_READ_PERIOD 0x00000000UL
+ /* CFG_CAL_READ_PERIOD [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_NUM_CAL_READS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_NUM_CAL_READS 0x00000001UL
+ /* CFG_NUM_CAL_READS [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_SELF_REFRESH)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_SELF_REFRESH 0x00000000UL
+ /* INIT_SELF_REFRESH [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_POWER_DOWN)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_POWER_DOWN 0x00000000UL
+ /* INIT_POWER_DOWN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_FORCE_WRITE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_FORCE_WRITE 0x00000000UL
+ /* INIT_FORCE_WRITE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_FORCE_WRITE_CS)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_FORCE_WRITE_CS 0x00000000UL
+ /* INIT_FORCE_WRITE_CS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLR_INIT_DISABLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLR_INIT_DISABLE 0x00000000UL
+ /* CFG_CTRLR_INIT_DISABLE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_RDIMM_COMPLETE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_RDIMM_COMPLETE 0x00000000UL
+ /* INIT_RDIMM_COMPLETE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RDIMM_LAT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RDIMM_LAT 0x00000000UL
+ /* CFG_RDIMM_LAT [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RDIMM_BSIDE_INVERT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RDIMM_BSIDE_INVERT 0x00000001UL
+ /* CFG_RDIMM_BSIDE_INVERT [0:32] RW value= 0x00000001 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_LRDIMM)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_LRDIMM 0x00000000UL
+ /* CFG_LRDIMM [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_MEMORY_RESET_MASK)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_MEMORY_RESET_MASK 0x00000000UL
+ /* INIT_MEMORY_RESET_MASK [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RD_PREAMB_TOGGLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RD_PREAMB_TOGGLE 0x00000000UL
+ /* CFG_RD_PREAMB_TOGGLE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RD_POSTAMBLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RD_POSTAMBLE 0x00000000UL
+ /* CFG_RD_POSTAMBLE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PU_CAL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_PU_CAL 0x00000001UL
+ /* CFG_PU_CAL [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DQ_ODT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_DQ_ODT 0x00000002UL
+ /* CFG_DQ_ODT [0:32] RW value= 0x2 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CA_ODT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CA_ODT 0x00000004UL
+ /* CFG_CA_ODT [0:32] RW value= 0x4 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQLATCH_DURATION)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQLATCH_DURATION 0x00000018UL
+ /* CFG_ZQLATCH_DURATION [0:32] RW value= 0x18 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CAL_SELECT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_CAL_SELECT 0x00000000UL
+ /* INIT_CAL_SELECT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CAL_L_R_REQ)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_CAL_L_R_REQ 0x00000000UL
+ /* INIT_CAL_L_R_REQ [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CAL_L_B_SIZE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_CAL_L_B_SIZE 0x00000000UL
+ /* INIT_CAL_L_B_SIZE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_RWFIFO)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_RWFIFO 0x00000000UL
+ /* INIT_RWFIFO [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_RD_DQCAL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_RD_DQCAL 0x00000000UL
+ /* INIT_RD_DQCAL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_START_DQSOSC)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_START_DQSOSC 0x00000000UL
+ /* INIT_START_DQSOSC [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_STOP_DQSOSC)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_STOP_DQSOSC 0x00000000UL
+ /* INIT_STOP_DQSOSC [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_ZQ_CAL_START)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_ZQ_CAL_START 0x00000000UL
+ /* INIT_ZQ_CAL_START [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_WR_POSTAMBLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_WR_POSTAMBLE 0x00000000UL
+ /* CFG_WR_POSTAMBLE [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CAL_L_ADDR_0)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_CAL_L_ADDR_0 0x00000000UL
+ /* INIT_CAL_L_ADDR_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CAL_L_ADDR_1)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_CAL_L_ADDR_1 0x00000000UL
+ /* INIT_CAL_L_ADDR_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLUPD_TRIG)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLUPD_TRIG 0x00000000UL
+ /* CFG_CTRLUPD_TRIG [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLUPD_START_DELAY)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLUPD_START_DELAY 0x00000000UL
+ /* CFG_CTRLUPD_START_DELAY [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_T_CTRLUPD_MAX)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_DFI_T_CTRLUPD_MAX 0x00000000UL
+ /* CFG_DFI_T_CTRLUPD_MAX [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLR_BUSY_SEL)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLR_BUSY_SEL 0x00000000UL
+ /* CFG_CTRLR_BUSY_SEL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLR_BUSY_VALUE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLR_BUSY_VALUE 0x00000000UL
+ /* CFG_CTRLR_BUSY_VALUE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLR_BUSY_TURN_OFF_DELAY)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLR_BUSY_TURN_OFF_DELAY 0x00000000UL
+ /* CFG_CTRLR_BUSY_TURN_OFF_DELAY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW 0x00000000UL
+ /* CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLR_BUSY_RESTART_HOLDOFF)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLR_BUSY_RESTART_HOLDOFF 0x00000000UL
+ /* CFG_CTRLR_BUSY_RESTART_HOLDOFF [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PARITY_RDIMM_DELAY)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_PARITY_RDIMM_DELAY 0x00000000UL
+ /* CFG_PARITY_RDIMM_DELAY [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CTRLR_BUSY_ENABLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CTRLR_BUSY_ENABLE 0x00000000UL
+ /* CFG_CTRLR_BUSY_ENABLE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ASYNC_ODT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ASYNC_ODT 0x00000000UL
+ /* CFG_ASYNC_ODT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ZQ_CAL_DURATION)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_ZQ_CAL_DURATION 0x00000320UL
+ /* CFG_ZQ_CAL_DURATION [0:32] RW value= 0x320 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MRRI)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MRRI 0x00000012UL
+ /* CFG_MRRI [0:32] RW value= 0x12 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_ODT_FORCE_EN)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_ODT_FORCE_EN 0x00000000UL
+ /* INIT_ODT_FORCE_EN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_ODT_FORCE_RANK)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_ODT_FORCE_RANK 0x00000000UL
+ /* INIT_ODT_FORCE_RANK [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PHYUPD_ACK_DELAY)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_PHYUPD_ACK_DELAY 0x00000000UL
+ /* CFG_PHYUPD_ACK_DELAY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MIRROR_X16_BG0_BG1)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_MIRROR_X16_BG0_BG1 0x00000000UL
+ /* CFG_MIRROR_X16_BG0_BG1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_PDA_MR_W_REQ)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_PDA_MR_W_REQ 0x00000000UL
+ /* INIT_PDA_MR_W_REQ [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_PDA_NIBBLE_SELECT)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_INIT_PDA_NIBBLE_SELECT 0x00000000UL
+ /* INIT_PDA_NIBBLE_SELECT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH 0x00000000UL
+ /* CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CKSRE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CKSRE 0x00000008UL
+ /* CFG_CKSRE [0:32] RW value= 0x00000008 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_CKSRX)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_CKSRX 0x0000000BUL
+ /* CFG_CKSRX [0:32] RW value= 0x0000000b */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RCD_STAB)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_RCD_STAB 0x00000000UL
+ /* CFG_RCD_STAB [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_T_CTRL_DELAY)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_DFI_T_CTRL_DELAY 0x00000000UL
+ /* CFG_DFI_T_CTRL_DELAY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_T_DRAM_CLK_ENABLE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_DFI_T_DRAM_CLK_ENABLE 0x00000000UL
+ /* CFG_DFI_T_DRAM_CLK_ENABLE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_IDLE_TIME_TO_SELF_REFRESH)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_IDLE_TIME_TO_SELF_REFRESH 0x00000000UL
+ /* CFG_IDLE_TIME_TO_SELF_REFRESH [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_IDLE_TIME_TO_POWER_DOWN)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_IDLE_TIME_TO_POWER_DOWN 0x00000000UL
+ /* CFG_IDLE_TIME_TO_POWER_DOWN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BURST_RW_REFRESH_HOLDOFF)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_BURST_RW_REFRESH_HOLDOFF 0x00000000UL
+ /* CFG_BURST_RW_REFRESH_HOLDOFF [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_BG_INTERLEAVE)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_BG_INTERLEAVE 0x00000001UL
+ /* CFG_BG_INTERLEAVE [0:32] RW value= 0x00000001 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_REFRESH_DURING_PHY_TRAINING)
+/*IP Blk = MC_BASE2 Access=RW */
+#define LIBERO_SETTING_CFG_REFRESH_DURING_PHY_TRAINING 0x00000000UL
+ /* CFG_REFRESH_DURING_PHY_TRAINING [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P0)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P0 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P1)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P1 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P2)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P2 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P2 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P3)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P3 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P3 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P4)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P4 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P4 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P5)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P5 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P5 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P6)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P6 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P6 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_STARVE_TIMEOUT_P7)
+/*IP Blk = MPFE Access=RW */
+#define LIBERO_SETTING_CFG_STARVE_TIMEOUT_P7 0x00000000UL
+ /* CFG_STARVE_TIMEOUT_P7 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_REORDER_EN)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_REORDER_EN 0x00000001UL
+ /* CFG_REORDER_EN [0:32] RW value= 0x00000001 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_REORDER_QUEUE_EN)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_REORDER_QUEUE_EN 0x00000001UL
+ /* CFG_REORDER_QUEUE_EN [0:32] RW value= 0x00000001 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_INTRAPORT_REORDER_EN)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_INTRAPORT_REORDER_EN 0x00000000UL
+ /* CFG_INTRAPORT_REORDER_EN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MAINTAIN_COHERENCY)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_MAINTAIN_COHERENCY 0x00000001UL
+ /* CFG_MAINTAIN_COHERENCY [0:32] RW value= 0x00000001 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_Q_AGE_LIMIT)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_Q_AGE_LIMIT 0x000000FFUL
+ /* CFG_Q_AGE_LIMIT [0:32] RW value= 0x000000FF */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RO_CLOSED_PAGE_POLICY)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_RO_CLOSED_PAGE_POLICY 0x00000000UL
+ /* CFG_RO_CLOSED_PAGE_POLICY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_REORDER_RW_ONLY)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_REORDER_RW_ONLY 0x00000000UL
+ /* CFG_REORDER_RW_ONLY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RO_PRIORITY_EN)
+/*IP Blk = REORDER Access=RW */
+#define LIBERO_SETTING_CFG_RO_PRIORITY_EN 0x00000000UL
+ /* CFG_RO_PRIORITY_EN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DM_EN)
+/*IP Blk = RMW Access=RW */
+#define LIBERO_SETTING_CFG_DM_EN 0x00000001UL
+ /* CFG_DM_EN [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_RMW_EN)
+/*IP Blk = RMW Access=RW */
+#define LIBERO_SETTING_CFG_RMW_EN 0x00000000UL
+ /* CFG_RMW_EN [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ECC_CORRECTION_EN)
+/*IP Blk = ECC Access=RW */
+#define LIBERO_SETTING_CFG_ECC_CORRECTION_EN 0x00000000UL
+ /* CFG_ECC_CORRECTION_EN [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ECC_BYPASS)
+/*IP Blk = ECC Access=RW */
+#define LIBERO_SETTING_CFG_ECC_BYPASS 0x00000000UL
+ /* CFG_ECC_BYPASS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_WRITE_DATA_1B_ECC_ERROR_GEN)
+/*IP Blk = ECC Access=RW */
+#define LIBERO_SETTING_INIT_WRITE_DATA_1B_ECC_ERROR_GEN 0x00000000UL
+ /* INIT_WRITE_DATA_1B_ECC_ERROR_GEN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_WRITE_DATA_2B_ECC_ERROR_GEN)
+/*IP Blk = ECC Access=RW */
+#define LIBERO_SETTING_INIT_WRITE_DATA_2B_ECC_ERROR_GEN 0x00000000UL
+ /* INIT_WRITE_DATA_2B_ECC_ERROR_GEN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ECC_1BIT_INT_THRESH)
+/*IP Blk = ECC Access=RW */
+#define LIBERO_SETTING_CFG_ECC_1BIT_INT_THRESH 0x00000000UL
+ /* CFG_ECC_1BIT_INT_THRESH [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_READ_CAPTURE_ADDR)
+/*IP Blk = READ_CAPT Access=RW */
+#define LIBERO_SETTING_INIT_READ_CAPTURE_ADDR 0x00000000UL
+ /* INIT_READ_CAPTURE_ADDR [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ERROR_GROUP_SEL)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_ERROR_GROUP_SEL 0x00000000UL
+ /* CFG_ERROR_GROUP_SEL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DATA_SEL)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_DATA_SEL 0x00000000UL
+ /* CFG_DATA_SEL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_MODE)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_MODE 0x00000000UL
+ /* CFG_TRIG_MODE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_POST_TRIG_CYCS)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_POST_TRIG_CYCS 0x00000000UL
+ /* CFG_POST_TRIG_CYCS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_MASK)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_MASK 0x00000000UL
+ /* CFG_TRIG_MASK [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_EN_MASK)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_EN_MASK 0x00000000UL
+ /* CFG_EN_MASK [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_MTC_ACQ_ADDR)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_MTC_ACQ_ADDR 0x00000000UL
+ /* MTC_ACQ_ADDR [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_MT_ADDR_0)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_MT_ADDR_0 0x00000000UL
+ /* CFG_TRIG_MT_ADDR_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_MT_ADDR_1)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_MT_ADDR_1 0x00000000UL
+ /* CFG_TRIG_MT_ADDR_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_ERR_MASK_0)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_ERR_MASK_0 0x00000000UL
+ /* CFG_TRIG_ERR_MASK_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_ERR_MASK_1)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_ERR_MASK_1 0x00000000UL
+ /* CFG_TRIG_ERR_MASK_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_ERR_MASK_2)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_ERR_MASK_2 0x00000000UL
+ /* CFG_TRIG_ERR_MASK_2 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_ERR_MASK_3)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_ERR_MASK_3 0x00000000UL
+ /* CFG_TRIG_ERR_MASK_3 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_TRIG_ERR_MASK_4)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_TRIG_ERR_MASK_4 0x00000000UL
+ /* CFG_TRIG_ERR_MASK_4 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_MTC_ACQ_WR_DATA_0)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_MTC_ACQ_WR_DATA_0 0x00000000UL
+ /* MTC_ACQ_WR_DATA_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_MTC_ACQ_WR_DATA_1)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_MTC_ACQ_WR_DATA_1 0x00000000UL
+ /* MTC_ACQ_WR_DATA_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_MTC_ACQ_WR_DATA_2)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_MTC_ACQ_WR_DATA_2 0x00000000UL
+ /* MTC_ACQ_WR_DATA_2 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_PRE_TRIG_CYCS)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_PRE_TRIG_CYCS 0x00000000UL
+ /* CFG_PRE_TRIG_CYCS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DATA_SEL_FIRST_ERROR)
+/*IP Blk = MTA Access=RW */
+#define LIBERO_SETTING_CFG_DATA_SEL_FIRST_ERROR 0x00000000UL
+ /* CFG_DATA_SEL_FIRST_ERROR [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DQ_WIDTH)
+/*IP Blk = DYN_WIDTH_ADJ Access=RW */
+#define LIBERO_SETTING_CFG_DQ_WIDTH 0x00000000UL
+ /* CFG_DQ_WIDTH [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ACTIVE_DQ_SEL)
+/*IP Blk = DYN_WIDTH_ADJ Access=RW */
+#define LIBERO_SETTING_CFG_ACTIVE_DQ_SEL 0x00000000UL
+ /* CFG_ACTIVE_DQ_SEL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_REQ)
+/*IP Blk = CA_PAR_ERR Access=RW */
+#define LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_REQ 0x00000000UL
+ /* INIT_CA_PARITY_ERROR_GEN_REQ [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_CMD)
+/*IP Blk = CA_PAR_ERR Access=RW */
+#define LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_CMD 0x00000000UL
+ /* INIT_CA_PARITY_ERROR_GEN_CMD [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_T_RDDATA_EN)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_T_RDDATA_EN 0x00000015UL
+ /* CFG_DFI_T_RDDATA_EN [0:32] RW value= 0x15 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_T_PHY_RDLAT)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_T_PHY_RDLAT 0x00000006UL
+ /* CFG_DFI_T_PHY_RDLAT [0:32] RW value= 0x6 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_T_PHY_WRLAT)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_T_PHY_WRLAT 0x00000003UL
+ /* CFG_DFI_T_PHY_WRLAT [0:32] RW value= 0x3 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_PHYUPD_EN)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_PHYUPD_EN 0x00000001UL
+ /* CFG_DFI_PHYUPD_EN [0:32] RW value= 0x00000001 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_DFI_LP_DATA_REQ)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_INIT_DFI_LP_DATA_REQ 0x00000000UL
+ /* INIT_DFI_LP_DATA_REQ [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_DFI_LP_CTRL_REQ)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_INIT_DFI_LP_CTRL_REQ 0x00000000UL
+ /* INIT_DFI_LP_CTRL_REQ [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_DFI_LP_WAKEUP)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_INIT_DFI_LP_WAKEUP 0x00000000UL
+ /* INIT_DFI_LP_WAKEUP [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_INIT_DFI_DRAM_CLK_DISABLE)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_INIT_DFI_DRAM_CLK_DISABLE 0x00000000UL
+ /* INIT_DFI_DRAM_CLK_DISABLE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_DATA_BYTE_DISABLE)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_DATA_BYTE_DISABLE 0x00000000UL
+ /* CFG_DFI_DATA_BYTE_DISABLE [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_LVL_SEL)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_LVL_SEL 0x00000000UL
+ /* CFG_DFI_LVL_SEL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_LVL_PERIODIC)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_LVL_PERIODIC 0x00000000UL
+ /* CFG_DFI_LVL_PERIODIC [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_DFI_LVL_PATTERN)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_CFG_DFI_LVL_PATTERN 0x00000000UL
+ /* CFG_DFI_LVL_PATTERN [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_DFI_INIT_START)
+/*IP Blk = DFI Access=RW */
+#define LIBERO_SETTING_PHY_DFI_INIT_START 0x00000001UL
+ /* PHY_DFI_INIT_START [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_0)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_0 0x00000000UL
+ /* CFG_AXI_START_ADDRESS_AXI1_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_1)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_1 0x00000000UL
+ /* CFG_AXI_START_ADDRESS_AXI1_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_0)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_0 0x00000000UL
+ /* CFG_AXI_START_ADDRESS_AXI2_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_1)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_1 0x00000000UL
+ /* CFG_AXI_START_ADDRESS_AXI2_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_0)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_0 0x7FFFFFFFUL
+ /* CFG_AXI_END_ADDRESS_AXI1_0 [0:32] RW value= 0x7FFFFFFF */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_1)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_1 0x00000000UL
+ /* CFG_AXI_END_ADDRESS_AXI1_1 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0 0x7FFFFFFFUL
+ /* CFG_AXI_END_ADDRESS_AXI2_0 [0:32] RW value= 0x7FFFFFFF */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1 0x00000000UL
+ /* CFG_AXI_END_ADDRESS_AXI2_1 [0:32] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_0)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_0 0x00000000UL
+ /* CFG_MEM_START_ADDRESS_AXI1_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_1)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_1 0x00000000UL
+ /* CFG_MEM_START_ADDRESS_AXI1_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_0)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_0 0x00000000UL
+ /* CFG_MEM_START_ADDRESS_AXI2_0 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_1)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_1 0x00000000UL
+ /* CFG_MEM_START_ADDRESS_AXI2_1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI1)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI1 0x00000000UL
+ /* CFG_ENABLE_BUS_HOLD_AXI1 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI2)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI2 0x00000000UL
+ /* CFG_ENABLE_BUS_HOLD_AXI2 [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_CFG_AXI_AUTO_PCH)
+/*IP Blk = AXI_IF Access=RW */
+#define LIBERO_SETTING_CFG_AXI_AUTO_PCH 0x00000000UL
+ /* CFG_AXI_AUTO_PCH [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_RESET_CONTROL)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_RESET_CONTROL 0x00008001UL
+ /* PHY_RESET_CONTROL [0:32] RW value= 0x8001 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_PC_RANK)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_PC_RANK 0x00000001UL
+ /* PHY_PC_RANK [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_RANKS_TO_TRAIN)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_RANKS_TO_TRAIN 0x00000001UL
+ /* PHY_RANKS_TO_TRAIN [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_WRITE_REQUEST)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_WRITE_REQUEST 0x00000000UL
+ /* PHY_WRITE_REQUEST [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_READ_REQUEST)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_READ_REQUEST 0x00000000UL
+ /* PHY_READ_REQUEST [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_WRITE_LEVEL_DELAY)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_WRITE_LEVEL_DELAY 0x00000000UL
+ /* PHY_WRITE_LEVEL_DELAY [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_GATE_TRAIN_DELAY)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_GATE_TRAIN_DELAY 0x0000003FUL
+ /* PHY_GATE_TRAIN_DELAY [0:32] RW value= 0x3F */
+#endif
+#if !defined (LIBERO_SETTING_PHY_EYE_TRAIN_DELAY)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_EYE_TRAIN_DELAY 0x0000003FUL
+ /* PHY_EYE_TRAIN_DELAY [0:32] RW value= 0x3F */
+#endif
+#if !defined (LIBERO_SETTING_PHY_EYE_PAT)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_EYE_PAT 0x00000000UL
+ /* PHY_EYE_PAT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_START_RECAL)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_START_RECAL 0x00000000UL
+ /* PHY_START_RECAL [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_CLR_DFI_LVL_PERIODIC)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_CLR_DFI_LVL_PERIODIC 0x00000000UL
+ /* PHY_CLR_DFI_LVL_PERIODIC [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_TRAIN_STEP_ENABLE)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_TRAIN_STEP_ENABLE 0x00000018UL
+ /* PHY_TRAIN_STEP_ENABLE [0:32] RW value= 0x18 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_LPDDR_DQ_CAL_PAT)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_LPDDR_DQ_CAL_PAT 0x00000000UL
+ /* PHY_LPDDR_DQ_CAL_PAT [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_INDPNDT_TRAINING)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_INDPNDT_TRAINING 0x00000001UL
+ /* PHY_INDPNDT_TRAINING [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_ENCODED_QUAD_CS)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_ENCODED_QUAD_CS 0x00000000UL
+ /* PHY_ENCODED_QUAD_CS [0:32] RW value= 0x00000000 */
+#endif
+#if !defined (LIBERO_SETTING_PHY_HALF_CLK_DLY_ENABLE)
+/*IP Blk = csr_custom Access=RW */
+#define LIBERO_SETTING_PHY_HALF_CLK_DLY_ENABLE 0x00000000UL
+ /* PHY_HALF_CLK_DLY_ENABLE [0:32] RW value= 0x00000000 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_DDRC_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/fpga_design_config.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/fpga_design_config.h
new file mode 100644
index 00000000..b294d61b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/fpga_design_config.h
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file fpga_design_config.h
+ * @author Embedded Software
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef FPGA_DESIGN_CONFIG_H_
+#define FPGA_DESIGN_CONFIG_H_
+
+#define LIBERO_SETTING_MSS_CONFIGURATOR_VERSION "2021.1"
+#define LIBERO_SETTING_DESIGN_NAME "ICICLE_MSS"
+#define LIBERO_SETTING_MPFS_PART "MPFS250T_ES"
+#define LIBERO_SETTING_GENERATION_DATE "06-22-2021_18:26:34"
+#define LIBERO_SETTING_XML_VERSION "0.5.3"
+#define LIBERO_SETTING_XML_VERSION_MAJOR 0
+#define LIBERO_SETTING_XML_VERSION_MINOR 5
+#define LIBERO_SETTING_XML_VERSION_PATCH 3
+#define LIBERO_SETTING_HEADER_GENERATOR_VERSION "0.6.3"
+#define LIBERO_SETTING_HEADER_GENERATOR_VERSION_MAJOR 0
+#define LIBERO_SETTING_HEADER_GENERATOR_VERSION_MINOR 6
+#define LIBERO_SETTING_HEADER_GENERATOR_VERSION_PATCH 3
+
+#include "memory_map/hw_memory.h"
+#include "memory_map/hw_apb_split.h"
+#include "memory_map/hw_cache.h"
+#include "memory_map/hw_pmp_hart0.h"
+#include "memory_map/hw_pmp_hart1.h"
+#include "memory_map/hw_pmp_hart2.h"
+#include "memory_map/hw_pmp_hart3.h"
+#include "memory_map/hw_pmp_hart4.h"
+#include "memory_map/hw_mpu_fic0.h"
+#include "memory_map/hw_mpu_fic1.h"
+#include "memory_map/hw_mpu_fic2.h"
+#include "memory_map/hw_mpu_crypto.h"
+#include "memory_map/hw_mpu_gem0.h"
+#include "memory_map/hw_mpu_gem1.h"
+#include "memory_map/hw_mpu_usb.h"
+#include "memory_map/hw_mpu_mmc.h"
+#include "memory_map/hw_mpu_scb.h"
+#include "memory_map/hw_mpu_trace.h"
+#include "io/hw_mssio_mux.h"
+#include "io/hw_hsio_mux.h"
+#include "sgmii/hw_sgmii_tip.h"
+#include "ddr/hw_ddr_options.h"
+#include "ddr/hw_ddr_io_bank.h"
+#include "ddr/hw_ddr_mode.h"
+#include "ddr/hw_ddr_off_mode.h"
+#include "ddr/hw_ddr_segs.h"
+#include "ddr/hw_ddrc.h"
+#include "clocks/hw_mss_clks.h"
+#include "clocks/hw_clk_sysreg.h"
+#include "clocks/hw_clk_mss_pll.h"
+#include "clocks/hw_clk_sgmii_pll.h"
+#include "clocks/hw_clk_ddr_pll.h"
+#include "clocks/hw_clk_mss_cfm.h"
+#include "clocks/hw_clk_sgmii_cfm.h"
+#include "general/hw_gen_peripherals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* No content in this file, used for referencing header */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef FPGA_DESIGN_CONFIG_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/general/hw_gen_peripherals.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/general/hw_gen_peripherals.h
new file mode 100644
index 00000000..b099d750
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/general/hw_gen_peripherals.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_gen_peripherals.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_GEN_PERIPHERALS_H_
+#define HW_GEN_PERIPHERALS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_GPIO_CR)
+/*GPIO Blocks reset control- (soft_reset options chossen in Libero confgurator)
+*/
+#define LIBERO_SETTING_GPIO_CR 0x000F0703UL
+ /* GPIO0_SOFT_RESET_SELECT [0:2] RW value= 0x3 */
+ /* GPIO0_DEFAULT [4:2] RW value= 0x0 */
+ /* GPIO1_SOFT_RESET_SELECT [8:3] RW value= 0x7 */
+ /* GPIO1_DEFAULT [12:3] RW value= 0x0 */
+ /* GPIO2_SOFT_RESET_SELECT [16:4] RW value= 0xF */
+ /* GPIO2_DEFAULT [20:4] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CRYPTO_CR_INFO)
+/*Information on how Crypto setup on this MPFS */
+#define LIBERO_SETTING_CRYPTO_CR_INFO 0x00000000UL
+ /* MSS_MODE [0:2] RO */
+ /* RESERVED [2:1] RO */
+ /* STREAM_ENABLE [3:1] RO */
+ /* RESERVED1 [4:28] RO */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_GEN_PERIPHERALS_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/io/hw_hsio_mux.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/io/hw_hsio_mux.h
new file mode 100644
index 00000000..9327dcf7
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/io/hw_hsio_mux.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_hsio_mux.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_HSIO_MUX_H_
+#define HW_HSIO_MUX_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_TRIM_OPTIONS)
+/*User trim options- set option to 1 to use */
+#define LIBERO_SETTING_TRIM_OPTIONS 0x00000000UL
+ /* TRIM_DDR_OPTION [0:1] */
+ /* TRIM_SGMII_OPTION [1:1] */
+#endif
+#if !defined (LIBERO_SETTING_DDR_IOC_REG0)
+/*Manual trim values */
+#define LIBERO_SETTING_DDR_IOC_REG0 0x00000000UL
+ /* BANK_PCODE [0:6] RW value= 0x0 */
+ /* BANK_NCODE [6:6] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SGMII_IOC_REG0)
+/*Manual trim values */
+#define LIBERO_SETTING_SGMII_IOC_REG0 0x00000000UL
+ /* BANK_PCODE [0:6] RW value= 0x0 */
+ /* BANK_NCODE [6:6] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_HSIO_MUX_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/io/hw_mssio_mux.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/io/hw_mssio_mux.h
new file mode 100644
index 00000000..23e15fae
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/io/hw_mssio_mux.h
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mssio_mux.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MSSIO_MUX_H_
+#define HW_MSSIO_MUX_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_IOMUX0_CR)
+/*Selects whether the peripheral is connected to the Fabric or IOMUX structure.
+*/
+#define LIBERO_SETTING_IOMUX0_CR 0x00000F9DUL
+ /* SPI0_FABRIC [0:1] RW value= 0x1 */
+ /* SPI1_FABRIC [1:1] RW value= 0x0 */
+ /* I2C0_FABRIC [2:1] RW value= 0x1 */
+ /* I2C1_FABRIC [3:1] RW value= 0x1 */
+ /* CAN0_FABRIC [4:1] RW value= 0x1 */
+ /* CAN1_FABRIC [5:1] RW value= 0x0 */
+ /* QSPI_FABRIC [6:1] RW value= 0x0 */
+ /* MMUART0_FABRIC [7:1] RW value= 0x1 */
+ /* MMUART1_FABRIC [8:1] RW value= 0x1 */
+ /* MMUART2_FABRIC [9:1] RW value= 0x1 */
+ /* MMUART3_FABRIC [10:1] RW value= 0x1 */
+ /* MMUART4_FABRIC [11:1] RW value= 0x1 */
+ /* MDIO0_FABRIC [12:1] RW value= 0x0 */
+ /* MDIO1_FABRIC [13:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_IOMUX1_CR)
+/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
+EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
+I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
+(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
+Logic 0,0xE implies Logic 1, 0xF implies Tristate */
+#define LIBERO_SETTING_IOMUX1_CR 0x11111111UL
+ /* PAD0 [0:4] RW value= 0x1 */
+ /* PAD1 [4:4] RW value= 0x1 */
+ /* PAD2 [8:4] RW value= 0x1 */
+ /* PAD3 [12:4] RW value= 0x1 */
+ /* PAD4 [16:4] RW value= 0x1 */
+ /* PAD5 [20:4] RW value= 0x1 */
+ /* PAD6 [24:4] RW value= 0x1 */
+ /* PAD7 [28:4] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_IOMUX2_CR)
+/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
+EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
+I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
+(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
+Logic 0,0xE implies Logic 1, 0xF implies Tristate */
+#define LIBERO_SETTING_IOMUX2_CR 0x00FF1111UL
+ /* PAD8 [0:4] RW value= 0x1 */
+ /* PAD9 [4:4] RW value= 0x1 */
+ /* PAD10 [8:4] RW value= 0x1 */
+ /* PAD11 [12:4] RW value= 0x1 */
+ /* PAD12 [16:4] RW value= 0xF */
+ /* PAD13 [20:4] RW value= 0xF */
+#endif
+#if !defined (LIBERO_SETTING_IOMUX3_CR)
+/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
+EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
+I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
+(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
+Logic 0,0xE implies Logic 1, 0xF implies Tristate */
+#define LIBERO_SETTING_IOMUX3_CR 0x44444444UL
+ /* PAD14 [0:4] RW value= 0x4 */
+ /* PAD15 [4:4] RW value= 0x4 */
+ /* PAD16 [8:4] RW value= 0x4 */
+ /* PAD17 [12:4] RW value= 0x4 */
+ /* PAD18 [16:4] RW value= 0x4 */
+ /* PAD19 [20:4] RW value= 0x4 */
+ /* PAD20 [24:4] RW value= 0x4 */
+ /* PAD21 [28:4] RW value= 0x4 */
+#endif
+#if !defined (LIBERO_SETTING_IOMUX4_CR)
+/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
+EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
+I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
+(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
+Logic 0,0xE implies Logic 1, 0xF implies Tristate */
+#define LIBERO_SETTING_IOMUX4_CR 0x88CC4444UL
+ /* PAD22 [0:4] RW value= 0x4 */
+ /* PAD23 [4:4] RW value= 0x4 */
+ /* PAD24 [8:4] RW value= 0x4 */
+ /* PAD25 [12:4] RW value= 0x4 */
+ /* PAD26 [16:4] RW value= 0xC */
+ /* PAD27 [20:4] RW value= 0xC */
+ /* PAD28 [24:4] RW value= 0x8 */
+ /* PAD29 [28:4] RW value= 0x8 */
+#endif
+#if !defined (LIBERO_SETTING_IOMUX5_CR)
+/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
+EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
+I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
+(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
+Logic 0,0xE implies Logic 1, 0xF implies Tristate */
+#define LIBERO_SETTING_IOMUX5_CR 0xF7772222UL
+ /* PAD30 [0:4] RW value= 0x2 */
+ /* PAD31 [4:4] RW value= 0x2 */
+ /* PAD32 [8:4] RW value= 0x2 */
+ /* PAD33 [12:4] RW value= 0x2 */
+ /* PAD34 [16:4] RW value= 0x7 */
+ /* PAD35 [20:4] RW value= 0x7 */
+ /* PAD36 [24:4] RW value= 0x7 */
+ /* PAD37 [28:4] RW value= 0xF */
+#endif
+#if !defined (LIBERO_SETTING_IOMUX6_CR)
+/*Sets whether the MMC/SD Voltage select lines are inverted on entry to the
+IOMUX structure */
+#define LIBERO_SETTING_IOMUX6_CR 0x00000000UL
+ /* VLT_SEL [0:1] RW value= 0x0 */
+ /* VLT_EN [1:1] RW value= 0x0 */
+ /* VLT_CMD_DIR [2:1] RW value= 0x0 */
+ /* VLT_DIR_0 [3:1] RW value= 0x0 */
+ /* VLT_DIR_1_3 [4:1] RW value= 0x0 */
+ /* SD_LED [5:1] RW value= 0x0 */
+ /* SD_VOLT_0 [6:1] RW value= 0x0 */
+ /* SD_VOLT_1 [7:1] RW value= 0x0 */
+ /* SD_VOLT_2 [8:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_CFG_CR)
+/*Configures the MSSIO block using SCB write */
+#define LIBERO_SETTING_MSSIO_BANK4_CFG_CR 0x00040A0DUL
+ /* BANK_PCODE [0:6] RW value= 0xD */
+ /* RESERVED0 [6:2] RW value= 0x00 */
+ /* BANK_NCODE [8:6] RW value= 0xA */
+ /* RESERVED1 [14:2] RW value= 0x0 */
+ /* VS [16:4] RW value= 0x4 */
+ /* RESERVED2 [20:12] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_0_1_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_0_1_CR 0x09280928UL
+ /* IO_CFG_0 [0:16] RW value= 0x0928 */
+ /* IO_CFG_1 [16:16] RW value= 0x0928 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_2_3_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_2_3_CR 0x09280928UL
+ /* IO_CFG_2 [0:16] RW value= 0x0928 */
+ /* IO_CFG_3 [16:16] RW value= 0x0928 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_4_5_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_4_5_CR 0x09280928UL
+ /* IO_CFG_4 [0:16] RW value= 0x0928 */
+ /* IO_CFG_5 [16:16] RW value= 0x0928 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_6_7_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_6_7_CR 0x09280928UL
+ /* IO_CFG_6 [0:16] RW value= 0x0928 */
+ /* IO_CFG_7 [16:16] RW value= 0x0928 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_8_9_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_8_9_CR 0x09280928UL
+ /* IO_CFG_8 [0:16] RW value= 0x0928 */
+ /* IO_CFG_9 [16:16] RW value= 0x0928 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_10_11_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_10_11_CR 0x09280928UL
+ /* IO_CFG_10 [0:16] RW value= 0x0928 */
+ /* IO_CFG_11 [16:16] RW value= 0x0928 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_12_13_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_12_13_CR 0x09280928UL
+ /* IO_CFG_12 [0:16] RW value= 0x0928 */
+ /* IO_CFG_13 [16:16] RW value= 0x0928 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_CFG_CR)
+/*Configures the MSSIO block using SCB write */
+#define LIBERO_SETTING_MSSIO_BANK2_CFG_CR 0x00080907UL
+ /* BANK_PCODE [0:6] RW value= 0x7 */
+ /* RESERVED0 [6:2] RW value= 0x00 */
+ /* BANK_NCODE [8:6] RW value= 0x9 */
+ /* RESERVED1 [14:2] RW value= 0x0 */
+ /* VS [16:4] RW value= 0x8 */
+ /* RESERVED2 [20:12] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_0_1_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_0_1_CR 0x08290829UL
+ /* IO_CFG_0 [0:16] RW value= 0x0829 */
+ /* IO_CFG_1 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_2_3_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_2_3_CR 0x08290829UL
+ /* IO_CFG_2 [0:16] RW value= 0x0829 */
+ /* IO_CFG_3 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_4_5_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_4_5_CR 0x08290829UL
+ /* IO_CFG_4 [0:16] RW value= 0x0829 */
+ /* IO_CFG_5 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_6_7_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_6_7_CR 0x08290829UL
+ /* IO_CFG_6 [0:16] RW value= 0x0829 */
+ /* IO_CFG_7 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_8_9_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_8_9_CR 0x08290829UL
+ /* IO_CFG_8 [0:16] RW value= 0x0829 */
+ /* IO_CFG_9 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_10_11_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_10_11_CR 0x08290829UL
+ /* IO_CFG_10 [0:16] RW value= 0x0829 */
+ /* IO_CFG_11 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_12_13_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_12_13_CR 0x08290829UL
+ /* IO_CFG_12 [0:16] RW value= 0x0829 */
+ /* IO_CFG_13 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_14_15_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_14_15_CR 0x08290829UL
+ /* IO_CFG_14 [0:16] RW value= 0x0829 */
+ /* IO_CFG_15 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_16_17_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_16_17_CR 0x08290829UL
+ /* IO_CFG_16 [0:16] RW value= 0x0829 */
+ /* IO_CFG_17 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_18_19_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_18_19_CR 0x08290829UL
+ /* IO_CFG_18 [0:16] RW value= 0x0829 */
+ /* IO_CFG_19 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_20_21_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_20_21_CR 0x08290829UL
+ /* IO_CFG_20 [0:16] RW value= 0x0829 */
+ /* IO_CFG_21 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_22_23_CR)
+/*IO electrical configuration for MSSIO pad */
+#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_22_23_CR 0x08290829UL
+ /* IO_CFG_22 [0:16] RW value= 0x0829 */
+ /* IO_CFG_23 [16:16] RW value= 0x0829 */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_VB2_CFG)
+/*default dpc values for MSSIO bank 2 */
+#define LIBERO_SETTING_MSSIO_VB2_CFG 0x00000828UL
+ /* DPC_IO_CFG_IBUFMD_0 [0:1] RW value= 0x0 */
+ /* DPC_IO_CFG_IBUFMD_1 [1:1] RW value= 0x0 */
+ /* DPC_IO_CFG_IBUFMD_2 [2:1] RW value= 0x0 */
+ /* DPC_IO_CFG_DRV_0 [3:1] RW value= 0x1 */
+ /* DPC_IO_CFG_DRV_1 [4:1] RW value= 0x0 */
+ /* DPC_IO_CFG_DRV_2 [5:1] RW value= 0x1 */
+ /* DPC_IO_CFG_DRV_3 [6:1] RW value= 0x0 */
+ /* DPC_IO_CFG_CLAMP [7:1] RW value= 0x0 */
+ /* DPC_IO_CFG_ENHYST [8:1] RW value= 0x0 */
+ /* DPC_IO_CFG_LOCKDN_EN [9:1] RW value= 0x0 */
+ /* DPC_IO_CFG_WPD [10:1] RW value= 0x0 */
+ /* DPC_IO_CFG_WPU [11:1] RW value= 0x1 */
+ /* DPC_IO_CFG_ATP_EN [12:1] RW value= 0x0 */
+ /* DPC_IO_CFG_LP_PERSIST_EN [13:1] RW value= 0x0 */
+ /* DPC_IO_CFG_LP_BYPASS_EN [14:1] RW value= 0x0 */
+ /* RESERVED [15:17] R */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_VB4_CFG)
+/*default dpc values for MSSIO bank 4 */
+#define LIBERO_SETTING_MSSIO_VB4_CFG 0x00000828UL
+ /* DPC_IO_CFG_IBUFMD_0 [0:1] RW value= 0x0 */
+ /* DPC_IO_CFG_IBUFMD_1 [1:1] RW value= 0x0 */
+ /* DPC_IO_CFG_IBUFMD_2 [2:1] RW value= 0x0 */
+ /* DPC_IO_CFG_DRV_0 [3:1] RW value= 0x1 */
+ /* DPC_IO_CFG_DRV_1 [4:1] RW value= 0x0 */
+ /* DPC_IO_CFG_DRV_2 [5:1] RW value= 0x1 */
+ /* DPC_IO_CFG_DRV_3 [6:1] RW value= 0x0 */
+ /* DPC_IO_CFG_CLAMP [7:1] RW value= 0x0 */
+ /* DPC_IO_CFG_ENHYST [8:1] RW value= 0x0 */
+ /* DPC_IO_CFG_LOCKDN_EN [9:1] RW value= 0x0 */
+ /* DPC_IO_CFG_WPD [10:1] RW value= 0x0 */
+ /* DPC_IO_CFG_WPU [11:1] RW value= 0x1 */
+ /* DPC_IO_CFG_ATP_EN [12:1] RW value= 0x0 */
+ /* DPC_IO_CFG_LP_PERSIST_EN [13:1] RW value= 0x0 */
+ /* DPC_IO_CFG_LP_BYPASS_EN [14:1] RW value= 0x0 */
+ /* RESERVED [15:17] R */
+#endif
+#if !defined (LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS)
+/*Indicates if eMMC is configured for use (bit 0 == 1), If SD is configued for
+use (bit 1 == 1). Bit 2 indicates which one should be used by default on MSS
+embedded software startup ( bit2 == 0, implies default is eMMC, bit2 == 1,
+implies default is SD). The eMMC configuration is always defined in xml tag
+(io_mux, the SD configuration is always defined in xml tag (io_mux_alt). All
+other elements in the (o_mux) and (io_mux_alt) not releating to eMMC/SD
+differences should be the same values. */
+#define LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS 0x00000000UL
+ /* EMMC_CONFIGURED [0:1] RW value= 0x0 */
+ /* SD_CONFIGURED [1:1] RW value= 0x0 */
+ /* DEFAULT_ON_START [2:1] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MSSIO_MUX_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_apb_split.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_apb_split.h
new file mode 100644
index 00000000..c6dd3e86
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_apb_split.h
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_apb_split.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_APB_SPLIT_H_
+#define HW_APB_SPLIT_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_APB_SPLIT_VERSION)
+/*This version incrments when change to format of this file */
+#define LIBERO_SETTING_APB_SPLIT_VERSION 0x00000001UL
+ /* VERSION [0:32] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_MEM_CONFIGS_ENABLED)
+/*Enabled in configurator when bit set to 1 */
+#define LIBERO_SETTING_MEM_CONFIGS_ENABLED 0x00000000UL
+ /* PMP [0:0] RW value= 0x0 */
+ /* MPU [1:0] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_APBBUS_CR)
+/*AMP Mode peripheral mapping register. When the register bit is '0' the
+peripheral is mapped into the 0x2000000 address range using AXI bus 5 from the
+Coreplex. When the register bit is '1' the peripheral is mapped into the
+0x28000000 address range using AXI bus 6 from the Coreplex. */
+#define LIBERO_SETTING_APBBUS_CR 0x00000000UL
+ /* MMUART0 [0:1] RW value= 0x0 */
+ /* MMUART1 [1:1] RW value= 0x0 */
+ /* MMUART2 [2:1] RW value= 0x0 */
+ /* MMUART3 [3:1] RW value= 0x0 */
+ /* MMUART4 [4:1] RW value= 0x0 */
+ /* WDOG0 [5:1] RW value= 0x0 */
+ /* WDOG1 [6:1] RW value= 0x0 */
+ /* WDOG2 [7:1] RW value= 0x0 */
+ /* WDOG3 [8:1] RW value= 0x0 */
+ /* WDOG4 [9:1] RW value= 0x0 */
+ /* SPI0 [10:1] RW value= 0x0 */
+ /* SPI1 [11:1] RW value= 0x0 */
+ /* I2C0 [12:1] RW value= 0x0 */
+ /* I2C1 [13:1] RW value= 0x0 */
+ /* CAN0 [14:1] RW value= 0x0 */
+ /* CAN1 [15:1] RW value= 0x0 */
+ /* GEM0 [16:1] RW value= 0x0 */
+ /* GEM1 [17:1] RW value= 0x0 */
+ /* TIMER [18:1] RW value= 0x0 */
+ /* GPIO0 [19:1] RW value= 0x0 */
+ /* GPIO1 [20:1] RW value= 0x0 */
+ /* GPIO2 [21:1] RW value= 0x0 */
+ /* RTC [22:1] RW value= 0x0 */
+ /* H2FINT [23:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_A_EN)
+/*AMP context A. When the register bit is '0' the peripheral is not allowed
+access from context A. */
+#define LIBERO_SETTING_CONTEXT_A_EN 0x00000000UL
+ /* MMUART0 [0:1] RW value= 0x0 */
+ /* MMUART1 [1:1] RW value= 0x0 */
+ /* MMUART2 [2:1] RW value= 0x0 */
+ /* MMUART3 [3:1] RW value= 0x0 */
+ /* MMUART4 [4:1] RW value= 0x0 */
+ /* WDOG0 [5:1] RW value= 0x0 */
+ /* WDOG1 [6:1] RW value= 0x0 */
+ /* WDOG2 [7:1] RW value= 0x0 */
+ /* WDOG3 [8:1] RW value= 0x0 */
+ /* WDOG4 [9:1] RW value= 0x0 */
+ /* SPI0 [10:1] RW value= 0x0 */
+ /* SPI1 [11:1] RW value= 0x0 */
+ /* I2C0 [12:1] RW value= 0x0 */
+ /* I2C1 [13:1] RW value= 0x0 */
+ /* CAN0 [14:1] RW value= 0x0 */
+ /* CAN1 [15:1] RW value= 0x0 */
+ /* GEM0 [16:1] RW value= 0x0 */
+ /* GEM1 [17:1] RW value= 0x0 */
+ /* TIMER [18:1] RW value= 0x0 */
+ /* GPIO0 [19:1] RW value= 0x0 */
+ /* GPIO1 [20:1] RW value= 0x0 */
+ /* GPIO2 [21:1] RW value= 0x0 */
+ /* RTC [22:1] RW value= 0x0 */
+ /* H2FINT [23:1] RW value= 0x0 */
+ /* CRYPTO [24:1] RW value= 0x0 */
+ /* USB [25:1] RW value= 0x0 */
+ /* QSPIXIP [26:1] RW value= 0x0 */
+ /* ATHENA [27:1] RW value= 0x0 */
+ /* TRACE [28:1] RW value= 0x0 */
+ /* MAILBOX_SC [29:1] RW value= 0x0 */
+ /* EMMC [30:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_EN)
+/*AMP context B. When the register bit is '0' the peripheral is not allowed
+access from context B. */
+#define LIBERO_SETTING_CONTEXT_B_EN 0x00000000UL
+ /* MMUART0 [0:1] RW value= 0x0 */
+ /* MMUART1 [1:1] RW value= 0x0 */
+ /* MMUART2 [2:1] RW value= 0x0 */
+ /* MMUART3 [3:1] RW value= 0x0 */
+ /* MMUART4 [4:1] RW value= 0x0 */
+ /* WDOG0 [5:1] RW value= 0x0 */
+ /* WDOG1 [6:1] RW value= 0x0 */
+ /* WDOG2 [7:1] RW value= 0x0 */
+ /* WDOG3 [8:1] RW value= 0x0 */
+ /* WDOG4 [9:1] RW value= 0x0 */
+ /* SPI0 [10:1] RW value= 0x0 */
+ /* SPI1 [11:1] RW value= 0x0 */
+ /* I2C0 [12:1] RW value= 0x0 */
+ /* I2C1 [13:1] RW value= 0x0 */
+ /* CAN0 [14:1] RW value= 0x0 */
+ /* CAN1 [15:1] RW value= 0x0 */
+ /* GEM0 [16:1] RW value= 0x0 */
+ /* GEM1 [17:1] RW value= 0x0 */
+ /* TIMER [18:1] RW value= 0x0 */
+ /* GPIO0 [19:1] RW value= 0x0 */
+ /* GPIO1 [20:1] RW value= 0x0 */
+ /* GPIO2 [21:1] RW value= 0x0 */
+ /* RTC [22:1] RW value= 0x0 */
+ /* H2FINT [23:1] RW value= 0x0 */
+ /* CRYPTO [24:1] RW value= 0x0 */
+ /* USB [25:1] RW value= 0x0 */
+ /* QSPIXIP [26:1] RW value= 0x0 */
+ /* ATHENA [27:1] RW value= 0x0 */
+ /* TRACE [28:1] RW value= 0x0 */
+ /* MAILBOX_SC [29:1] RW value= 0x0 */
+ /* EMMC [30:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_A_HART_EN)
+/*When the register bit is '0' hart is not associated with context A. */
+#define LIBERO_SETTING_CONTEXT_A_HART_EN 0x00000000UL
+ /* HART0 [0:1] RW value= 0x0 */
+ /* HART1 [1:1] RW value= 0x0 */
+ /* HART2 [2:1] RW value= 0x0 */
+ /* HART3 [3:1] RW value= 0x0 */
+ /* HART4 [4:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_HART_EN)
+/*When the register bit is '0' hart is not associated with context B. */
+#define LIBERO_SETTING_CONTEXT_B_HART_EN 0x00000000UL
+ /* HART0 [0:1] RW value= 0x0 */
+ /* HART1 [1:1] RW value= 0x0 */
+ /* HART2 [2:1] RW value= 0x0 */
+ /* HART3 [3:1] RW value= 0x0 */
+ /* HART4 [4:1] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_APB_SPLIT_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_cache.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_cache.h
new file mode 100644
index 00000000..9500d681
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_cache.h
@@ -0,0 +1,436 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_cache.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_CACHE_H_
+#define HW_CACHE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_WAY_ENABLE)
+/*Way indexes less than or equal to this register value may be used by the
+cache. E.g. set to 0x7, will allocate 8 cache ways, 0-7 to cache, and leave
+8-15 as LIM. Note 1: Way 0 is always allocated as cache. Note 2: each way is
+128KB. */
+#define LIBERO_SETTING_WAY_ENABLE 0x0000000BUL
+ /* WAY_ENABLE [0:8] RW value= 0xB */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_DMA)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_DMA 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_0)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_1)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_2)
+/*Way mask registerAXI slave port 2. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_3)
+/*Way mask register AXI slave port 3. Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_DCACHE)
+/*Way mask register E51 data cache (hart0). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_DCACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_ICACHE)
+/*Way mask registerE52 instruction cache (hart0). Set field to zero to disable
+way from this master. The available cache ways are 0 to number set in
+WAY_ENABLE register. If using scratch pad memory, the ways you want reserved
+for scrathpad are not available for selection, you must set to 0. e.g. If three
+ways reserved for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set
+to zero for all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_ICACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_DCACHE)
+/*Way mask register data cache (hart1). Set field to zero to disable way from
+this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_DCACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_ICACHE)
+/*Way mask register instruction cache (hart1). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_ICACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_DCACHE)
+/*Way mask register data cache (hart2). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_DCACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_ICACHE)
+/*Way mask register instruction cache (hart2). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_ICACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_DCACHE)
+/*Way mask register data cache (hart3). Set field to 1 to disable way from this
+master.Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_DCACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_ICACHE)
+/*Way mask register instruction cache(hart3). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_ICACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_DCACHE)
+/*Way mask register data cache (hart4). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_DCACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_ICACHE)
+/*Way mask register instruction cache (hart4). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_ICACHE 0x0000F0FFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x0 */
+ /* WAY_MASK_9 [9:1] RW value= 0x0 */
+ /* WAY_MASK_10 [10:1] RW value= 0x0 */
+ /* WAY_MASK_11 [11:1] RW value= 0x0 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS)
+/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
+2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
+for scratchpad start at way 0, and work up. */
+#define LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS 0x00000004UL
+ /* NUM_OF_WAYS [0:8] RW value= 0x4 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_CACHE_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_memory.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_memory.h
new file mode 100644
index 00000000..b1df361f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_memory.h
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_memory.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MEMORY_H_
+#define HW_MEMORY_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_RESET_VECTOR_HART0)
+/*Reset vector hart0 */
+#define LIBERO_SETTING_RESET_VECTOR_HART0 0x20220000
+#define LIBERO_SETTING_RESET_VECTOR_HART0_SIZE 0x4 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_RESET_VECTOR_HART1)
+/*Reset vector hart1 */
+#define LIBERO_SETTING_RESET_VECTOR_HART1 0x20220000
+#define LIBERO_SETTING_RESET_VECTOR_HART1_SIZE 0x4 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_RESET_VECTOR_HART2)
+/*Reset vector hart2 */
+#define LIBERO_SETTING_RESET_VECTOR_HART2 0x20220000
+#define LIBERO_SETTING_RESET_VECTOR_HART2_SIZE 0x4 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_RESET_VECTOR_HART3)
+/*Reset vector hart3 */
+#define LIBERO_SETTING_RESET_VECTOR_HART3 0x20220000
+#define LIBERO_SETTING_RESET_VECTOR_HART3_SIZE 0x4 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_RESET_VECTOR_HART4)
+/*Reset vector hart4 */
+#define LIBERO_SETTING_RESET_VECTOR_HART4 0x20220000
+#define LIBERO_SETTING_RESET_VECTOR_HART4_SIZE 0x4 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_DDR_32_CACHE)
+/*example instance of memory */
+#define LIBERO_SETTING_DDR_32_CACHE 0x80000000
+#define LIBERO_SETTING_DDR_32_CACHE_SIZE 0x100000 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_DDR_32_NON_CACHE)
+/*example instance */
+#define LIBERO_SETTING_DDR_32_NON_CACHE 0xC0000000
+#define LIBERO_SETTING_DDR_32_NON_CACHE_SIZE 0x100000 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_DDR_64_CACHE)
+/*64 bit address */
+#define LIBERO_SETTING_DDR_64_CACHE 0x1000000000
+#define LIBERO_SETTING_DDR_64_CACHE_SIZE 0x100000 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_DDR_64_NON_CACHE)
+/*64 bit address */
+#define LIBERO_SETTING_DDR_64_NON_CACHE 0x1400000000
+#define LIBERO_SETTING_DDR_64_NON_CACHE_SIZE 0x100000 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_DDR_32_WCB)
+/*example instance */
+#define LIBERO_SETTING_DDR_32_WCB 0xD0000000
+#define LIBERO_SETTING_DDR_32_WCB_SIZE 0x100000 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_DDR_64_WCB)
+/*64 bit address */
+#define LIBERO_SETTING_DDR_64_WCB 0x1800000000
+#define LIBERO_SETTING_DDR_64_WCB_SIZE 0x100000 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_RESERVED_SNVM)
+/*Offset and size of reserved sNVM. (Not available to MSS) */
+#define LIBERO_SETTING_RESERVED_SNVM 0x00000000
+#define LIBERO_SETTING_RESERVED_SNVM_SIZE 0x00000000 /* Length of memory block*/
+#endif
+#if !defined (LIBERO_SETTING_RESERVED_ENVM)
+/*Offset and size of reserved eNVM (Not available to MSS) */
+#define LIBERO_SETTING_RESERVED_ENVM 0x00000000
+#define LIBERO_SETTING_RESERVED_ENVM_SIZE 0x00000000 /* Length of memory block*/
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MEMORY_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_crypto.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_crypto.h
new file mode 100644
index 00000000..e979f49d
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_crypto.h
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_crypto.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_CRYPTO_H_
+#define HW_MPU_CRYPTO_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_CRYPTO_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic0.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic0.h
new file mode 100644
index 00000000..d13029ef
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic0.h
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_fic0.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_FIC0_H_
+#define HW_MPU_FIC0_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP4)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP5)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP6)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP7)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP8)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP8 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP9)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP9 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP10)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP10 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP11)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP11 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP12)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP12 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP13)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP13 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP14)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP14 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP15)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC0_MPU_CFG_PMP15 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_FIC0_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic1.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic1.h
new file mode 100644
index 00000000..cadd8624
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic1.h
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_fic1.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_FIC1_H_
+#define HW_MPU_FIC1_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP4)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP5)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP6)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP7)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP8)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP8 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP9)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP9 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP10)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP10 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP11)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP11 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP12)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP12 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP13)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP13 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP14)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP14 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP15)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC1_MPU_CFG_PMP15 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_FIC1_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic2.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic2.h
new file mode 100644
index 00000000..8aca9475
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_fic2.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_fic2.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_FIC2_H_
+#define HW_MPU_FIC2_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP4)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP5)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP6)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP7)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_FIC2_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_FIC2_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_gem0.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_gem0.h
new file mode 100644
index 00000000..e6313546
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_gem0.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_gem0.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_GEM0_H_
+#define HW_MPU_GEM0_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP4)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP5)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP6)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP7)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM0_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_GEM0_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_gem1.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_gem1.h
new file mode 100644
index 00000000..3c2284e5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_gem1.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_gem1.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_GEM1_H_
+#define HW_MPU_GEM1_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP4)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP5)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP6)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP7)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_GEM1_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_GEM1_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_mmc.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_mmc.h
new file mode 100644
index 00000000..a3b93e4c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_mmc.h
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_mmc.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_MMC_H_
+#define HW_MPU_MMC_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_MMC_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_MMC_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_MMC_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_MMC_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_MMC_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_scb.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_scb.h
new file mode 100644
index 00000000..02ada2d3
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_scb.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_scb.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_SCB_H_
+#define HW_MPU_SCB_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP4)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP5)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP6)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP7)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_SCB_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_SCB_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_trace.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_trace.h
new file mode 100644
index 00000000..706b8997
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_trace.h
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_trace.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_TRACE_H_
+#define HW_MPU_TRACE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_TRACE_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_TRACE_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_TRACE_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_TRACE_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_TRACE_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_usb.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_usb.h
new file mode 100644
index 00000000..6e799d76
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_mpu_usb.h
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_mpu_usb.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_MPU_USB_H_
+#define HW_MPU_USB_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP0)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_USB_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP1)
+/*mpu setup register, 64 bits */
+#define LIBERO_SETTING_USB_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP2)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_USB_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP3)
+/*pmp setup register, 64 bits */
+#define LIBERO_SETTING_USB_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
+ /* PMP [0:38] RW value= 0xFFFFFFFFF */
+ /* RESERVED [38:18] RW value= 0x0 */
+ /* MODE [56:8] RW value= 0x1F */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_MPU_USB_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart0.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart0.h
new file mode 100644
index 00000000..d770674f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart0.h
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_pmp_hart0.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_PMP_HART0_H_
+#define HW_PMP_HART0_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPCFG0)
+/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART0_CSR_PMPCFG0 0x0000000000000000ULL
+ /* PMP0CFG [0:8] RW value= 0x00 */
+ /* PMP1CFG [8:8] RW value= 0x0 */
+ /* PMP2CFG [16:8] RW value= 0x00 */
+ /* PMP3CFG [24:8] RW value= 0x00 */
+ /* PMP4CFG [32:8] RW value= 0x00 */
+ /* PMP5CFG [40:8] RW value= 0x00 */
+ /* PMP6CFG [48:8] RW value= 0x00 */
+ /* PMP7CFG [56:8] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPCFG2)
+/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART0_CSR_PMPCFG2 0x0000000000000000ULL
+ /* PMP8CFG [0:8] RW value= 0x00 */
+ /* PMP9CFG [8:8] RW value= 0x00 */
+ /* PMP10CFG [16:8] RW value= 0x00 */
+ /* PMP11CFG [24:8] RW value= 0x00 */
+ /* PMP12CFG [32:8] RW value= 0x00 */
+ /* PMP13CFG [40:8] RW value= 0x00 */
+ /* PMP14CFG [48:8] RW value= 0x00 */
+ /* PMP15CFG [56:8] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR0)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR0 0x0000000000000000ULL
+ /* CSR_PMPADDR0 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR1)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR1 0x0000000000000000ULL
+ /* CSR_PMPADDR1 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR2)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR2 0x0000000000000000ULL
+ /* CSR_PMPADDR2 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR3)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR3 0x0000000000000000ULL
+ /* CSR_PMPADDR3 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR4)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR4 0x0000000000000000ULL
+ /* CSR_PMPADDR4 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR5)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR5 0x0000000000000000ULL
+ /* CSR_PMPADDR5 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR6)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR6 0x0000000000000000ULL
+ /* CSR_PMPADDR6 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR7)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR7 0x0000000000000000ULL
+ /* CSR_PMPADDR7 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR8)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR8 0x0000000000000000ULL
+ /* CSR_PMPADDR8 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR9)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR9 0x0000000000000000ULL
+ /* CSR_PMPADDR9 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR10)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR10 0x0000000000000000ULL
+ /* CSR_PMPADDR10 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR11)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR11 0x0000000000000000ULL
+ /* CSR_PMPADDR11 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR12)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR12 0x0000000000000000ULL
+ /* CSR_PMPADDR12 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR13)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR13 0x0000000000000000ULL
+ /* CSR_PMPADDR13 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR14)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR14 0x0000000000000000ULL
+ /* CSR_PMPADDR14 [0:64] RW value= 0x00 */
+#endif
+#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR15)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART0_CSR_PMPADDR15 0x0000000000000000ULL
+ /* CSR_PMPADDR15 [0:64] RW value= 0x00 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_PMP_HART0_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart1.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart1.h
new file mode 100644
index 00000000..bdb199dd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart1.h
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_pmp_hart1.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_PMP_HART1_H_
+#define HW_PMP_HART1_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPCFG0)
+/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART1_CSR_PMPCFG0 0x000000000000009FULL
+ /* PMP0CFG [0:8] RW value= 0x9F */
+ /* PMP1CFG [8:8] RW value= 0x0 */
+ /* PMP2CFG [16:8] RW value= 0x0 */
+ /* PMP3CFG [24:8] RW value= 0x0 */
+ /* PMP4CFG [32:8] RW value= 0x0 */
+ /* PMP5CFG [40:8] RW value= 0x0 */
+ /* PMP6CFG [48:8] RW value= 0x0 */
+ /* PMP7CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPCFG2)
+/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART1_CSR_PMPCFG2 0x0000000000000000ULL
+ /* PMP8CFG [0:8] RW value= 0x0 */
+ /* PMP9CFG [8:8] RW value= 0x0 */
+ /* PMP10CFG [16:8] RW value= 0x0 */
+ /* PMP11CFG [24:8] RW value= 0x0 */
+ /* PMP12CFG [32:8] RW value= 0x0 */
+ /* PMP13CFG [40:8] RW value= 0x0 */
+ /* PMP14CFG [48:8] RW value= 0x0 */
+ /* PMP15CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR0)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR0 0xFFFFFFFFFFFFFFFFULL
+ /* CSR_PMPADDR0 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR1)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR1 0x0000000000000000ULL
+ /* CSR_PMPADDR1 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR2)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR2 0x0000000000000000ULL
+ /* CSR_PMPADDR2 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR3)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR3 0x0000000000000000ULL
+ /* CSR_PMPADDR3 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR4)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR4 0x0000000000000000ULL
+ /* CSR_PMPADDR4 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR5)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR5 0x0000000000000000ULL
+ /* CSR_PMPADDR5 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR6)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR6 0x0000000000000000ULL
+ /* CSR_PMPADDR6 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR7)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR7 0x0000000000000000ULL
+ /* CSR_PMPADDR7 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR8)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR8 0x0000000000000000ULL
+ /* CSR_PMPADDR8 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR9)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR9 0x0000000000000000ULL
+ /* CSR_PMPADDR9 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR10)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR10 0x0000000000000000ULL
+ /* CSR_PMPADDR10 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR11)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR11 0x0000000000000000ULL
+ /* CSR_PMPADDR11 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR12)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR12 0x0000000000000000ULL
+ /* CSR_PMPADDR12 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR13)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR13 0x0000000000000000ULL
+ /* CSR_PMPADDR13 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR14)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR14 0x0000000000000000ULL
+ /* CSR_PMPADDR14 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR15)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART1_CSR_PMPADDR15 0x0000000000000000ULL
+ /* CSR_PMPADDR15 [0:64] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_PMP_HART1_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart2.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart2.h
new file mode 100644
index 00000000..8c3928dc
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart2.h
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_pmp_hart2.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_PMP_HART2_H_
+#define HW_PMP_HART2_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPCFG0)
+/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART2_CSR_PMPCFG0 0x000000000000009FULL
+ /* PMP0CFG [0:8] RW value= 0x9F */
+ /* PMP1CFG [8:8] RW value= 0x0 */
+ /* PMP2CFG [16:8] RW value= 0x0 */
+ /* PMP3CFG [24:8] RW value= 0x0 */
+ /* PMP4CFG [32:8] RW value= 0x0 */
+ /* PMP5CFG [40:8] RW value= 0x0 */
+ /* PMP6CFG [48:8] RW value= 0x0 */
+ /* PMP7CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPCFG2)
+/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART2_CSR_PMPCFG2 0x0000000000000000ULL
+ /* PMP8CFG [0:8] RW value= 0x0 */
+ /* PMP9CFG [8:8] RW value= 0x0 */
+ /* PMP10CFG [16:8] RW value= 0x0 */
+ /* PMP11CFG [24:8] RW value= 0x0 */
+ /* PMP12CFG [32:8] RW value= 0x0 */
+ /* PMP13CFG [40:8] RW value= 0x0 */
+ /* PMP14CFG [48:8] RW value= 0x0 */
+ /* PMP15CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR0)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR0 0xFFFFFFFFFFFFFFFFULL
+ /* CSR_PMPADDR0 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR1)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR1 0x0000000000000000ULL
+ /* CSR_PMPADDR1 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR2)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR2 0x0000000000000000ULL
+ /* CSR_PMPADDR2 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR3)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR3 0x0000000000000000ULL
+ /* CSR_PMPADDR3 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR4)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR4 0x0000000000000000ULL
+ /* CSR_PMPADDR4 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR5)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR5 0x0000000000000000ULL
+ /* CSR_PMPADDR5 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR6)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR6 0x0000000000000000ULL
+ /* CSR_PMPADDR6 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR7)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR7 0x0000000000000000ULL
+ /* CSR_PMPADDR7 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR8)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR8 0x0000000000000000ULL
+ /* CSR_PMPADDR8 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR9)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR9 0x0000000000000000ULL
+ /* CSR_PMPADDR9 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR10)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR10 0x0000000000000000ULL
+ /* CSR_PMPADDR10 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR11)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR11 0x0000000000000000ULL
+ /* CSR_PMPADDR11 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR12)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR12 0x0000000000000000ULL
+ /* CSR_PMPADDR12 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR13)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR13 0x0000000000000000ULL
+ /* CSR_PMPADDR13 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR14)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR14 0x0000000000000000ULL
+ /* CSR_PMPADDR14 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR15)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART2_CSR_PMPADDR15 0x0000000000000000ULL
+ /* CSR_PMPADDR15 [0:64] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_PMP_HART2_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart3.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart3.h
new file mode 100644
index 00000000..d09e15a9
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart3.h
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_pmp_hart3.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_PMP_HART3_H_
+#define HW_PMP_HART3_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPCFG0)
+/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART3_CSR_PMPCFG0 0x000000000000009FULL
+ /* PMP0CFG [0:8] RW value= 0x9F */
+ /* PMP1CFG [8:8] RW value= 0x0 */
+ /* PMP2CFG [16:8] RW value= 0x0 */
+ /* PMP3CFG [24:8] RW value= 0x0 */
+ /* PMP4CFG [32:8] RW value= 0x0 */
+ /* PMP5CFG [40:8] RW value= 0x0 */
+ /* PMP6CFG [48:8] RW value= 0x0 */
+ /* PMP7CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPCFG2)
+/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART3_CSR_PMPCFG2 0x0000000000000000ULL
+ /* PMP8CFG [0:8] RW value= 0x0 */
+ /* PMP9CFG [8:8] RW value= 0x0 */
+ /* PMP10CFG [16:8] RW value= 0x0 */
+ /* PMP11CFG [24:8] RW value= 0x0 */
+ /* PMP12CFG [32:8] RW value= 0x0 */
+ /* PMP13CFG [40:8] RW value= 0x0 */
+ /* PMP14CFG [48:8] RW value= 0x0 */
+ /* PMP15CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR0)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR0 0xFFFFFFFFFFFFFFFFULL
+ /* CSR_PMPADDR0 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR1)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR1 0x0000000000000000ULL
+ /* CSR_PMPADDR1 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR2)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR2 0x0000000000000000ULL
+ /* CSR_PMPADDR2 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR3)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR3 0x0000000000000000ULL
+ /* CSR_PMPADDR3 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR4)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR4 0x0000000000000000ULL
+ /* CSR_PMPADDR4 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR5)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR5 0x0000000000000000ULL
+ /* CSR_PMPADDR5 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR6)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR6 0x0000000000000000ULL
+ /* CSR_PMPADDR6 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR7)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR7 0x0000000000000000ULL
+ /* CSR_PMPADDR7 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR8)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR8 0x0000000000000000ULL
+ /* CSR_PMPADDR8 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR9)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR9 0x0000000000000000ULL
+ /* CSR_PMPADDR9 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR10)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR10 0x0000000000000000ULL
+ /* CSR_PMPADDR10 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR11)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR11 0x0000000000000000ULL
+ /* CSR_PMPADDR11 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR12)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR12 0x0000000000000000ULL
+ /* CSR_PMPADDR12 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR13)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR13 0x0000000000000000ULL
+ /* CSR_PMPADDR13 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR14)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR14 0x0000000000000000ULL
+ /* CSR_PMPADDR14 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR15)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART3_CSR_PMPADDR15 0x0000000000000000ULL
+ /* CSR_PMPADDR15 [0:64] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_PMP_HART3_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart4.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart4.h
new file mode 100644
index 00000000..5f2696d9
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/memory_map/hw_pmp_hart4.h
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_pmp_hart4.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_PMP_HART4_H_
+#define HW_PMP_HART4_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPCFG0)
+/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART4_CSR_PMPCFG0 0x000000000000009FULL
+ /* PMP0CFG [0:8] RW value= 0x9F */
+ /* PMP1CFG [8:8] RW value= 0x0 */
+ /* PMP2CFG [16:8] RW value= 0x0 */
+ /* PMP3CFG [24:8] RW value= 0x0 */
+ /* PMP4CFG [32:8] RW value= 0x0 */
+ /* PMP5CFG [40:8] RW value= 0x0 */
+ /* PMP6CFG [48:8] RW value= 0x0 */
+ /* PMP7CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPCFG2)
+/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
+execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
+#define LIBERO_SETTING_HART4_CSR_PMPCFG2 0x0000000000000000ULL
+ /* PMP8CFG [0:8] RW value= 0x0 */
+ /* PMP9CFG [8:8] RW value= 0x0 */
+ /* PMP10CFG [16:8] RW value= 0x0 */
+ /* PMP11CFG [24:8] RW value= 0x0 */
+ /* PMP12CFG [32:8] RW value= 0x0 */
+ /* PMP13CFG [40:8] RW value= 0x0 */
+ /* PMP14CFG [48:8] RW value= 0x0 */
+ /* PMP15CFG [56:8] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR0)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR0 0xFFFFFFFFFFFFFFFFULL
+ /* CSR_PMPADDR0 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR1)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR1 0x0000000000000000ULL
+ /* CSR_PMPADDR1 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR2)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR2 0x0000000000000000ULL
+ /* CSR_PMPADDR2 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR3)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR3 0x0000000000000000ULL
+ /* CSR_PMPADDR3 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR4)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR4 0x0000000000000000ULL
+ /* CSR_PMPADDR4 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR5)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR5 0x0000000000000000ULL
+ /* CSR_PMPADDR5 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR6)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR6 0x0000000000000000ULL
+ /* CSR_PMPADDR6 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR7)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR7 0x0000000000000000ULL
+ /* CSR_PMPADDR7 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR8)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR8 0x0000000000000000ULL
+ /* CSR_PMPADDR8 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR9)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR9 0x0000000000000000ULL
+ /* CSR_PMPADDR9 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR10)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR10 0x0000000000000000ULL
+ /* CSR_PMPADDR10 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR11)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR11 0x0000000000000000ULL
+ /* CSR_PMPADDR11 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR12)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR12 0x0000000000000000ULL
+ /* CSR_PMPADDR12 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR13)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR13 0x0000000000000000ULL
+ /* CSR_PMPADDR13 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR14)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR14 0x0000000000000000ULL
+ /* CSR_PMPADDR14 [0:64] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR15)
+/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
+in CSR_PMPCFGx */
+#define LIBERO_SETTING_HART4_CSR_PMPADDR15 0x0000000000000000ULL
+ /* CSR_PMPADDR15 [0:64] RW value= 0x0 */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_PMP_HART4_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/sgmii/hw_sgmii_tip.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/sgmii/hw_sgmii_tip.h
new file mode 100644
index 00000000..88a3e41b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/fpga_design_config/sgmii/hw_sgmii_tip.h
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * @file hw_sgmii_tip.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ *
+ *
+ * Note 1: This file should not be edited. If you need to modify a parameter
+ * without going through regenerating using the MSS Configurator Libero flow
+ * or editing the associated xml file
+ * the following method is recommended:
+
+ * 1. edit the following file
+ * boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
+
+ * 2. define the value you want to override there.
+ * (Note: There is a commented example in the platform directory)
+
+ * Note 2: The definition in mss_sw_config.h takes precedence, as
+ * mss_sw_config.h is included prior to the generated header files located in
+ * boards/your_board/fpga_design_config
+ *
+ */
+
+#ifndef HW_SGMII_TIP_H_
+#define HW_SGMII_TIP_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_SGMII_MODE)
+/*SGMII mode control (SEU) */
+#define LIBERO_SETTING_SGMII_MODE 0x08C0E6FFUL
+ /* REG_PLL_EN [0:1] RW value= 0x1 */
+ /* REG_DLL_EN [1:1] RW value= 0x1 */
+ /* REG_PVT_EN [2:1] RW value= 0x1 */
+ /* REG_BC_VRGEN_EN [3:1] RW value= 0x1 */
+ /* REG_TX0_EN [4:1] RW value= 0x1 */
+ /* REG_RX0_EN [5:1] RW value= 0x1 */
+ /* REG_TX1_EN [6:1] RW value= 0x1 */
+ /* REG_RX1_EN [7:1] RW value= 0x1 */
+ /* REG_DLL_LOCK_FLT [8:2] RW value= 0x2 */
+ /* REG_DLL_ADJ_CODE [10:4] RW value= 0x9 */
+ /* REG_CH0_CDR_RESET_B [14:1] RW value= 0x1 */
+ /* REG_CH1_CDR_RESET_B [15:1] RW value= 0x1 */
+ /* REG_BC_VRGEN [16:6] RW value= 0x00 */
+ /* REG_CDR_MOVE_STEP [22:1] RW value= 0x1 */
+ /* REG_REFCLK_EN_RDIFF [23:1] RW value= 0x1 */
+ /* REG_BC_VS [24:4] RW value= 0x8 */
+ /* REG_REFCLK_EN_UDRIVE_P [28:1] RW value= 0x0 */
+ /* REG_REFCLK_EN_INS_HYST_P [29:1] RW value= 0x0 */
+ /* REG_REFCLK_EN_UDRIVE_N [30:1] RW value= 0x0 */
+ /* REG_REFCLK_EN_INS_HYST_N [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_PLL_CNTL)
+/*PLL control register (SEU) */
+#define LIBERO_SETTING_PLL_CNTL 0x80140101UL
+ /* REG_PLL_POSTDIV [0:7] RW value= 0x1 */
+ /* ARO_PLL0_LOCK [7:1] RO */
+ /* REG_PLL_RFDIV [8:6] RW value= 0x1 */
+ /* REG_PLL_REG_RFCLK_SEL [14:1] RW value= 0x0 */
+ /* REG_PLL_LP_REQUIRES_LOCK [15:1] RW value= 0x0 */
+ /* REG_PLL_INTIN [16:12] RW value= 0x14 */
+ /* REG_PLL_BWI [28:2] RW value= 0x0 */
+ /* REG_PLL_BWP [30:2] RW value= 0x2 */
+#endif
+#if !defined (LIBERO_SETTING_CH0_CNTL)
+/*Channel0 control register */
+#define LIBERO_SETTING_CH0_CNTL 0x37F07770UL
+ /* REG_TX0_WPU_P [0:1] RW value= 0x0 */
+ /* REG_TX0_WPD_P [1:1] RW value= 0x0 */
+ /* REG_TX0_SLEW_P [2:2] RW value= 0x0 */
+ /* REG_TX0_DRV_P [4:4] RW value= 0x7 */
+ /* REG_TX0_ODT_P [8:4] RW value= 0x7 */
+ /* REG_TX0_ODT_STATIC_P [12:3] RW value= 0x7 */
+ /* REG_RX0_TIM_LONG [15:1] RW value= 0x0 */
+ /* REG_RX0_WPU_P [16:1] RW value= 0x0 */
+ /* REG_RX0_WPD_P [17:1] RW value= 0x0 */
+ /* REG_RX0_IBUFMD_P [18:3] RW value= 0x4 */
+ /* REG_RX0_EYEWIDTH_P [21:3] RW value= 0x7 */
+ /* REG_RX0_ODT_P [24:4] RW value= 0x7 */
+ /* REG_RX0_ODT_STATIC_P [28:3] RW value= 0x3 */
+ /* REG_RX0_EN_FLAG_N [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_CH1_CNTL)
+/*Channel1 control register */
+#define LIBERO_SETTING_CH1_CNTL 0x37F07770UL
+ /* REG_TX1_WPU_P [0:1] RW value= 0x0 */
+ /* REG_TX1_WPD_P [1:1] RW value= 0x0 */
+ /* REG_TX1_SLEW_P [2:2] RW value= 0x0 */
+ /* REG_TX1_DRV_P [4:4] RW value= 0x7 */
+ /* REG_TX1_ODT_P [8:4] RW value= 0x7 */
+ /* REG_TX1_ODT_STATIC_P [12:3] RW value= 0x7 */
+ /* REG_RX1_TIM_LONG [15:1] RW value= 0x0 */
+ /* REG_RX1_WPU_P [16:1] RW value= 0x0 */
+ /* REG_RX1_WPD_P [17:1] RW value= 0x0 */
+ /* REG_RX1_IBUFMD_P [18:3] RW value= 0x4 */
+ /* REG_RX1_EYEWIDTH_P [21:3] RW value= 0x7 */
+ /* REG_RX1_ODT_P [24:4] RW value= 0x7 */
+ /* REG_RX1_ODT_STATIC_P [28:3] RW value= 0x3 */
+ /* REG_RX1_EN_FLAG_N [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_RECAL_CNTL)
+/*Recalibration control register */
+#define LIBERO_SETTING_RECAL_CNTL 0x000020C8UL
+ /* REG_RECAL_DIFF_RANGE [0:5] RW value= 0x8 */
+ /* REG_RECAL_START_EN [5:1] RW value= 0x0 */
+ /* REG_PVT_CALIB_START [6:1] RW value= 0x1 */
+ /* REG_PVT_CALIB_LOCK [7:1] RW value= 0x1 */
+ /* REG_RECAL_UPD [8:1] RW value= 0x0 */
+ /* BC_VRGEN_DIRECTION [9:1] RW value= 0x0 */
+ /* BC_VRGEN_LOAD [10:1] RW value= 0x0 */
+ /* BC_VRGEN_MOVE [11:1] RW value= 0x0 */
+ /* REG_PVT_REG_CALIB_CLKDIV [12:2] RW value= 0x2 */
+ /* REG_PVT_REG_CALIB_DIFFR_VSEL [14:2] RW value= 0x0 */
+ /* SRO_DLL_90_CODE [16:7] RO */
+ /* SRO_DLL_LOCK [23:1] RO */
+ /* SRO_DLL_ST_CODE [24:7] RO */
+ /* SRO_RECAL_START [31:1] RO */
+#endif
+#if !defined (LIBERO_SETTING_CLK_CNTL)
+/*Clock input and routing control registers */
+#define LIBERO_SETTING_CLK_CNTL 0xF00050CCUL
+ /* REG_REFCLK_EN_TERM_P [0:2] RW value= 0x0 */
+ /* REG_REFCLK_EN_RXMODE_P [2:2] RW value= 0x3 */
+ /* REG_REFCLK_EN_TERM_N [4:2] RW value= 0x0 */
+ /* REG_REFCLK_EN_RXMODE_N [6:2] RW value= 0x3 */
+ /* REG_REFCLK_CLKBUF_EN_PULLUP [8:1] RW value= 0x0 */
+ /* REG_CLKMUX_FCLK_SEL [9:3] RW value= 0x0 */
+ /* REG_CLKMUX_PLL0_RFCLK0_SEL [12:2] RW value= 0x1 */
+ /* REG_CLKMUX_PLL0_RFCLK1_SEL [14:2] RW value= 0x1 */
+ /* REG_CLKMUX_SPARE0 [16:16] RW value= 0xf000 */
+#endif
+#if !defined (LIBERO_SETTING_DYN_CNTL)
+/*Dynamic control registers */
+#define LIBERO_SETTING_DYN_CNTL 0x00000000UL
+ /* REG_PLL_DYNEN [0:1] RW value= 0x0 */
+ /* REG_DLL_DYNEN [1:1] RW value= 0x0 */
+ /* REG_PVT_DYNEN [2:1] RW value= 0x0 */
+ /* REG_BC_DYNEN [3:1] RW value= 0x0 */
+ /* REG_CLKMUX_DYNEN [4:1] RW value= 0x0 */
+ /* REG_LANE0_DYNEN [5:1] RW value= 0x0 */
+ /* REG_LANE1_DYNEN [6:1] RW value= 0x0 */
+ /* BC_VRGEN_OOR [7:1] RO */
+ /* REG_PLL_SOFT_RESET_PERIPH [8:1] RW value= 0x0 */
+ /* REG_DLL_SOFT_RESET_PERIPH [9:1] RW value= 0x0 */
+ /* REG_PVT_SOFT_RESET_PERIPH [10:1] RW value= 0x0 */
+ /* REG_BC_SOFT_RESET_PERIPH [11:1] RW value= 0x0 */
+ /* REG_CLKMUX_SOFT_RESET_PERIPH [12:1] RW value= 0x0 */
+ /* REG_LANE0_SOFT_RESET_PERIPH [13:1] RW value= 0x0 */
+ /* REG_LANE1_SOFT_RESET_PERIPH [14:1] RW value= 0x0 */
+ /* PVT_CALIB_STATUS [15:1] RO */
+ /* ARO_PLL0_VCO0PH_SEL [16:3] RO */
+ /* ARO_PLL0_VCO1PH_SEL [19:3] RO */
+ /* ARO_PLL0_VCO2PH_SEL [22:3] RO */
+ /* ARO_PLL0_VCO3PH_SEL [25:3] RO */
+ /* ARO_REF_DIFFR [28:4] RO */
+#endif
+#if !defined (LIBERO_SETTING_PVT_STAT)
+/*PVT calibrator status registers */
+#define LIBERO_SETTING_PVT_STAT 0x00000000UL
+ /* ARO_REF_PCODE [0:6] RO */
+ /* ARO_IOEN_BNK [6:1] RO */
+ /* ARO_IOEN_BNK_B [7:1] RO */
+ /* ARO_REF_NCODE [8:6] RO */
+ /* ARO_CALIB_STATUS [14:1] RO */
+ /* ARO_CALIB_STATUS_B [15:1] RO */
+ /* ARO_PCODE [16:6] RO */
+ /* ARO_CALIB_INTRPT [22:1] RO */
+ /* PVT_CALIB_INTRPT [23:1] RO */
+ /* ARO_NCODE [24:6] RO */
+ /* PVT_CALIB_LOCK [30:1] RW value= 0x0 */
+ /* PVT_CALIB_START [31:1] RW value= 0x0 */
+#endif
+#if !defined (LIBERO_SETTING_SPARE_CNTL)
+/*Spare control register */
+#define LIBERO_SETTING_SPARE_CNTL 0xFF000000UL
+ /* REG_SPARE [0:32] RW value= 0xFF000000 */
+#endif
+#if !defined (LIBERO_SETTING_SPARE_STAT)
+/*Spare status register */
+#define LIBERO_SETTING_SPARE_STAT 0x00000000UL
+ /* SRO_SPARE [0:32] RO */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* #ifdef HW_SGMII_TIP_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt
new file mode 100644
index 00000000..d05a6a92
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt
@@ -0,0 +1,5 @@
+contains user configuration of the drivers.
+drivers config should follow the following format:
+platform/config/drivers//_sw_cfg.h
+e.g
+platform/config/drivers/ddr/ddr_sw_cfg.h
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld
new file mode 100644
index 00000000..2ab464f3
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-ddr-loaded-by-boot-loader.ld
+ * Use this linker script when the program is fully located in DDR. The
+ * assumption is DDR has already been initialized by another program.
+ * This linker script can be used with a debugger or when compiled and loaded
+ * by a boot-loader.
+ * Please see the project mpfs-hal-run-from-ddr-1 located in the Bare Metal
+ * library under examples/mpfs-hal for an example of it use.
+ * https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+HEAP_SIZE = 0k; /* needs to be calculated for your application if using */
+
+/*
+ * Stack size for our single hart U54 application.
+ */
+STACK_SIZE_U54_APPLICATION = 8k;
+
+/*
+ * A small amount of unitialised memory used to store information
+ * obtained from the boot-loader on start-up
+ */
+UNITITALISED_MEM = 16B;
+
+/* reset address 0xC0000000 */
+SECTION_START_ADDRESS = 0x80000000;
+
+
+SECTIONS
+{
+
+ /* text: test code section */
+ . = SECTION_START_ADDRESS;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > ddr_cached_32bit
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> ddr_cached_32bit
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > ddr_cached_32bit
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > ddr_cached_32bit
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > ddr_cached_32bit
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__app_stack_bottom = .);
+ . += STACK_SIZE_U54_APPLICATION;
+ PROVIDE(__app_stack_top = .);
+ } > ddr_cached_32bit
+
+ /*
+ * used by a program loaded by a bootloader to store information passed
+ * from boot-loader
+ * a0 holds the hart ID
+ * a1 hold pointer to device data, which includes pointer to shared memory
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .no_init : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ . += UNITITALISED_MEM;
+ PROVIDE(__uninit_top_h$ = .);
+ /*
+ * following not used but need to be provided for compilation
+ */
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__stack_top_h0$ = .);
+ PROVIDE(__stack_top_h1$ = .);
+ PROVIDE(__stack_top_h2$ = .);
+ PROVIDE(__stack_top_h3$ = .);
+ PROVIDE(__stack_top_h4$ = .);
+ } > ddr_cached_32bit
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..45b2bba6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma-envm.ld
+ * Code starts from eNVM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * The startup stack size is used on start-up.
+ * The application stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >envm
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> envm /* On the MPFS for startup code use, >switch_code AT>envm */
+}
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld
new file mode 100644
index 00000000..cf28ec03
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_envm.ld
+ * Use with Bare metal startup code.
+ * Startup code runs from envm on MSS reset
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+STACK_SIZE_PER_HART = 8k;
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ /* *entry.o(.text); */
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > envm
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> envm
+
+ /*
+ * The .ram_code section will contain the code that is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code_dtim AT>envm
+
+ /*
+ * The .ddr_code section will contain the code that is run from DDR.
+ * This is to verify DDR working as expeted
+ */
+ .ddr_code :
+ {
+ . = ALIGN (4);
+ __ddr_load = LOADADDR (.ram_code);
+ __ddr_start = .;
+ *(.ddr_codetext) /* .ram_codetext sections (code) */
+ *(.ddr_codetext*) /* .ram_codetext* sections (code) */
+ *(.ddr_coderodata) /* read-only data (constants) */
+ *(.ddr_coderodata*)
+ . = ALIGN (4);
+ __ddr_end = .;
+ } >ddr_cached_32bit AT>envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set
+ point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing.
+ Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim AT > envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim AT > envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary (0x1000) - corresponds to page size, when using
+ memory mem */
+ /* protection */
+ /* .stack : ALIGN(0x1000) */
+ .stack : ALIGN(0x10)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ /* place __start_of_free_lim$ after last allocation of l2_lim */
+ . = ALIGN(0x10);
+ PROVIDE(__start_of_free_lim$ = .);
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..98a7dace
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld
@@ -0,0 +1,388 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ * Code starts from LIM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * The startup stack size is used on start-up.
+ * The application stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __l2lim_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >l2lim
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> l2lim
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>envm */
+
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld
new file mode 100644
index 00000000..fd4ed76a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_lim.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+/* STACK_SIZE_PER_HART = 8k; */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+ /* text: text code section */
+ . = __l2lim_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ . = ALIGN(0x10);
+ } > l2lim
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ . = ALIGN (0x10);
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> l2lim
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including eNVM clock.
+ * This can not be done when running from eNVM
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>eNVM */
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h
new file mode 100644
index 00000000..fdf65956
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * Platform definitions
+ * Version based on requirements of MPFS MSS
+ *
+ */
+ /*========================================================================*//**
+ @mainpage Sample file detailing how mss_sw_config.h should be constructed for
+ the MPFS MSS
+
+ @section intro_sec Introduction
+ The mss_sw_config.h has the default software configuration settings for the
+ MPFS HAL and will be located at
+ /src/platform/platform_config_reference folder of the bare
+ metal SoftConsole project. The platform_config_reference is provided as a
+ default reference configuration.
+ When you want to configure the MPFS HAL with required configuration for
+ your project, the mss_sw_config.h must be edited and be placed in the
+ following project directory:
+ /src/boards//platform_config/mpfs_hal_config/
+
+ @section
+
+*//*==========================================================================*/
+
+
+#ifndef MSS_SW_CONFIG_H_
+#define MSS_SW_CONFIG_H_
+
+/*
+ * MPFS_HAL_FIRST_HART and MPFS_HAL_LAST_HART defines are used to specify which
+ * harts to actually start. The value and the actual hart it represents are
+ * listed below:
+ * value hart
+ * 0 E51
+ * 1 U54_1
+ * 2 U54_2
+ * 3 U54_3
+ * 4 U54_4
+ * Set MPFS_HAL_FIRST_HART to a value greater than 0 if you do not want your
+ * application to start and execute code on the harts represented by smaller
+ * value numbers.
+ * Set MPFS_HAL_LAST_HART to a value smaller than 4 if you do not wish to use
+ * all U54_x harts.
+ * Harts that are not started will remain in an infinite WFI loop unless used
+ * through some other method.
+ * The value of MPFS_HAL_FIRST_HART must always be less than MPFS_HAL_LAST_HART.
+ * The value of MPFS_HAL_LAST_HART must never be greater than 4.
+ * A typical use-case where you set MPFS_HAL_FIRST_HART = 1 and
+ * MPFS_HAL_LAST_HART = 1 is when
+ * your application is running on U54_1 and a bootloader running on E51 loads
+ * your application to the target memory and kicks-off U54_1 to run it.
+ */
+#ifndef MPFS_HAL_FIRST_HART
+#define MPFS_HAL_FIRST_HART 1
+#endif
+
+#ifndef MPFS_HAL_LAST_HART
+#define MPFS_HAL_LAST_HART 1
+#endif
+
+/*
+ * IMAGE_LOADED_BY_BOOTLOADER
+ * We set IMAGE_LOADED_BY_BOOTLOADER = 0 if the application image runs from
+ * non-volatile memory after reset. (No previous stage bootloader is used.)
+ * Set IMAGE_LOADED_BY_BOOTLOADER = 1 if the application image is loaded by a
+ * previous stage bootloader.
+ *
+ * MPFS_HAL_HW_CONFIG is defined if we are a boot-loader. This is a
+ * conditional compile switch is used to determine if MPFS HAL will perform the
+ * hardware configurations or not.
+ * Defined => This program acts as a First stage bootloader and performs
+ * hardware configurations.
+ * Not defined => This program assumes that the hardware configurations are
+ * already performed (Typically by a previous boot stage)
+ *
+ * List of items initialised when MPFS_HAL_HW_CONFIG is enabled
+ * - load virtual rom (see load_virtual_rom(void) in system_startup.c)
+ * - l2 cache config
+ * - Bus error unit config
+ * - MPU config
+ * - pmp config
+ * - I/O, clock and clock mux's, DDR and SGMII
+ * - will start other harts, see text describing MPFS_HAL_FIRST_HART,
+ * MPFS_HAL_LAST_HART above
+ *
+ */
+#define IMAGE_LOADED_BY_BOOTLOADER 1
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+#define MPFS_HAL_HW_CONFIG
+#endif
+
+
+/*
+ * If you are using common memory for sharing across harts,
+ * uncomment #define MPFS_HAL_SHARED_MEM_ENABLED
+ * make sure common memory is allocated in the linker script
+ * See app_hart_common mem section in the example platform
+ * linker scripts.
+ */
+
+#define MPFS_HAL_SHARED_MEM_ENABLED
+
+
+/* define the required tick rate in Milliseconds */
+/* if this program is running on one hart only, only that particular hart value
+ * will be used */
+#define HART0_TICK_RATE_MS 5UL
+#define HART1_TICK_RATE_MS 5UL
+#define HART2_TICK_RATE_MS 5UL
+#define HART3_TICK_RATE_MS 5UL
+#define HART4_TICK_RATE_MS 5UL
+
+/*
+ * Define the size of the Hart Local Storage (HLS).
+ * In the MPFS HAL, we are using HLS for debug data storage during the initial
+ * boot phase.
+ * This includes the flags which indicate the hart state regarding boot state.
+ * The HLS will take memory from top of each stack allocated at boot time.
+ *
+ */
+#define HLS_DEBUG_AREA_SIZE 64
+
+/*
+ * Bus Error Unit (BEU) configurations
+ * BEU_ENABLE => Configures the events that the BEU can report. bit value
+ * 1= enabled, 0 = disabled.
+ * BEU_PLIC_INT => Configures which accrued events should generate an
+ * interrupt to the PLIC.
+ * BEU_LOCAL_INT => Configures which accrued events should generate a
+ * local interrupt to the hart on which the event accrued.
+ */
+#define BEU_ENABLE 0x0ULL
+#define BEU_PLIC_INT 0x0ULL
+#define BEU_LOCAL_INT 0x0ULL
+
+/*
+ * Clear memory on startup
+ * 0 => do not clear DTIM and L2
+ * 1 => Clears memory
+ * Note: If you are the zero stage bootloader, set this to one.
+ */
+#ifndef MPFS_HAL_CLEAR_MEMORY
+#define MPFS_HAL_CLEAR_MEMORY 1
+#endif
+
+/*
+ * Comment out the lines to disable the corresponding hardware support not required
+ * in your application.
+ * This is not necessary from an operational point of view as operation dictated
+ * by MSS configurator settings, and items are enabled/disabled by this method.
+ * The reason you may want to use below is to save code space.
+ */
+#define SGMII_SUPPORT
+#define DDR_SUPPORT
+#define MSSIO_SUPPORT
+
+/*
+ * DDR software options
+ */
+
+/*
+ * Debug DDR startup through a UART
+ * Comment out in normal operation. May be useful for debug purposes in bring-up
+ * of a new board design.
+ * See the weakly linked function setup_ddr_debug_port(mss_uart_instance_t * uart)
+ * If you need to edit this function, make another copy of the function in your
+ * application without the weak linking attribute. This copy will then get linked.
+ * */
+//#define DEBUG_DDR_INIT
+//#define DEBUG_DDR_RD_RW_FAIL
+//#define DEBUG_DDR_RD_RW_PASS
+//#define DEBUG_DDR_CFG_DDR_SGMII_PHY
+//#define DEBUG_DDR_DDRCFG
+
+
+/*
+ * The hardware configuration settings imported from Libero project get generated
+ * into /src/boards// folder.
+ * If you need to overwrite them for testing purposes, you can do so here.
+ * e.g. If you want change the default SEG registers configuration defined by
+ * LIBERO_SETTING_SEG0_0, define it here and it will take precedence.
+ * #define LIBERO_SETTING_SEG0_0 0x80007F80UL
+ *
+ */
+
+#endif /* USER_CONFIG_MSS_USER_CONFIG_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt
new file mode 100644
index 00000000..086c9f12
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt
@@ -0,0 +1,2 @@
+contains user configuration of the platform
+e.g. division of memory between harts etc.
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/middleware/config/readme.txt b/driver-examples/mss-can/mpfs-can-external-loopback/src/middleware/config/readme.txt
new file mode 100644
index 00000000..95f6cb21
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/middleware/config/readme.txt
@@ -0,0 +1 @@
+contains files relating to configuration of third party modules
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/middleware/readme.txt b/driver-examples/mss-can/mpfs-can-external-loopback/src/middleware/readme.txt
new file mode 100644
index 00000000..0ffaed97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/middleware/readme.txt
@@ -0,0 +1 @@
+contains files relating to third party modules
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_can/mss_can.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_can/mss_can.c
new file mode 100644
index 00000000..fb59df0a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_can/mss_can.c
@@ -0,0 +1,1049 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * PolarFire SoC Microprocessor Subsystem(MSS) CAN bare metal software driver
+ * implementation.
+ */
+
+
+/*******************************************************************************
+ * Include files
+ */
+#include "mpfs_hal/mss_hal.h"
+#include "mss_can.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * Macros
+ */
+#define CAN_ID_SHIFT 18u
+#define CAN_ERROR_STATUS_SHIFT 16u
+#define CAN_ERROR_STATUS_MASK 0x03u
+#define CAN_RX_GTE96_SHIFT 19u
+#define CAN_FLAG_MASK 0x01u
+#define CAN_ERROR_COUNT_SHIFT 8u
+#define CAN_ERROR_COUNT_MASK 0xFFu
+#define CAN_TXGTE96_SHIFT 18u
+#define CAN_INT_MASK 0xFFFFFFFCu
+#define ENABLE 1u
+#define DISABLE 0u
+#define SYSREG_CAN_SOFTRESET_MASK (uint32_t)(3 << 14u)
+
+/*******************************************************************************
+ * Instance definition
+ */
+mss_can_instance_t g_mss_can_0_lo;
+mss_can_instance_t g_mss_can_1_lo;
+mss_can_instance_t g_mss_can_0_hi;
+mss_can_instance_t g_mss_can_1_hi;
+
+static void global_init
+(
+ mss_can_instance_t* this_wd
+);
+
+/***************************************************************************//**
+ * MSS_CAN_init()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_init
+(
+ mss_can_instance_t* this_can,
+ uint32_t bitrate,
+ pmss_can_config_reg pcan_config,
+ uint8_t basic_can_rx_mb,
+ uint8_t basic_can_tx_mb
+)
+{
+ uint32_t temp;
+ uint8_t mailbox_number;
+ uint8_t ret_value;
+ mss_can_rxmsgobject canrxobj;
+
+ global_init(this_can);
+
+ /* Initialize the device structure */
+ this_can->basic_can_rx_mb = basic_can_rx_mb;
+ this_can->basic_can_tx_mb = basic_can_tx_mb;
+
+ /* Initialize the rx mailbox */
+ canrxobj.ID = 0u;
+ canrxobj.DATAHIGH = 0u;
+ canrxobj.DATALOW = 0u;
+ canrxobj.AMR.L = 0u;
+ canrxobj.ACR.L = 0u;
+ canrxobj.AMR_D = 0u;
+ canrxobj.ACR_D = 0u;
+ canrxobj.RXB.L = (0u | CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL);
+
+ for (mailbox_number = 0u; mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ ret_value = MSS_CAN_config_buffer_n(this_can, mailbox_number,
+ &canrxobj);
+ }
+
+ /* Configure CAN controller */
+ if (CAN_SPEED_MANUAL == bitrate)
+ {
+ /*
+ * If user wants to specify registers directly Check if parameters
+ * meet minimums.
+ */
+ if (pcan_config->CFG_TSEG1 < 2u)
+ {
+ return (CAN_TSEG1_TOO_SMALL );
+ }
+
+ if ((pcan_config->CFG_TSEG2 == 0u) ||
+ ((pcan_config->SAMPLING_MODE == 1u) && (pcan_config->CFG_TSEG2
+ == 1u)))
+ {
+ return (CAN_TSEG2_TOO_SMALL);
+ }
+ temp = pcan_config->CFG_SJW;
+ if ((temp > pcan_config->CFG_TSEG1) ||
+ (temp > pcan_config->CFG_TSEG2))
+ {
+ return (CAN_SJW_TOO_BIG);
+ }
+
+ this_can->hw_reg->Config.L = pcan_config->L;
+ }
+ else
+ {
+ /* User has chosen a default setting. */
+ this_can->hw_reg->Config.L = bitrate;
+ }
+
+ /* Disable Interrupts */
+ this_can->hw_reg->IntEbl.L = DISABLE;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_config_reg()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_config_reg
+(
+ mss_can_instance_t* this_can,
+ uint32_t cfg
+)
+{
+ /* Clear all pending interrupts */
+ this_can->hw_reg->IntStatus.L = DISABLE;
+
+ /* Disable CAN Device */
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+
+ /* Disable receive interrupts. */
+ this_can->hw_reg->IntEbl.RX_MSG = DISABLE;
+
+ /* Disable interrupts from CAN device. */
+ this_can->hw_reg->IntEbl.INT_EBL = DISABLE;
+
+ /* Sets configuration bits */
+ this_can->hw_reg->Config.L = cfg;
+ MSS_CAN_start(this_can);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_mode()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_mode
+(
+ mss_can_instance_t* this_can,
+ mss_can_mode_t mode
+)
+{
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+ if (CANOP_SW_RESET == mode)
+ {
+ SYSREG->SOFT_RESET_CR |= SYSREG_CAN_SOFTRESET_MASK;
+ SYSREG->SOFT_RESET_CR &= ~SYSREG_CAN_SOFTRESET_MASK;
+ }
+ else
+ {
+ this_can->hw_reg->Command.L = (uint32_t)mode;
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_start()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_start
+(
+ mss_can_instance_t* this_can
+)
+{
+ /* Clear all pending interrupts*/
+ this_can->hw_reg->IntStatus.L = DISABLE;
+
+ /* Enable CAN Device*/
+ this_can->hw_reg->Command.RUN_STOP = ENABLE;
+
+ /* Enable CAN Interrupt at NVIC level- if supported */
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ if (if (&g_mss_can_0_lo == this_can) || (&g_mss_can_0_hi == this_can))
+ {
+ PLIC_DisableIRQ(CAN0_PLIC);
+ }
+ else
+ {
+ PLIC_DisableIRQ(CAN1_PLIC);
+ }
+#endif
+
+ /* Enable receive interrupts. */
+ this_can->hw_reg->IntEbl.RX_MSG = ENABLE;
+
+ /* Enable interrupts from CAN device.*/
+ this_can->hw_reg->IntEbl.INT_EBL = ENABLE;
+
+}
+
+/***************************************************************************//**
+ * MSS_CAN_stop()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_stop
+(
+ mss_can_instance_t* this_can
+)
+{
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_id()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_id
+(
+ pmss_can_msgobject pmsg
+)
+{
+ if (pmsg->IDE)
+ {
+ return (pmsg->ID);
+ }
+ else
+ {
+ return (pmsg->ID >> CAN_ID_SHIFT);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_id()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_set_id
+(
+ pmss_can_msgobject pmsg
+)
+{
+ if (pmsg->IDE)
+ {
+ return (pmsg->ID);
+ }
+ else
+ {
+ return (pmsg->ID << CAN_ID_SHIFT);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_msg_filter_mask()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_msg_filter_mask
+(
+ uint32_t id,
+ uint8_t ide,
+ uint8_t rtr
+)
+{
+ if (ide)
+ {
+ id <<= 3u;
+ }
+ else
+ {
+ id <<= 21;
+
+ /* Set unused ID bits to 1! */
+ id |= (0x3FFFF << 3u);
+ }
+ id |= ((uint32_t)(ide << 2u) | (uint32_t)(rtr << 1u));
+
+ return (id);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntEbl.L |= irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_clear_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_clear_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntEbl.L &= ~irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_global_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_global_int_ebl
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntEbl.INT_EBL);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_int_ebl
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntEbl.L & CAN_INT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_clear_int_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_clear_int_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntStatus.L = irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_int_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_int_status
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntStatus.L);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_rtr_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_set_rtr_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Is buffer configured for RTR auto-replay? */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRREPLY == 0u)
+ {
+ return (CAN_NO_RTR_MAILBOX);
+ }
+ else
+ {
+ /* Transfer the ID. */
+ this_can->hw_reg->RxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->RxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ return (CAN_OK);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rtr_message_abort_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_rtr_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ /* Mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Set abort request */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRABORT = 1u;
+
+ /* Check the abort is granted */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRREPLYPEND == 0u)
+ {
+ /* If the RX buffer isn't busy. Abort was successful */
+ return (CAN_OK);
+ }
+ else
+ {
+ /* Message not aborted.*/
+ return (CAN_ERR);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_config_buffer()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_config_buffer
+(
+ mss_can_instance_t* this_can,
+ pmss_can_filterobject pfilter
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX - this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Set filters */
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = pfilter->ACR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = pfilter->AMR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = pfilter->AMCR_D.MASK;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = pfilter->AMCR_D.CODE;
+
+ /* Configure mailbox */
+ if (mailbox_number < (CAN_RX_MAILBOX - 1))
+ {
+ /* set link flag, if not last buffer */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L =
+ (CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL | \
+ CAN_RX_LINK_EBL);
+ }
+ else
+ {
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L =
+ (CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL);
+ }
+ success = CAN_OK;
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_config_buffer_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_config_buffer_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_rxmsgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Configure mailbox */
+ this_can->hw_reg->RxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->RxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = pmsg->ACR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = pmsg->AMR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = pmsg->AMR_D;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = pmsg->ACR_D;
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L = (pmsg->RXB.L | \
+ CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL);
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Check that a new message is available and get it */
+ if ((ENABLE == this_can->hw_reg->Command.RUN_STOP) &&
+ (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV))
+ {
+ /* Copy ID */
+ pmsg->ID = this_can->hw_reg->RxMsg[mailbox_number].ID;
+
+ /* Copy 4 of the data bytes */
+ pmsg->DATALOW = this_can->hw_reg->RxMsg[mailbox_number].DATALOW;
+
+ /* Copy the other 4 data bytes. */
+ pmsg->DATAHIGH = this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH;
+
+ /* Get DLC, IDE and RTR and time stamp. */
+ pmsg->L = this_can->hw_reg->RxMsg[mailbox_number].RXB.L;
+
+ /* Ack that it's been removed from the FIFO */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV = ENABLE;
+
+ /* And let app know there is a message. */
+ return (CAN_VALID_MSG);
+ }
+ else
+ {
+ return (CAN_NO_MSG);
+ }
+}
+
+/*******************************************************************************
+ * MSS_CAN_get_message()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX-this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Check that if there is a valid message */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV)
+ {
+ /* Copy ID */
+ pmsg->ID = this_can->hw_reg->RxMsg[mailbox_number].ID;
+
+ /* Copy 4 of the data bytes */
+ pmsg->DATALOW = this_can->hw_reg->RxMsg[mailbox_number].DATALOW;
+
+ /* Copy the other 4 data bytes.*/
+ pmsg->DATAHIGH = this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH;
+
+ /* Get DLC, IDE and RTR and time stamp.*/
+ pmsg->L = this_can->hw_reg->RxMsg[mailbox_number].RXB.L;
+
+ /* Ack that it's been removed from the FIFO */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV = ENABLE;
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_message_av()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message_av
+(
+ mss_can_instance_t* this_can
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX-this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Check that buffer is enabled and contains a message */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV)
+ {
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Can't send if device is disabled */
+ if (DISABLE == this_can->hw_reg->Command.RUN_STOP)
+ {
+ /* Message not sent. */
+ return (CAN_NO_MSG);
+ }
+
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_TX_MAILBOX - this_can->basic_can_tx_mb))
+ {
+ /* mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXREQ == 0u)
+ {
+ /* If the Tx buffer isn't busy.... */
+ this_can->hw_reg->TxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->TxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->TxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L = (pmsg->L | \
+ CAN_TX_WPNH_EBL | \
+ CAN_TX_REQ);
+ return (CAN_VALID_MSG);
+ }
+ else
+ {
+ /* Message not sent. */
+ return (CAN_NO_MSG);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_abort_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_TX_MAILBOX - this_can->basic_can_tx_mb))
+ {
+ /* mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Set abort request */
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L =
+ ((this_can->hw_reg->TxMsg[mailbox_number].TXB.L & ~CAN_TX_REQ) | \
+ CAN_TX_ABORT);
+
+ /* Check the abort is granted */
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXABORT == 0u)
+ {
+ /* If the Tx buffer isn't busy, Abort was successful */
+ return (CAN_OK);
+ }
+ else
+ {
+ /* Message not aborted. */
+ return (CAN_ERR);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_ready()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_ready
+(
+ mss_can_instance_t* this_can
+)
+{
+ uint8_t success = CAN_ERR;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_tx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that is available */
+ for (mailbox_number = CAN_TX_MAILBOX-this_can->basic_can_tx_mb; \
+ mailbox_number < CAN_TX_MAILBOX; mailbox_number++)
+ {
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXREQ == 0u)
+ {
+ /* Tx buffer isn't busy */
+ success = CAN_OK;
+ break;
+ }
+ }
+
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_tx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that is available */
+ for (mailbox_number = CAN_TX_MAILBOX-this_can->basic_can_tx_mb; \
+ mailbox_number < CAN_TX_MAILBOX; mailbox_number++)
+ {
+ /* Check which transmit mailbox is not busy and use it. */
+ if ((MSS_CAN_get_tx_buffer_status(this_can) & (1u << mailbox_number))
+ == 0)
+ {
+ /* If the Tx buffer isn't busy.... */
+ this_can->hw_reg->TxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->TxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->TxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L = (pmsg->L | \
+ CAN_TX_WPNH_EBL | \
+ CAN_TX_REQ);
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_mask_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t *pamr,
+ uint32_t *pacr,
+ uint16_t *pdta_amr,
+ uint16_t *pdta_acr
+)
+{
+ if (mailbox_number >= CAN_RX_MAILBOX)
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ *pamr = this_can->hw_reg->RxMsg[mailbox_number].AMR.L;
+ *pacr = this_can->hw_reg->RxMsg[mailbox_number].ACR.L;
+ *pdta_acr = this_can->hw_reg->RxMsg[mailbox_number].ACR_D;
+ *pdta_amr = this_can->hw_reg->RxMsg[mailbox_number].AMR_D;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_mask_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_set_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t amr,
+ uint32_t acr,
+ uint16_t dta_amr,
+ uint16_t dta_acr
+)
+{
+ if (mailbox_number >= CAN_RX_MAILBOX)
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = amr;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = acr;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = (uint32_t)dta_amr;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = (uint32_t)dta_acr;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_buffer_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_buffer_status
+(
+ mss_can_instance_t* this_can
+)
+{
+#ifdef CANMOD3
+ return (this_can->hw_reg->BufferStatus.L & 0x0000FFFF);
+#else
+ return (this_can->hw_reg->BufferStatus.RXMSGAV);
+#endif
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_buffer_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_buffer_status
+(
+ mss_can_instance_t* this_can
+)
+{
+#ifdef CANMOD3
+ return ((this_can->hw_reg->BufferStatus.L >> 16u) & 0x00FF);
+#else
+ return (this_can->hw_reg->BufferStatus.TXREQ);
+#endif
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_error_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_error_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t *status
+)
+{
+ /* Supply error register info if user wants. */
+ *status = this_can->hw_reg->ErrorStatus.L;
+
+ /* 00 Error Active, 01 Error Passive, 1x Bus Off */
+ return ((uint8_t)(((*status) >> CAN_ERROR_STATUS_SHIFT) &
+ CAN_ERROR_STATUS_MASK));
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_error_count()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_error_count
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_ERROR_COUNT_SHIFT) & \
+ CAN_ERROR_COUNT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_gte96()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_gte96
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_RX_GTE96_SHIFT) & \
+ CAN_FLAG_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_error_count()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_error_count
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->ErrorStatus.L & CAN_ERROR_COUNT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_gte96 ()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_gte96
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_TXGTE96_SHIFT) & \
+ CAN_FLAG_MASK);
+}
+
+/*******************************************************************************
+ * Global initialization for all modes
+ */
+static void global_init
+(
+ mss_can_instance_t* this_wd
+)
+{
+ if (&g_mss_can_0_lo == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_0_LO_BASE;
+ this_wd->irqn = CAN0_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_1_lo == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_1_LO_BASE;
+ this_wd->irqn = CAN1_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_0_hi == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_0_HI_BASE;
+ this_wd->irqn = CAN0_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_1_hi == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_1_HI_BASE;
+ this_wd->irqn = CAN1_PLIC;
+ this_wd->int_type = 0;
+ }
+ else
+ {
+ ;/* LDRA Warning */
+ }
+}
+
+#ifndef MSS_CAN_USER_ISR
+/***************************************************************************//**
+ * CAN interrupt service routine.
+ * CAN_IRQHandler is included within the RISC-V vector table as part of the
+ * MPFS HAL.
+ */
+uint8_t External_can0_plic_IRQHandler(void)
+{
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ /* User provided code is required here to handle interrupts from the MSS CAN
+ * peripheral. Remove the assert once this is in place.*/
+ ASSERT(!"An ISR is required here if interrupts are enabled");
+#else
+ ASSERT(!"Unexpected MSS CAN interrupt - MSS CAN NVIC Interrupts should be \
+ disabled");
+#endif
+ return 0;
+}
+
+uint8_t can1_IRQHandler(void)
+{
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ /* User provided code is required here to handle interrupts from the MSS CAN
+ * peripheral. Remove the assert once this is in place.*/
+ ASSERT(!"An ISR is required here if interrupts are enabled");
+#else
+ ASSERT(!"Unexpected MSS CAN interrupt - MSS CAN NVIC Interrupts should be \
+ disabled");
+#endif
+ return 0;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_can/mss_can.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_can/mss_can.h
new file mode 100644
index 00000000..d4153c32
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_can/mss_can.h
@@ -0,0 +1,2430 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * PolarFire SoC Microprocessor Subsystem(MSS) CAN bare metal software driver
+ * public API.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire SoC MSS CAN Bare Metal Driver.
+
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor Subsystem (MSS) includes two CAN controller.
+ The CAN controller is configurable to provide support for up to 32 transmit
+ and 32 receive mailboxes.
+
+ This PolarFire SoC MSS CAN driver provides a set of functions for accessing
+ and controlling the MSS CAN as part of a bare metal system where no operating
+ system is available. The driver can be adapted for use as part of an
+ operating system, but the implementation of the adaptation layer between the
+ driver and the operating system's driver model is outside the scope of the
+ driver.
+
+ --------------------------------
+ Features
+ --------------------------------
+ The MSS CAN driver provides support for the following features:
+ - Basic CAN APIs if application needs support for Basic CAN operation.
+ (Configure as FIFO by linking several mailboxes together, one message
+ filter for entire FIFO)
+ - Full CAN APIs (each mail box has its own message filter)
+ - Support for 11 bit and 29 bit message identifiers
+ - Support for Data frame and Remote frames
+ - Error detection mechanism
+
+ ==============================================================================
+ Hardware Flow Dependencies
+ ==============================================================================
+ The configuration of all features of the PolarFire MSS CAN is covered by
+ this driver, with the exception of the PolarFire SoC IOMUX configuration.
+ The PolarFire SoC allows multiple non-concurrent uses of few external pins
+ through IOMUX configuration. This feature allows optimization of external pin
+ usage by assigning external pins for use by either the microprocessor
+ subsystem or the FPGA fabric. The MSS CAN serial signals are routed through
+ IOMUXs to the PolarFire SoC device external pins. The MSS CAN serial
+ signals can also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
+ For more information on IOMUX, refer to the I/O Configuration section of the
+ PolarFire SoC Microprocessor Subsystem (MSS) User's Guide.
+
+ The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
+ must ensure that the MSS CAN peripherals are enabled and configured in the
+ PolarFire SoC MSS configurator if you wish to use them. For more information
+ on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
+ Subsystem (MSS) User's Guide.
+
+ On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
+ masters and multiple slaves. Five RISC-V CPUs connect to the Master ports M10
+ to M14 of the AXI switch. By default, all the APB peripherals are accessible
+ on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB bridges
+ (referred as main APB bus). However, to support logical separation in the
+ Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals can
+ alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to APB
+ bridges (referred as the AMP APB bus).
+ Application must make sure that the desired CAN instance is appropriately
+ configured on one of the APB bus described above by configuring the PolarFire
+ SoC system registers (SYSREG) as per the application need and that the
+ appropriate data structures are provided to this driver as parameter to the
+ functions provided by this driver.
+
+ The base address and the register addresses are defined in this driver as
+ constants. The interrupt number assignment for the MSS CAN peripherals is
+ defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
+ is included in the project settings of the SoftConsole toolchain and that it
+ is generated into your project.
+
+ ==============================================================================
+ Theory of Operation
+ ==============================================================================
+ The MSS CAN driver uses one instance of the mss_can_instance_t structure per
+ port. This instance is used to identify the target port and a pointer to this
+ instance is passed as the first argument to all CAN driver functions.
+
+ The PolarFire SoC MSS CAN driver operations can be divided in following
+ sub-sections:
+ - CAN Controller Configuration
+ - Operation Status
+ - Interrupt Support
+ - Helper Functions
+ - Basic CAN Message Handling
+ - Full CAN Message Handling
+
+ --------------------------------
+ Configuration
+ --------------------------------
+ The MSS CAN driver must first be initialized and the mode of operation must
+ be selected before performing data transfers on CAN Bus. The MSS_CAN_init()
+ function is used to initialize the CAN controller and driver. Set CAN
+ controller operation mode as normal operation using MSS_CAN_set_mode()
+ function. The operating mode of operation is selected using
+ MSS_CAN_set_mode() function. The actual data transfer can be started using
+ start the CAN controller by using MSS_CAN_start() function, with this actual
+ data transmission or reception shall start. MSS_CAN_stop() function is used
+ to stops the CAN controller. Once initialized, during normal mode of
+ operation, the MSS CAN driver configuration can be changed using
+ MSS_CAN_set_config_reg() function is used to change the CAN controllers
+ configuration during normal operation.
+
+ --------------------------------
+ Operation Status
+ --------------------------------
+ MSS_CAN_get_error_status() function returns the current CAN error state
+ (error active, error passive, and bus off). The MSS_CAN_get_rx_error_count()
+ and MSS_CAN_get_tx_error_count() functions return the actual
+ receive and transmit error counter values while MSS_CAN_get_rx_gte96()
+ function and MSS_CAN_get_tx_gte96() function show if the error counters are
+ greater or equal to 96, which indicates a heavily disturbed bus.
+
+ --------------------------------
+ Interrupt Support
+ --------------------------------
+ The interrupt service routines are not part of the CAN driver. But access
+ functions for the interrupt registers are provided. The individual
+ interrupt enable bits can be set using MSS_CAN_set_int_ebl() function and
+ individual interrupt enable bits can be cleared using MSS_CAN_clear_int_ebl
+ while MSS_CAN_get_int_ebl() function returns their actual state.
+ MSS_CAN_get_global_int_ebl() function indicates if interrupt
+ generation is enabled at all. MSS_CAN_get_int_status() function shows the
+ current state of the different interrupt status bits. Each interrupt status
+ bit can be individually cleared using MSS_CAN_clear_int_status() function.
+
+ The interrupt service routines are not part of the MSS CAN driver and the
+ driver ships with the MSS_CAN_ENABLE_INTERRUPTS macro disabled which stops
+ the MSS CAN interrupt being enabled at the PLIC, however a stub ISR is
+ present in the mss_can.c file to show the format of the function and catch
+ any unexpected interrupts to aid in debugging.
+
+ --------------------------------
+ Helper Functions
+ --------------------------------
+ The MSS CAN peripheral expects all ID bits to be left aligned. This makes
+ setting the ID cumbersome. Using MSS_CAN_set_id(), a given right-aligned
+ ID field is modified according to the ID size which is indicated by the
+ IDE bit. MSS_CAN_get_id() provides the reverse operation: It returns the
+ ID right aligned. MSS_CAN_get_msg_filter_mask() packs the ID, IDE, and RTR
+ bits together as they are used in the mask registers. MSS_CAN_get_mask_n()
+ returns the message filter settings of the selected receive mailbox.
+ MSS_CAN_set_mask_n() configures the message filter settings for the
+ selected receive mailbox.
+
+ --------------------------------
+ Basic CAN Message Handling
+ --------------------------------
+ A Basic CAN type controller contains one or more message filter and one
+ common message buffer or FIFO. The CAN driver contains some functions to
+ emulate Basic CAN operation by linking several buffers together to form a
+ buffer array that shares one message filter. Since this buffer array is not
+ a real FIFO, message inversion might happen (eg, a newer message might be
+ pulled from the receive buffer prior to an older message).
+ Before using the Basic CAN API, the CAN controller has to be configured
+ first with a MSS_CAN_config_buffer() function call. This sets up the
+ message array and configures the message filter. MSS_CAN_send_message()
+ function and MSS_CAN_get_message() function are used to send and receive
+ a message from transmit or receive buffers. MSS_CAN_send_message_ready()
+ function indicates if a new message can be sent. MSS_CAN_get_message_av()
+ function shows if a new message is available.
+
+ --------------------------------
+ Full CAN Message Handling
+ --------------------------------
+ In Full CAN operation, each message mailbox has its own message filter.
+ This reduces the number of receive interrupts as the host CPU only gets an
+ interrupt when a message of interest has arrived. Further, software based
+ message filtering overhead is reduced and there is less message to
+ be checked. Before a buffer can be used for Full CAN operation, it needs to
+ be configured using MSS_CAN_config_buffer_n() function. An error is
+ generated if this buffer is already reserved for Basic CAN operation.
+ The MSS_CAN_get_rx_buffer_status() and MSS_CAN_get_tx_buffer_status()
+ functions indicate the current state of the receive and transmit buffers
+ respectively. With MSS_CAN_send_message_n() function a message can be sent
+ using buffer. A pending message transfer can be aborted with
+ MSS_CAN_send_message_abort_n() function and a message can be read with
+ MSS_CAN_get_message_n() function. If a buffer is set for automatic RTR reply,
+ MSS_CAN_set_rtr_message_n() function sets the CAN message that is returned
+ upon reception of the RTR message. MSS_CAN_get_rtr_message_abort_n()
+ function aborts a RTR message transmit request.
+
+ NOTE:
+ 1. User has to set the RTR message filter to match with
+ MSS_CAN_rtr_message_abort_n() function a pending RTR auto-reply can be
+ aborted.
+ 2. An error is generated if buffer is already reserved for Basic CAN
+ operation and is trying to use the same buffer for Full CAN functionality.
+ 3. Special case of Full CAN where several mailboxes are linked together to
+ create FIFOs that share an identical message filter configuration, can
+ be built upon the available Full CAN functions.
+
+ *//*=========================================================================*/
+
+#ifndef MSS_CAN_H_
+#define MSS_CAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following macro MSS_CAN_ENABLE_INTERRUPTS must be defined to allow the
+ * enabling of the MSS CAN peripheral interrupts at the PLIC level.
+ * This version of the MSS CAN driver does not provide any support for MSS CAN
+ * interrupts and so this MACRO should be disabled unless there is a user
+ * supplied ISR.
+ */
+
+#if 0
+#define MSS_CAN_ENABLE_INTERRUPTS
+#endif
+
+/**
+ * Define CAN target device
+ *
+ * CANMOD3: Device with 16 Rx and 8 Tx mailboxes
+ * CANMOD3X: Device with 32 Rx and 32 Tx mailboxes
+ */
+
+#define CANMOD3X
+
+#ifdef CANMOD3
+ #define CAN_RX_MAILBOX 16u
+ #define CAN_TX_MAILBOX 8u
+#else
+ #define CAN_RX_MAILBOX 32u
+ #define CAN_TX_MAILBOX 32u
+#endif
+
+
+/* Configuration and Speed definitions */
+#define CAN_PRESET (mss_can_config_reg.L)0
+#define CAN_SAMPLE_BOTH_EDGES 0x00000001u
+#define CAN_THREE_SAMPLES 0x00000002u
+#define CAN_SET_SJW(_sjw) (_sjw<<2u)
+#define CAN_AUTO_RESTART 0x00000010u
+#define CAN_SET_TSEG2(_tseg2) (_tseg2<<5u)
+#define CAN_SET_TSEG1(_tseg1) (_tseg1<<8u)
+#define CAN_SET_BITRATE(_bitrate) (_bitrate<<16u)
+#define CAN_ARB_ROUNDROBIN 0x00000000u
+#define CAN_ARB_FIXED_PRIO 0x00001000u
+#define CAN_BIG_ENDIAN 0x00000000u
+#define CAN_LITTLE_ENDIAN 0x00002000u
+
+/* Manual setting with specified fields */
+#define CAN_SPEED_MANUAL 0u
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used in the PolarFire SoC MSS CAN driver for
+ bitrate definitions:
+
+ | Constants | Description |
+ |--------------------|-----------------------------------------------------|
+ | CAN_SPEED_8M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 32MHz. |
+ | AN_SPEED_8M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 32MHz. |
+
+ */
+/* 5000m 81% Sample bit three times */
+#define CAN_SPEED_8M_5K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_5K CAN_SET_BITRATE(199)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_5K CAN_SET_BITRATE(399)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 5000m 81% Sample bit three times */
+#define CAN_SPEED_8M_10K CAN_SET_BITRATE(49)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_10K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_10K CAN_SET_BITRATE(199)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 2500m 81% Sample bit three times */
+#define CAN_SPEED_8M_20K CAN_SET_BITRATE(24)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_20K CAN_SET_BITRATE(49)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_20K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 1000m 87% */
+#define CAN_SPEED_8M_50K CAN_SET_BITRATE(9)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_50K CAN_SET_BITRATE(19)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_50K CAN_SET_BITRATE(39)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 600m 87% */
+#define CAN_SPEED_8M_100K CAN_SET_BITRATE(4)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_100K CAN_SET_BITRATE(9)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_100K CAN_SET_BITRATE(19)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 500m 87% */
+#define CAN_SPEED_8M_125K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_125K CAN_SET_BITRATE(7)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_125K CAN_SET_BITRATE(15)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 250m 87% */
+#define CAN_SPEED_8M_250K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_250K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_250K CAN_SET_BITRATE(7)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 100m 75% @ 8M, 87% @ 16M */
+#define CAN_SPEED_8M_500K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_500K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_500K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 25m 75% */
+#define CAN_SPEED_8M_1M CAN_SET_BITRATE(0)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_1M CAN_SET_BITRATE(1)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_1M CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_ERR | Indicates error condition |
+ | CAN_TSEG1_TOO_SMALL | Value provided to configure TSEG1 is too |
+ | | small |
+ | CAN_TSEG2_TOO_SMALL | Value provided to configure TSEG2 is too |
+ | | small |
+ | CAN_SJW_TOO_BIG | Value provided to configure synchronous jump|
+ | | width (SJW) is too big. |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+ | CAN_NO_RTR_MAILBOX | Indicates that there is no mailbox for |
+ | | remote transmit request (RTR) frame |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ */
+#define CAN_OK 0u
+#define CAN_ERR 1u
+#define CAN_TSEG1_TOO_SMALL 2u
+#define CAN_TSEG2_TOO_SMALL 3u
+#define CAN_SJW_TOO_BIG 4u
+#define CAN_BASIC_CAN_MAILBOX 5u
+#define CAN_NO_RTR_MAILBOX 6u
+#define CAN_INVALID_MAILBOX 7u
+
+/* Flag bits */
+#define CAN_NO_MSG 0x00u
+#define CAN_VALID_MSG 0x01u
+
+/*
+ * A couple of definitions just to make the code more readable so we know
+ * what a 1 and 0 mean.
+#define CAN_RTR 1<<21
+#define CAN_EXT_IDE 1<<20
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used in the MSS CAN driver for Interrupt Bit
+ Definitions
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ */
+#define CAN_INT_GLOBAL 1<<0 /* Global interrupt */
+#define CAN_INT_ARB_LOSS 1<<2 /* Arbitration loss interrupt */
+#define CAN_INT_OVR_LOAD 1<<3 /*Overload interrupt */
+#define CAN_INT_BIT_ERR 1<<4 /* Bit error interrupt */
+#define CAN_INT_STUFF_ERR 1<<5 /* Bit stuffing error interrupt */
+#define CAN_INT_ACK_ERR 1<<6 /* Acknowledgement error interrupt */
+#define CAN_INT_FORM_ERR 1<<7 /* Format error interrupt */
+#define CAN_INT_CRC_ERR 1<<8 /* CRC error interrupt */
+#define CAN_INT_BUS_OFF 1<<9 /* Bus-off interrupt */
+#define CAN_INT_RX_MSG_LOST 1<<10 /* Rx message lost interrupt */
+#define CAN_INT_TX_MSG 1<<11 /* Tx message interupt */
+#define CAN_INT_RX_MSG 1<<12 /* Rx message interrupt */
+#define CAN_INT_RTR_MSG 1<<13 /* RTR message interrupt */
+#define CAN_INT_STUCK_AT_0 1<<14 /* Stuck-at-0 error interrupt */
+#define CAN_INT_SST_FAILURE 1<<15 /* Single-shot transmission error interrupt*/
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for transmit message buffer control bit
+ definitions:
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_TX_WPNH_EBL | Indicates “WPNH” bit mask |
+ | CAN_TX_WPNL_EBL | Indicates WPNL bit mask |
+ | CAN_TX_REQ | Indicates transmit request flag bit position |
+ | CAN_TX_INT_EBL | Indicates transmit Interrupt enable bit mask |
+ | CAN_TX_ABORT | Indicates Transmit abort mask |
+
+ */
+#define CAN_TX_WPNH_EBL 1<<23
+#define CAN_TX_WPNL_EBL 1<<3
+#define CAN_TX_INT_EBL 1<<2
+#define CAN_TX_ABORT 1<<1
+#define CAN_TX_REQ 0x01u
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for receive message buffer control bit
+ definitions:
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_RX_WPNH_EBL | Indicates WPNH bit mask. |
+ | CAN_RX_WPNL_EBL | Indicates WPNL bit mask |
+ | CAN_RX_LINK_EBL | Indicates link flag bit mask |
+ | CAN_RX_INT_EBL | Indicates receive interrupt enable bit mask |
+ | CAN_RX_RTR_REPLY_EBL | Indicates RTR reply bit mask |
+ | CAN_RX_BUFFER_EBL | Indicates Transaction buffer enable bit mask |
+ | CAN_RX_RTR_ABORT | Indicates RTR abort request mask |
+ | CAN_RX_RTRP | Indicates RTReply pending status mask |
+ | CAN_RX_MSGAV | Indicates receive message available status mask|
+
+ */
+#define CAN_RX_WPNH_EBL 1<<23
+#define CAN_RX_WPNL_EBL 1<<7
+#define CAN_RX_LINK_EBL 1<<6
+#define CAN_RX_INT_EBL 1<<5
+#define CAN_RX_RTR_REPLY_EBL 1<<4
+#define CAN_RX_BUFFER_EBL 1<<3
+#define CAN_RX_RTR_ABORT 1<<2
+#define CAN_RX_RTRP 1<<1
+#define CAN_RX_MSGAV 0x01
+
+/*-------------------------------------------------------------------------*//**
+ The mss_can_mode_t enumeration specifies the possible operating modes of CAN
+ controller. The meaning of the constants is as described below
+
+ | Modes | Description |
+ |----------------------------|------------------------------------------|
+ | CANOP_MODE_NORMAL | Indicates CAN controller is in normal |
+ | | operational mode. |
+ | CANOP_MODE_LISTEN_ONLY | Indicates CAN controller is in listen |
+ | | only mode. |
+ | CANOP_MODE_EXT_LOOPBACK | Indicates CAN controller is in external |
+ | | loop back mode. |
+ | CANOP_MODE_INT_LOOPBACK | Indicates CAN controller is in internal |
+ | | loop back mode. |
+ | CANOP_SRAM_TEST_MODE | Indicates CAN controller is in test mode.|
+ | CANOP_SW_RESET | Indicates CAN controller is in stop mode.|
+
+ */
+typedef enum mss_can_mode
+{
+ CANOP_MODE_NORMAL = 0x01u,
+ CANOP_MODE_LISTEN_ONLY = 0x03u,
+ CANOP_MODE_EXT_LOOPBACK = 0x05u,
+ CANOP_MODE_INT_LOOPBACK = 0x07u,
+ CANOP_SRAM_TEST_MODE = 0x08u,
+ CANOP_SW_RESET = 0x10u
+} mss_can_mode_t;
+
+typedef struct _mss_can_msgobject
+{
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields. */
+ union
+ {
+ __IO uint32_t L; /* 32 bit flag */
+ struct
+ {
+ /* Flags structure. */
+ __IO uint32_t NA0:16;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:10;
+ };
+ };
+} mss_can_msgobject;
+
+typedef mss_can_msgobject * pmss_can_msgobject;
+
+/* _CAN_filterobject */
+
+typedef struct _CAN_filterobject
+{
+ /* Acceptance mask settings */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } AMR;
+
+ /* Acceptance code settings */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } ACR;
+
+ /* Acceptance mask and code settings for first two data bytes */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t MASK:16;
+ __IO uint32_t CODE:16;
+ };
+ } AMCR_D;
+} mss_can_filterobject;
+
+typedef mss_can_filterobject * pmss_can_filterobject;
+
+/*_CAN_txmsgobject */
+
+typedef struct _CAN_txmsgobject
+{
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields.*/
+ union
+ {
+ __IO uint32_t L;
+
+ /* Tx Flags structure. */
+ struct
+ {
+ __IO uint32_t TXREQ:1;
+ __IO uint32_t TXABORT:1;
+ __IO uint32_t TXINTEBL:1;
+ __IO uint32_t WPNL:1;
+ __IO uint32_t NA0:12;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:1;
+ __IO uint32_t WPNH:1;
+ __IO uint32_t NA2:8;
+ };
+ } TXB;
+
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+} mss_can_txmsgobject;
+
+/* _mss_can_rxmsgobject */
+
+typedef struct _mss_can_rxmsgobject
+{
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields. */
+ union
+ {
+ __IO uint32_t L; /* 32 bit flag */
+
+ /* Tx Flags structure. */
+ struct
+ {
+ __IO uint32_t MSGAV:1;
+ __IO uint32_t RTRREPLYPEND:1;
+ __IO uint32_t RTRABORT:1;
+ __IO uint32_t BUFFEREBL:1;
+ __IO uint32_t RTRREPLY:1;
+ __IO uint32_t RXINTEBL:1;
+ __IO uint32_t LINKFLAG:1;
+ __IO uint32_t WPNL:1;
+ __IO uint32_t NA0:8;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:1;
+ __IO uint32_t WPNH:1;
+ __IO uint32_t NA2:8;
+ };
+ } RXB;
+
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+ /* CAN Message Filter: Acceptance mask register */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } AMR;
+
+ /* CAN Message Filter: Acceptance code register */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } ACR;
+
+ __IO uint32_t AMR_D;
+ __IO uint32_t ACR_D;
+
+} mss_can_rxmsgobject;
+typedef mss_can_rxmsgobject * pmss_can_rxmsgobject;
+
+/* Error status register */
+typedef union error_status
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t TX_ERR_CNT:8;
+ __IO uint32_t RX_ERR_CNT:8;
+ __IO uint32_t ERROR_STAT:2;
+ __IO uint32_t TXGTE96:1;
+ __IO uint32_t RXGTE96:1;
+ __IO uint32_t N_A:12;
+ };
+} mss_can_error_status;
+
+/*
+ * Buffer status register For CANMOD3X,
+ * this are two 32-bit registers, for can, it is only one 32-bit register.
+ */
+#ifdef CANMOD3
+typedef union buffer_status
+{
+ __I uint32_t L;
+ struct
+ {
+ __I uint32_t RXMSGAV:16;
+ __I uint32_t TXREQ:8;
+ __I uint32_t N_A:8;
+ };
+#else
+typedef struct buffer_status
+{
+ __I uint32_t RXMSGAV;
+ __I uint32_t TXREQ;
+#endif
+} mss_can_buffer_status;
+
+/* Interrupt enable register */
+typedef union int_enable
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t INT_EBL:1;
+ __IO uint32_t N_A0:1;
+ __IO uint32_t ARB_LOSS:1;
+ __IO uint32_t OVR_LOAD:1;
+ __IO uint32_t BIT_ERR:1;
+ __IO uint32_t STUFF_ERR:1;
+ __IO uint32_t ACK_ERR:1;
+ __IO uint32_t FORM_ERR:1;
+ __IO uint32_t CRC_ERR:1;
+ __IO uint32_t BUS_OFF:1;
+ __IO uint32_t RX_MSG_LOSS:1;
+ __IO uint32_t TX_MSG:1;
+ __IO uint32_t RX_MSG:1;
+ __IO uint32_t RTR_MSG:1;
+ __IO uint32_t STUCK_AT_0:1;
+ __IO uint32_t SST_FAILURE:1;
+ __IO uint32_t N_A1:16;
+ };
+} mss_can_int_enable;
+
+typedef mss_can_int_enable * pmss_can_int_enable;
+
+/* Interrupt status register */
+typedef union int_status
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A0:2;
+ __IO uint32_t ARB_LOSS:1;
+ __IO uint32_t OVR_LOAD:1;
+ __IO uint32_t BIT_ERR:1;
+ __IO uint32_t STUFF_ERR:1;
+ __IO uint32_t ACK_ERR:1;
+ __IO uint32_t FORM_ERR:1;
+ __IO uint32_t CRC_ERR:1;
+ __IO uint32_t BUS_OFF:1;
+ __IO uint32_t RX_MSG_LOSS:1;
+ __IO uint32_t TX_MSG:1;
+ __IO uint32_t RX_MSG:1;
+ __IO uint32_t RTR_MSG:1;
+ __IO uint32_t STUCK_AT_0:1;
+ __IO uint32_t SST_FAILURE:1;
+ __IO uint32_t N_A1:16;
+ };
+} mss_can_int_status;
+typedef mss_can_int_status * pmss_can_int_status;
+
+/* Command register */
+typedef union command_reg
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t RUN_STOP:1;
+ __IO uint32_t LISTEN_ONLY:1;
+ __IO uint32_t LOOP_BACK:1;
+ __IO uint32_t SRAM_TEST:1;
+ __IO uint32_t SW_RESET:1;
+ __IO uint32_t N_A:27;
+ };
+} mss_can_command_reg;
+
+/* Configuration register */
+typedef union can_config_reg
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t EDGE_MODE:1;
+ __IO uint32_t SAMPLING_MODE:1;
+ __IO uint32_t CFG_SJW:2;
+ __IO uint32_t AUTO_RESTART:1;
+ __IO uint32_t CFG_TSEG2:3;
+ __IO uint32_t CFG_TSEG1:4;
+ __IO uint32_t CFG_ARBITER:1;
+ __IO uint32_t ENDIAN:1;
+ __IO uint32_t ECR_MODE:1;
+ __IO uint32_t N_A0:1;
+ __IO uint32_t CFG_BITRATE:15;
+ __IO uint32_t N_A1:1;
+ };
+} mss_can_config_reg;
+typedef mss_can_config_reg * pmss_can_config_reg ;
+
+/* Register mapping of CAN controller */
+typedef struct CAN_device
+{
+ mss_can_int_status IntStatus; /* Interrupt status register */
+ mss_can_int_enable IntEbl; /* Interrupt enable register */
+ mss_can_buffer_status BufferStatus; /* Buffer status indicators */
+ mss_can_error_status ErrorStatus; /* Error status */
+ mss_can_command_reg Command; /* CAN operating mode */
+ mss_can_config_reg Config; /* Configuration register */
+#ifdef CANMOD3
+ uint32_t NA[2];
+#else
+ uint32_t NA;
+#endif
+ mss_can_txmsgobject TxMsg[CAN_TX_MAILBOX]; /* Tx message buffers */
+ mss_can_rxmsgobject RxMsg[CAN_RX_MAILBOX]; /* Rx message buffers */
+
+} CAN_DEVICE;
+
+typedef CAN_DEVICE * PCAN_DEVICE;
+
+#define MSS_CAN_0_LO_BASE (CAN_DEVICE*)0x2010C000
+#define MSS_CAN_1_LO_BASE (CAN_DEVICE*)0x2010D000
+#define MSS_CAN_0_HI_BASE (CAN_DEVICE*)0x2810C000
+#define MSS_CAN_1_HI_BASE (CAN_DEVICE*)0x2810D000
+
+#define SYSREG_CAN_A_SOFTRESET_MASK ( (uint32_t)0x01u << 14u )
+#define SYSREG_CAN_B_SOFTRESET_MASK ( (uint32_t)0x01u << 15u )
+
+/*-------------------------------------------------------------------------*//**
+ The structure mss_can_instance_t is used by the driver to manage the
+ configuration and operation of each MSS CAN peripheral. The instance content
+ should only be accessed by using the respective API functions.
+
+ Each API function has a pointer to this instance as first argument.
+
+ */
+typedef struct can_instance
+{
+ /* Hardware related entries (pointer to device, interrupt number etc) */
+ CAN_DEVICE * hw_reg; /* Pointer to CAN registers. */
+ uint8_t irqn; /* refer to local or PLIC */
+ uint8_t int_type; /*!< 0 => local, 1 => PLIC */
+ /* Local data (eg pointer to local FIFO, irq number etc) */
+ uint8_t basic_can_rx_mb; /* number of rx mailboxes */
+ uint8_t basic_can_tx_mb; /* number of tx mailboxes */
+ } mss_can_instance_t;
+
+ /*------------------------------------------------------------------------*//**
+ This instances of mss_can_instance_t holds all data related to the operations
+ performed by CAN. A pointer to instance is passed as the first parameter
+ to CAN driver functions to indicate that which CAN instance should perform the
+ requested operation.
+ */
+extern mss_can_instance_t g_mss_can_0_lo;
+extern mss_can_instance_t g_mss_can_1_lo;
+extern mss_can_instance_t g_mss_can_0_hi;
+extern mss_can_instance_t g_mss_can_1_hi;
+
+/*----------------------------------------------------------------------------*/
+/*-----------------------MSS CAN Public APIs ---------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_init() function initializes the CAN driver as well as the CAN
+ controller. The basic_can_rx_mb and basic_can_tx_mb are used to configure the
+ number of receive and transmit mailboxes in basic CAN operation. This function
+ configures the CAN channel speed as per the “bitrate” parameter. It
+ initializes all receive mailboxes and make it ready for configuration. This is
+ the first function to be called before using any other function.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param bitrate
+ The bitRate parameter is used to configure CAN speed. The following standard
+ preset definitions are provided for systems with a PCLK1 of 8MHz, 16MHz or
+ 32MHz:
+ +-------------------+--------------------+--------------------+
+ | 8MHz PCLK1 | 16MHz PCLK1 | 32MHz PCLK1 |
+ +-------------------+--------------------+--------------------+
+ | CAN_SPEED_8M_5K | CAN_SPEED_16M_5K | CAN_SPEED_32M_5K |
+ | CAN_SPEED_8M_10K | CAN_SPEED_16M_10K | CAN_SPEED_32M_10K |
+ | CAN_SPEED_8M_20K | CAN_SPEED_16M_20K | CAN_SPEED_32M_20K |
+ | CAN_SPEED_8M_50K | CAN_SPEED_16M_50K | CAN_SPEED_32M_50K |
+ | CAN_SPEED_8M_100K | CAN_SPEED_16M_100K | CAN_SPEED_32M_100K |
+ | CAN_SPEED_8M_125K | CAN_SPEED_16M_125K | CAN_SPEED_32M_125K |
+ | CAN_SPEED_8M_250K | CAN_SPEED_16M_250K | CAN_SPEED_32M_250K |
+ | CAN_SPEED_8M_500K | CAN_SPEED_16M_500K | CAN_SPEED_32M_500K |
+ | CAN_SPEED_8M_1M | CAN_SPEED_16M_1M | CAN_SPEED_32M_1M |
+ +-------------------+--------------------+--------------------+
+
+ For custom settings, use CAN_SPEED_MANUAL and configure the settings via
+ pcan_config.
+
+ The default configurations can be altered by the addition of 0 or more of
+ the following:
+ - CAN_AUTO_RESTART
+ - CAN_ARB_FIXED_PRIO
+ - CAN_LITTLE_ENDIAN
+
+ @param pcan_config
+ The pcan_config parameter is a pointer to a mss_can_config_reg structure. This
+ structure is only used when bitrate is configured as CAN_SPEED_MANUAL.
+
+ When populating the mss_can_config_reg structure, the following should be noted:
+
+ 1. CFG_BITRATE defines the length of a CAN time quantum in terms of PCLK1
+ with 0 = 1 PCLK1, 1 = 2 PCLK1s and so on.
+ 2. A CAN bit time is made up of between 8 and 25 time quanta and the bit
+ rate is PCLK1 / ((CFG_BITRATE + 1) * number of time quanta per bit).
+ 3. There is a fixed overhead of 1 time quantum for synchronization at the
+ start of every CAN bit and the remaining time quanta in the bit are
+ allocated with CFG_TSEG1 and CFG_TSEG2.
+ 4. CFG_TSEG1 can have a value between 2 and 15 which represents between 3
+ and 16 time quanta.
+ 5. If SAMPLING_MODE is 0, CFG_TSEG2 can have a value between 1 and 7 which
+ represents between 2 and 8 time quanta and if SAMPLING_MODE is 1,
+ CFG_TSEG2 can have a value between 2 and 7 which represents between 3
+ and 8 time quanta.
+ 6. Receive sampling takes place at the end of the segment defined by
+ CFG_TSEG1.
+
+ For example, if CFG_TSEG1 = 3 and CFG_TSEG2 = 2 we get:
+
+ |<------------ 1 CAN bit time (8 time quanta)------------>|
+ /------+------+------+------+------+------+------+------\
+ -+ Synch | CFG_TSEG1 + 1 | CFG_TSEG2 + 1 +-
+ \------+------+------+------+------+------+------+------/
+ |
+ Receiver samples date here -->|
+
+ @param basic_can_rx_mb
+ The basic_can_rx_mb parameter is the number of receive mailboxes used in
+ basic CAN mode.
+
+ @param basic_can_tx_mb
+ The basic_can_tx_mb parameter is the number of transmit mailboxes used in
+ basic CAN mode.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_TSEG1_TOO_SMALL | Value provided to configure TSEG1 is too |
+ | | small |
+ | CAN_TSEG2_TOO_SMALL | Value provided to configure TSEG2 is too |
+ | | small |
+ | CAN_SJW_TOO_BIG | Value provided to configure synchronous jump|
+ | | width (SJW) is too big. |
+
+ Example 1: Using a default set for bitrate, tseg1, tseg2, and sjw and
+ additional configuration parameters.
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo, (CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16u,7u);
+
+ return(0);
+ }
+ @endcode
+
+ Example 2: Using custom settings for bitrate, tseg1, tseg2, and sjw.
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+
+ #define SYSTEM_CLOCK 8000000
+ #define BITS_PER_SECOND 10000
+
+ int e51(void)
+ {
+ mss_can_config_reg canreg;
+
+ canreg.CFG_BITRATE = (SYSTEM_CLOCK / (BITS_PER_SECOND * 8) - 1;
+ canreg.CFG_TSEG1 = 4;
+ canreg.CFG_TSEG2 = 1;
+ canreg.AUTO_RESTART = 0;
+ canreg.CFG_SJW = 0;
+ canreg.SAMPLING_MODE = 0;
+ canreg.EDGE_MODE = 0;
+ canreg.ENDIAN = 1;
+
+ MSS_CAN_init(&g_mss_can_0_lo,CAN_SPEED_MANUAL,&canreg,8,4);
+
+ return(0);
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_init
+(
+ mss_can_instance_t* this_can,
+ uint32_t bitrate,
+ pmss_can_config_reg pcan_config,
+ uint8_t basic_can_rx_mb,
+ uint8_t basic_can_tx_mb
+);
+
+ /*------------------------------------------------------------------------*//**
+ The MSS_CAN_set_config_reg() function sets the configuration register and
+ starts the CAN controller for normal mode operation. This function is used
+ when one needs to change the configuration settings while the CAN controller
+ was already initialized using MSS_CAN_init() function and is running.
+ MSS_CAN_set_config_reg() function should not be used when the CAN controller
+ wasn't initialized yet.
+
+ It performs following tasks:
+ - Clears all pending interrupts
+ - Stops CAN controller
+ - Disable interrupts
+ - Sets new configuration
+ - Starts CAN controller
+
+ @param this_can
+ The this_can parameter is a pointer to the MSS_CAN_instance_t structure.
+
+ @param cfg
+ The cfg parameter is a 4 bytes variable used to set the configuration
+ settings.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+
+ int e51(void)
+ {
+ Return_status = MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | \
+ CAN_AUTO_RESTART | CAN_LITTLE_ENDIAN),
+ (pmss_can_config_reg)0,16,7);
+ ....
+
+ MSS_CAN_set_config_reg(&g_mss_can_0_lo, (CAN_SPEED_16M_500K | \
+ CAN_AUTO_RESTART | CAN_LITTLE_ENDIAN));
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_config_reg
+(
+ mss_can_instance_t* this_can,
+ uint32_t cfg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_mode() function sets the CAN controller operating mode based
+ on the mode parameter. After this operation CAN controller is not in
+ operational, to do that invoke MSS_CAN_start() function.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mode
+ The mode parameter tells about desired operating mode of CAN controller.
+ Possible operating modes are as mentioned below:
+
+ | Mode | Description |
+ |--------------------------|-----------------------------------------|
+ | CANOP_MODE_INT_LOOPBACK | Sets normal operating mode |
+ | CANOP_MODE_LISTEN_ONLY | In listen-only mode, the CAN controller |
+ | | does not send any messages. Normally |
+ | | used for automatic bitrate detection |
+ | CANOP_MODE_INT_LOOPBACK | Selects internal loopback mode. This is |
+ | | used for self-test |
+ | CANOP_MODE_EXT_LOOPBACK | Selects external loopback. The CAN |
+ | | controller will receive a copy of each |
+ | | message sent. |
+ | CANOP_SRAM_TEST_MODE | Sets SRAM test mode |
+ | CANOP_SW_RESET | Issues a software reset |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+
+ ....
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_mode
+(
+ mss_can_instance_t* this_can,
+ mss_can_mode_t mode
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_start() function clears all pending interrupts and enable CAN
+ controller to perform normal operation. It enables receive interrupts also.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+ MSS_CAN_start(&g_mss_can_0_lo);
+
+ ....
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_start
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_stop() function is used to disable the CAN controller.
+
+ NOTE: Interrupt flags status remain unaffected.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+ MSS_CAN_start(&g_mss_can_0_lo);
+
+ ....
+ ....
+
+ MSS_CAN_stop(&g_mss_can_0_lo);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_stop
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_id() function returns the message identifier. Bits right
+ justified based on message identifier (Extended identifier) type.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns message identifier.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ...
+ return_id = MSS_CAN_get_id(&pmsg);
+
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_id
+(
+ pmss_can_msgobject pmsg
+);
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_id() function returns ID bits left justified based on IDE
+ type. IDE type might be either standard or extended.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns message identifier.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+ pmsg->ID = 0x120;
+ MSS_CAN_set_id(&pmsg);
+
+ ....
+ return(0);
+ }
+ @endcode
+*/
+uint32_t
+MSS_CAN_set_id
+(
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_msg_filter_mask() function packs the ID, IDE, and RTR bits
+ together as they are used in the message filter mask and returns packed
+ identifier.
+
+ @param id
+ The id parameter is a 4 byte variable to hold message identifier.
+
+ @param ide
+ The ide parameter is a 1 byte variable to indicate IDE type. Acceptable
+ values are as mentioned below:
+
+ | Value | Description |
+ |------------|-------------------------------|
+ | 0 | Standard format |
+ | 1 | Extended format |
+
+ @param rtr
+ The rtr parameter is a 1 byte variable to indicate message type. Acceptable
+ values are as mentioned below:
+
+ | Value | Description |
+ |------------|-------------------------------|
+ | 0 | Regular message (data frame) |
+ | 1 | RTR message (remote frame) |
+
+ @return
+ This function returns packed id.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_msg_filter_mask( 0x120, 1, 0);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_msg_filter_mask
+(
+ uint32_t id,
+ uint8_t ide,
+ uint8_t rtr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_int_ebl() function enable specific interrupt based on
+ irq_flag parameter.
+
+ @param this_can
+ This is a pointer to an mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+
+ | Constants | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_set_int_ebl(&g_mss_can_0_lo,CAN_INT_TX_MSG);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_clear_int_ebl() function disable specific interrupt based on
+ irq_flag parameter.
+
+ @param this_can
+ This is a pointer to an mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+
+ | Constant | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_clear_int_ebl(&g_mss_can_0_lo,CAN_INT_TX_MSG);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_clear_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_global_int_ebl() function returns the status of global
+ interrupt enable flag.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns global interrupt enable flag status.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_global_int_ebl(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_global_int_ebl
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_int_ebl() function returns the status of interrupt enable
+ flags.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns interrupt enable flag status.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_int_ebl(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_int_ebl
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_clear_int_status() function clears the selected interrupt flags.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+ | Constants | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+ MSS_CAN_clear_int_status(&g_mss_can_0_lo,CAN_INT_RX_MSG);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_clear_int_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_int_status() function returns the status of interrupts.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of existed interrupts.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_int_status(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_int_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_rtr_message_n () function loads mailbox with the given CAN
+ message. This message will be sent out after receipt of a RTR message
+ request. It verifies that whether the given mailbox is configured for Full
+ CAN or not and also checks for RTR auto-reply is enabled or not.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+ | CAN_NO_RTR_MAILBOX | Indicates that there is no mailbox for |
+ | | remote transmit request (RTR) frame |
+
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ pmsg->ID = 0x120;
+ pmsg->DATALOW = 0xAA5555AA;
+ pmsg->DATAHIGH = 0xAA5555AA;
+
+ MSS_CAN_set_rtr_message_n(&g_mss_can_0_lo, 5, &pmsg);
+
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_set_rtr_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rtr_message_abort_n() function aborts a RTR message transmit
+ request on mailbox mailbox_number and checks that message abort was
+ successful.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ ret_status = MSS_CAN_get_rtr_message_abort_n((&g_mss_can_0_lo, 6);
+
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_get_rtr_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_config_buffer() function configures receive mailboxes initialized
+ for Basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pfilter
+ The pfilter parameter is a pointer to the CAN message filter structure.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ pfilter.ACR.L=0x00000000;
+ pfilter.AMR.L= 0xFFFFFFFF;
+ pfilter.AMCR_D.MASK= 0xFFFF;
+ pfilter.AMCR_D.CODE= 0x00;
+
+ ret_status = MSS_CAN_config_buffer(&g_mss_can_0_lo, &pfilter);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_config_buffer
+(
+ mss_can_instance_t* this_can,
+ pmss_can_filterobject pfilter
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_config_buffer_n() function configures the receive mailbox
+ specified in mailbox_number. The function checks that the mailbox is set for
+ Full CAN operation, if not it return with error code.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes
+ - CAN_BASIC_CAN_MAILBOX
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ rx_msg.ID = 0x200;
+ rx_msg.DATAHIGH = 0u;
+ rx_msg.DATALOW = 0u;
+ rx_msg.AMR.L = 0xFFFFFFFF;
+ rx_msg.ACR.L = 0x00000000;
+ rx_msg.AMR_D = 0x0000FFFF;
+ rx_msg.ACR_D = 0x00000000;
+ rx_msg.RXB.DLC = 8u;
+ rx_msg.RXB.IDE = 0;
+
+ ret_status = MSS_CAN_config_buffer_n(&g_mss_can_0_lo, 3, &rx_msg);
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_config_buffer_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_rxmsgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message_n() function read message from the receive mailbox
+ specified in "mailbox_number" parameter and returns status of operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that will hold the
+ received message.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject msg;
+ ...
+
+ ret_status = MSS_CAN_get_message_n(&g_mss_can_0_lo, 3, &msg);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message() function read message from the first mailbox set
+ for Basic CAN operation that contains a message. Once the message has been
+ read from the mailbox, the message receipt is acknowledged.
+ Note: Since neither a hardware nor a software FIFO exists, message inversion
+ might happen (example, a newer message might be read from the receive
+ buffer prior to an older message).
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object, that will hold the
+ received message.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject rx_buf;
+ ...
+ if(CAN_VALID_MSG == MSS_CAN_get_message_av(&g_mss_can_0_lo))
+ {
+ if(CAN_VALID_MSG != MSS_CAN_get_message(&g_mss_can_0_lo, &rx_buf))
+ {
+ ....
+ }
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message_av() function indicates if receive buffer contains a
+ new message in Basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject rx_buf;
+ ...
+ if(CAN_VALID_MSG == MSS_CAN_get_message_av(&g_mss_can_0_lo))
+ {
+ MSS_CAN_get_message(&g_mss_can_0_lo, &rx_buf);
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message_av
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_n() function sends a message using mailbox
+ "mailbox_number". The function verifies that this mailbox is configured for
+ Full CAN operation and is empty.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that holds the CAN
+ message to transmit.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will return the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID=0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0<<20)| 0x00080000);
+
+ if (CAN_OK != MSS_CAN_send_message_n(&g_mss_can_0_lo, 0, &pmsg))
+ {
+ ...
+ }
+
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_abort_n() function aborts a message transmit
+ request for the specified mailbox number in mailbox_number and checks that
+ message abort status.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it
+ will return the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ if (CAN_OK != MSS_CAN_send_message_abort_n(&g_mss_can_0_lo, 0))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_ready() function will identify the availability of
+ mailbox to fill with new message in basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns CAN_OK on successful identification of free mailbox,
+ otherwise it will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID = 0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0 << 20)| 0x00080000);
+
+ if(CAN_OK == MSS_CAN_send_message_ready(&g_mss_can_0_lo))
+ {
+ MSS_CAN_send_message(&g_mss_can_0_lo, &pmsg);
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_ready
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message() function will copy the data to the first available
+ mailbox set for Basic CAN operation and send data on to the bus.
+ Note: Since neither a hardware nor a software FIFO exists, message inversion
+ might happen (example, a newer message might be send from the transmit
+ buffer prior to an older message).
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that holds the CAN
+ message to transmit.
+
+ @return
+ This function returns CAN_OK on successful identification of free mailbox,
+ otherwise it will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID = 0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0 << 20)| 0x00080000);
+
+ if (CAN_OK == MSS_CAN_send_message_ready(&g_mss_can_0_lo))
+ {
+ if (CAN_OK != MSS_CAN_send_message(&g_mss_can_0_lo, &pmsg))
+ {
+ ...
+ }
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_mask_n() function returns the message filter settings of the
+ selected receive mailbox. The function is valid for Full CAN operation only.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pamr
+ The pamr parameter is a pointer to the acceptance mask.
+
+ @param pacr
+ The pacr parameter is a pointer to the acceptance code.
+
+ @param pdta_amr
+ The pdta_amr parameter is a pointer to the acceptance mask of first two
+ data bytes.
+
+ @param pdta_acr
+ The pdta_acr parameter is a pointer to the acceptance code of first two
+ data bytes.
+
+ @return
+ This function will returns the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ if (CAN_OK != MSS_CAN_get_mask_n(&g_mss_can_0_lo,mailbox_number,&pamr,&pacr,
+ &pdamr, &pdacr))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_get_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t *pamr,
+ uint32_t *pacr,
+ uint16_t *pdta_amr,
+ uint16_t *pdta_acr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_mask_n() function configures the message filter settings for
+ the selected receive mailbox. The function is valid for Full CAN operation
+ only.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param amr
+ The amr parameter is a variable to hold the acceptance mask.
+
+ @param acr
+ The acr parameter is a variable to hold the acceptance code.
+
+ @param dta_amr
+ The dta_amr parameter is a variable to hold the acceptance mask of first two
+ data bytes.
+
+ @param dta_acr
+ The dta_acr parameter is a variable to hold the acceptance code of first two
+ data bytes.
+
+ @return
+ This function returns the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ if (CAN_OK != MSS_CAN_set_mask_n(&g_mss_can_0_lo,mailbox_number,&pamr,&pacr,
+ &pdamr, &pdacr))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_set_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t amr,
+ uint32_t acr,
+ uint16_t dta_amr,
+ uint16_t dta_acr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_buffer_status() function returns the buffer status of all
+ receive (32) mailboxes.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of receive buffers (32 buffers).
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status=0;
+ ...
+ return_status = MSS_CAN_get_rx_buffer_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_buffer_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_buffer_status() function returns the buffer status of all
+ transmit(32) mailboxes.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of transmit buffers (32 buffers).
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_buffer_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+*/
+uint32_t
+MSS_CAN_get_tx_buffer_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_error_status() function returns the present error state of
+ the CAN controller. Error state might be error active or error passive or
+ bus-off.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param status
+ The status parameter is a pointer to hold the content of error status
+ register.
+
+ @return
+ The function shall return the following codes:
+ | Codes | Descriptions |
+ |--------|-------------------------------|
+ | 0 | error active |
+ | 1 | error passive |
+ | 2 | bus-off |
+
+ Example:
+ @code
+ e51()
+ {
+ uint8_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_error_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_error_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t* status
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_error_count() function returns the current receive error
+ counter value. Counter value ranges from 0x00 - 0xFF.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns the receive error counter value.
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_rx_error_count(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_error_count
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_gte96() function provides information about receive
+ error count. It identifies that receive error count is greater than or equal
+ to 96, and reports 1 if count exceeds 96.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns following values:
+
+ | Value | Description |
+ |-------|------------------------------------------------------|
+ | 0 | if receive error count less than 96. |
+ | 1 | if receive error count greater than or equals to 96. |
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_rx_gte96(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_gte96
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_error_count() function returns the current transmit error
+ counter value. Counter value ranges from 0x00 - 0xFF.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns the transmit error counter value.
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_error_count(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_tx_error_count
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_gte96() function provides information about transmit
+ error count. It identifies that transmit error count is greater than or equals
+ to 96, and reports 1 if count exceeds 96.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns following values:
+
+ | Value | Description |
+ |-------|-------------------------------------------------------|
+ | 0 | if transmit error count less than 96. |
+ | 1 | if transmit error count greater than or equals to 96. |
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_gte96(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_tx_gte96
+(
+ mss_can_instance_t* this_can
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_CAN_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart.c
new file mode 100644
index 00000000..3c63ce71
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart.c
@@ -0,0 +1,1841 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver
+ * implementation.
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+#include "mss_uart_regs.h"
+#include "mss_uart.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MSS_UART0_LO_BASE (MSS_UART_TypeDef*)0x20000000UL
+#define MSS_UART1_LO_BASE (MSS_UART_TypeDef*)0x20100000UL
+#define MSS_UART2_LO_BASE (MSS_UART_TypeDef*)0x20102000UL
+#define MSS_UART3_LO_BASE (MSS_UART_TypeDef*)0x20104000UL
+#define MSS_UART4_LO_BASE (MSS_UART_TypeDef*)0x20106000UL
+
+#define MSS_UART0_HI_BASE (MSS_UART_TypeDef*)0x28000000UL
+#define MSS_UART1_HI_BASE (MSS_UART_TypeDef*)0x28100000UL
+#define MSS_UART2_HI_BASE (MSS_UART_TypeDef*)0x28102000UL
+#define MSS_UART3_HI_BASE (MSS_UART_TypeDef*)0x28104000UL
+#define MSS_UART4_HI_BASE (MSS_UART_TypeDef*)0x28106000UL
+
+
+mss_uart_instance_t g_mss_uart0_lo;
+mss_uart_instance_t g_mss_uart1_lo;
+mss_uart_instance_t g_mss_uart2_lo;
+mss_uart_instance_t g_mss_uart3_lo;
+mss_uart_instance_t g_mss_uart4_lo;
+
+mss_uart_instance_t g_mss_uart0_hi;
+mss_uart_instance_t g_mss_uart1_hi;
+mss_uart_instance_t g_mss_uart2_hi;
+mss_uart_instance_t g_mss_uart3_hi;
+mss_uart_instance_t g_mss_uart4_hi;
+
+/* This variable tracks if the UART peripheral is located on S5 or S6 on AXI
+ * switch. This will be used to determine which UART instance to be passed to
+ * UART interrupt handler. value 0 = S5(low). value 1 = S6(high)
+ * Bit positions:
+ * 0 ==> MMUART0
+ * 1 ==> MMUART1
+ * 2 ==> MMUART2
+ * 3 ==> MMUART3
+ * 4 ==> MMUART4
+
+ */
+static uint32_t g_uart_axi_pos = 0x0u;
+
+/*******************************************************************************
+ * Defines
+ */
+#define TX_COMPLETE 0u
+#define TX_FIFO_SIZE 16u
+
+#define FCR_TRIG_LEVEL_MASK 0xC0u
+
+#define IIRF_MASK 0x0Fu
+
+#define INVALID_INTERRUPT 0u
+#define INVALID_IRQ_HANDLER ((mss_uart_irq_handler_t) 0)
+#define NULL_HANDLER ((mss_uart_irq_handler_t) 0)
+
+#define MSS_UART_DATA_READY ((uint8_t) 0x01)
+
+#define SYNC_ASYNC_MODE_MASK (0x7u)
+
+#define UART0_POSITION_MASK 0x01u
+#define UART1_POSITION_MASK 0x02u
+#define UART2_POSITION_MASK 0x04u
+#define UART3_POSITION_MASK 0x08u
+#define UART4_POSITION_MASK 0x10u
+
+/*******************************************************************************
+ * Possible values for Interrupt Identification Register Field.
+ */
+#define IIRF_MODEM_STATUS 0x00u
+#define IIRF_THRE 0x02u
+#define IIRF_MMI 0x03u
+#define IIRF_RX_DATA 0x04u
+#define IIRF_RX_LINE_STATUS 0x06u
+#define IIRF_DATA_TIMEOUT 0x0Cu
+
+/*******************************************************************************
+ * Receiver error status mask.
+ */
+#define STATUS_ERROR_MASK ( MSS_UART_OVERUN_ERROR | MSS_UART_PARITY_ERROR | \
+ MSS_UART_FRAMING_ERROR | MSS_UART_BREAK_ERROR | \
+ MSS_UART_FIFO_ERROR)
+
+/*******************************************************************************
+ * Local functions.
+ */
+static void global_init(mss_uart_instance_t * this_uart, uint32_t baud_rate,
+ uint8_t line_config);
+static void uart_isr(mss_uart_instance_t * this_uart);
+static void default_tx_handler(mss_uart_instance_t * this_uart);
+static void enable_irq(const mss_uart_instance_t * this_uart);
+static void disable_irq(const mss_uart_instance_t * this_uart);
+static void config_baud_divisors
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baudrate
+);
+
+/*******************************************************************************
+ * Public Functions
+ *******************************************************************************/
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Disable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+
+ /* set default tx handler for automated TX using interrupt in USART mode */
+ this_uart->tx_handler = default_tx_handler;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void MSS_UART_lin_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Enable LIN mode */
+ this_uart->hw_reg->MM0 |= ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_irda_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config,
+ mss_uart_rzi_polarity_t rxpol,
+ mss_uart_rzi_polarity_t txpol,
+ mss_uart_rzi_pulsewidth_t pw
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Enable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 |= EIRD_MASK;
+
+ ((rxpol == MSS_UART_ACTIVE_LOW) ? (this_uart->hw_reg->MM1 &= ~EIRX_MASK) :
+ (this_uart->hw_reg->MM1 |= EIRX_MASK));
+
+ ((txpol == MSS_UART_ACTIVE_LOW) ? (this_uart->hw_reg->MM1 &= ~EITX_MASK) :
+ (this_uart->hw_reg->MM1 |= EITX_MASK));
+
+ ((pw == MSS_UART_3_BY_16) ? (this_uart->hw_reg->MM1 &= ~EITP_MASK) :
+ (this_uart->hw_reg->MM1 |= EITP_MASK));
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_smartcard_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Disable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Enable SmartCard Mode : Only when data is 8-bit and 2 stop bits */
+ if ((MSS_UART_DATA_8_BITS | MSS_UART_TWO_STOP_BITS) ==
+ (line_config & (MSS_UART_DATA_8_BITS | MSS_UART_TWO_STOP_BITS)))
+ {
+ this_uart->hw_reg->MM2 |= EERR_MASK;
+
+ /* Enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 |= ESWM_MASK;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_polled_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+)
+{
+ uint32_t char_idx = 0u;
+ uint32_t size_sent;
+ uint8_t status;
+ uint32_t temp_tx_size = tx_size;
+
+ ASSERT(pbuff != ( (uint8_t*)0));
+ ASSERT(tx_size > 0u);
+
+ if ((pbuff != ((uint8_t*)0)) && (temp_tx_size > 0u))
+ {
+ /* Remain in this loop until the entire input buffer
+ * has been transferred to the UART.
+ */
+ do
+ {
+ /* Read the Line Status Register and update the sticky record */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /* Check if TX FIFO is empty. */
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t fill_size = TX_FIFO_SIZE;
+
+ /* Calculate the number of bytes to transmit. */
+ if (temp_tx_size < TX_FIFO_SIZE)
+ {
+ fill_size = temp_tx_size;
+ }
+
+ /* Fill the TX FIFO with the calculated the number of bytes. */
+ for (size_sent = 0u; size_sent < fill_size; ++size_sent)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = pbuff[char_idx];
+ char_idx++;
+ }
+
+ /* find the number of bytes remaining(not transmitted yet) */
+ temp_tx_size -= size_sent;
+ }
+ }while (temp_tx_size);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_polled_tx_string
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * p_sz_string
+)
+{
+ uint32_t char_idx = 0u;
+ uint32_t fill_size;
+ uint8_t data_byte;
+ uint8_t status;
+
+ ASSERT(p_sz_string != ((uint8_t*)0));
+
+ if (p_sz_string != ((uint8_t*)0))
+ {
+ /* Get the first data byte from the input buffer */
+ data_byte = p_sz_string[char_idx];
+
+ /* First check for the NULL terminator byte.
+ * Then remain in this loop until the entire string in the input buffer
+ * has been transferred to the UART.
+ */
+ while (0u != data_byte)
+ {
+ /* Wait until TX FIFO is empty. */
+ do
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+ }while (0u == (status & MSS_UART_THRE));
+
+ /* Send bytes from the input buffer until the TX FIFO is full
+ * or we reach the NULL terminator byte.
+ */
+ fill_size = 0u;
+
+ while ((0u != data_byte) && (fill_size < TX_FIFO_SIZE))
+ {
+ /* Send the data byte */
+ this_uart->hw_reg->THR = data_byte;
+ ++fill_size;
+ char_idx++;
+ /* Get the next data byte from the input buffer */
+ data_byte = p_sz_string[char_idx];
+ }
+ }
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_irq_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+)
+{
+ ASSERT(pbuff != ((uint8_t*)0));
+ ASSERT(tx_size > 0u);
+
+ if ((tx_size > 0u) && (pbuff != ((uint8_t*)0)))
+ {
+ /* Initialize the transmit info for the UART instance with the
+ * arguments */
+ this_uart->tx_buffer = pbuff;
+ this_uart->tx_buff_size = tx_size;
+ this_uart->tx_idx = 0u;
+
+ /* assign default handler for data transfer */
+ this_uart->tx_handler = default_tx_handler;
+
+ /* enables TX interrupt */
+ this_uart->hw_reg->IER |= ETBEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+int8_t
+MSS_UART_tx_complete
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ int8_t ret_value = 0;
+ uint8_t status = 0u;
+
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ if ((TX_COMPLETE == this_uart->tx_buff_size) &&
+ ((status & MSS_UART_TEMT) != 0u))
+ {
+ ret_value = (int8_t)1;
+ }
+
+ return ret_value;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+size_t
+MSS_UART_get_rx
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t * rx_buff,
+ size_t buff_size
+)
+{
+ size_t rx_size = 0u;
+ uint8_t status = 0u;
+
+ ASSERT(rx_buff != ((uint8_t*)0));
+ ASSERT(buff_size > 0u);
+
+ if ((rx_buff != (uint8_t*)0) && (buff_size > 0u))
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ while (((status & MSS_UART_DATA_READY) != 0u) && (rx_size < buff_size))
+ {
+ rx_buff[rx_size] = this_uart->hw_reg->RBR;
+ ++rx_size;
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+ }
+ }
+
+ return rx_size;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+)
+{
+ ASSERT(MSS_UART_INVALID_IRQ > irq_mask);
+
+ enable_irq(this_uart);
+
+ if (MSS_UART_INVALID_IRQ > irq_mask)
+ {
+ /* irq_mask encoding: 1- enable
+ * bit 0 - Receive Data Available Interrupt
+ * bit 1 - Transmitter Holding Register Empty Interrupt
+ * bit 2 - Receiver Line Status Interrupt
+ * bit 3 - Modem Status Interrupt
+ */
+ this_uart->hw_reg->IER |= ((uint8_t)(((uint32_t)irq_mask &
+ (uint32_t)IIRF_MASK)));
+
+
+ /*
+ * bit 4 - Receiver time-out interrupt
+ * bit 5 - NACK / ERR signal interrupt
+ * bit 6 - PID parity error interrupt
+ * bit 7 - LIN break detection interrupt
+ * bit 8 - LIN Sync detection interrupt
+ */
+ this_uart->hw_reg->IEM |= (uint8_t)(((uint32_t)irq_mask >> 4u) &
+ ((uint32_t)IIRF_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+)
+{
+ /* irq_mask encoding: 1 - disable
+ * bit 0 - Receive Data Available Interrupt
+ * bit 1 - Transmitter Holding Register Empty Interrupt
+ * bit 2 - Receiver Line Status Interrupt
+ * bit 3 - Modem Status Interrupt
+ */
+ this_uart->hw_reg->IER &= ((uint8_t)(~((uint32_t)irq_mask &
+ (uint32_t)IIRF_MASK)));
+
+ /*
+ * bit 4 - Receiver time-out interrupt
+ * bit 5 - NACK / ERR signal interrupt
+ * bit 6 - PID parity error interrupt
+ * bit 7 - LIN break detection interrupt
+ * bit 8 - LIN Sync detection interrupt
+ */
+ this_uart->hw_reg->IEM &= (uint8_t)(~(((uint32_t)irq_mask >> 4u) &
+ ((uint32_t)IIRF_MASK)));
+
+ if(1 == this_uart->local_irq_enabled)
+ {
+ __disable_local_irq((int8_t)MMUART0_E51_INT);
+ }
+ else
+ {
+ disable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler,
+ mss_uart_rx_trig_level_t trigger_level
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER );
+ ASSERT(trigger_level < MSS_UART_FIFO_INVALID_TRIG_LEVEL);
+
+ if ((handler != INVALID_IRQ_HANDLER) &&
+ (trigger_level < MSS_UART_FIFO_INVALID_TRIG_LEVEL))
+ {
+ this_uart->rx_handler = handler;
+
+ /* Set the receive interrupt trigger level. */
+ this_uart->hw_reg->FCR = (this_uart->hw_reg->FCR &
+ (uint8_t)(~((uint8_t)FCR_TRIG_LEVEL_MASK))) |
+ (uint8_t)trigger_level;
+
+ /* Enable receive interrupt. */
+ this_uart->hw_reg->IER |= ERBFI_MASK;
+
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_loopback
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_loopback_t loopback
+)
+{
+ ASSERT(MSS_UART_INVALID_LOOPBACK > loopback);
+
+ if (MSS_UART_INVALID_LOOPBACK > loopback)
+ {
+ switch (loopback)
+ {
+ case MSS_UART_LOCAL_LOOPBACK_OFF:
+ /* Disable local loopback */
+ this_uart->hw_reg->MCR &= ~LOOP_MASK;
+ break;
+
+ case MSS_UART_LOCAL_LOOPBACK_ON:
+ /* Enable local loopback */
+ this_uart->hw_reg->MCR |= LOOP_MASK;
+ break;
+
+ case MSS_UART_REMOTE_LOOPBACK_OFF:
+ case MSS_UART_AUTO_ECHO_OFF:
+ /* Disable remote loopback & automatic echo */
+ this_uart->hw_reg->MCR &= ~(RLOOP_MASK|ECHO_MASK);
+ break;
+
+ case MSS_UART_REMOTE_LOOPBACK_ON:
+ /* Enable remote loopback */
+ this_uart->hw_reg->MCR |= (1u << RLOOP);
+ break;
+
+ case MSS_UART_AUTO_ECHO_ON:
+ /* Enable automatic echo */
+ this_uart->hw_reg->MCR |= (1u << ECHO);
+ break;
+
+ case MSS_UART_INVALID_LOOPBACK:
+ /* Fall through to default. */
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+}
+
+/***************************************************************************//**
+ * interrupt service routine.
+ */
+uint8_t mmuart0_plic_77_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART0_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart0_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart0_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart1_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART1_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart1_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart1_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart2_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART2_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart2_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart2_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart3_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART3_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart3_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart3_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart4_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART4_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart4_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart4_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+void mmuart0_e51_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART0_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart0_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart0_lo);
+ }
+}
+
+void mmuart_u54_h1_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART1_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart1_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart1_lo);
+ }
+}
+
+void mmuart_u54_h2_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART2_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart2_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart2_lo);
+ }
+}
+
+void mmuart_u54_h3_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART3_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart3_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart3_lo);
+ }
+}
+
+void mmuart_u54_h4_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART4_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart4_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart4_lo);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rxstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->linests_handler = handler;
+
+ /* Enable receiver line status interrupt. */
+ this_uart->hw_reg->IER |= ELSI_MASK;
+
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_tx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->tx_handler = handler;
+
+ /* Make TX buffer info invalid */
+ this_uart->tx_buffer = (const uint8_t*)0;
+ this_uart->tx_buff_size = 0u;
+
+ /* Enable transmitter holding register Empty interrupt. */
+ this_uart->hw_reg->IER |= ETBEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_modemstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->modemsts_handler = handler;
+
+ /* Enable modem status interrupt. */
+ this_uart->hw_reg->IER |= EDSSI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+size_t
+MSS_UART_fill_tx_fifo
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * tx_buffer,
+ size_t tx_size
+)
+{
+ uint8_t status = 0u;
+ uint32_t size_sent = 0u;
+
+ ASSERT(tx_buffer != ( (uint8_t*)0));
+ ASSERT(tx_size > 0);
+
+ /* Fill the UART's Tx FIFO until the FIFO is full or the complete input
+ * buffer has been written. */
+ if ((tx_buffer != ((uint8_t*)0)) && (tx_size > 0u))
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t fill_size = TX_FIFO_SIZE;
+
+ if (tx_size < TX_FIFO_SIZE)
+ {
+ fill_size = tx_size;
+ }
+
+ /* Fill up FIFO */
+ for (size_sent = 0u; size_sent < fill_size; size_sent++)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = tx_buffer[size_sent];
+ }
+ }
+ }
+
+ return size_sent;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_rx_status
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_INVALID_PARAM;
+
+ /*
+ * Extract UART receive error status.
+ * Bit 1 - Overflow error status
+ * Bit 2 - Parity error status
+ * Bit 3 - Frame error status
+ * Bit 4 - Break interrupt indicator
+ * Bit 7 - FIFO data error status
+ */
+ this_uart->status |= (this_uart->hw_reg->LSR);
+ status = (this_uart->status & STATUS_ERROR_MASK);
+ /* Clear the sticky status after reading */
+ this_uart->status = 0u;
+
+ return status;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_modem_status
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_INVALID_PARAM;
+
+ /*
+ * Extract UART modem status and place in lower bits of "status".
+ * Bit 0 - Delta Clear to Send Indicator
+ * Bit 1 - Delta Clear to Receive Indicator
+ * Bit 2 - Trailing edge of Ring Indicator detector
+ * Bit 3 - Delta Data Carrier Detect indicator
+ * Bit 4 - Clear To Send
+ * Bit 5 - Data Set Ready
+ * Bit 6 - Ring Indicator
+ * Bit 7 - Data Carrier Detect
+ */
+ status = this_uart->hw_reg->MSR;
+
+ return status;
+}
+
+/***************************************************************************//**
+ * MSS_UART_get_tx_status.
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_tx_status
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_TX_BUSY;
+
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /*
+ * Extract the transmit status bits from the UART's Line Status Register.
+ * Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status.
+ (If = 1, TX FIFO is empty)
+ * Bit 6 - Transmitter Empty (TEMT) status.
+ (If = 1, both TX FIFO and shift register are empty)
+ */
+ status &= (MSS_UART_THRE | MSS_UART_TEMT);
+
+ return status;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_break
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* set break character on Tx line */
+ this_uart->hw_reg->LCR |= SB_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_clear_break
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* remove break character from Tx line */
+ this_uart->hw_reg->LCR &= ~SB_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_pidpei_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->pid_pei_handler = handler;
+
+ /* Enable PID parity error interrupt. */
+ this_uart->hw_reg->IEM |= EPID_PEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_linbreak_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->break_handler = handler;
+
+ /* Enable LIN break detection interrupt. */
+ this_uart->hw_reg->IEM |= ELINBI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_linsync_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->sync_handler = handler;
+
+ /* Enable LIN sync detection interrupt. */
+ this_uart->hw_reg->IEM |= ELINSI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_nack_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->nack_handler = handler;
+
+ /* Enable LIN sync detection interrupt. */
+ this_uart->hw_reg->IEM |= ENACKI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_timeout_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->rto_handler = handler;
+
+ /* Enable receiver timeout interrupt. */
+ this_uart->hw_reg->IEM |= ERTOI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 |= ESWM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 &= ~ESWM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+)
+{
+ ASSERT(MSS_UART_INVALID_ENDIAN > endian);
+
+ if (MSS_UART_INVALID_ENDIAN > endian)
+ {
+ /* Configure MSB first / LSB first for receiver */
+ ((MSS_UART_LITTLEEND == endian) ? (this_uart->hw_reg->MM1 &= ~E_MSB_RX_MASK) :
+ (this_uart->hw_reg->MM1 |= E_MSB_RX_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_tx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+)
+{
+ ASSERT(MSS_UART_INVALID_ENDIAN > endian);
+
+ if (MSS_UART_INVALID_ENDIAN > endian)
+ {
+ /* Configure MSB first / LSB first for transmitter */
+ ((MSS_UART_LITTLEEND == endian) ? (this_uart->hw_reg->MM1 &= ~E_MSB_TX_MASK) :
+ (this_uart->hw_reg->MM1 |= E_MSB_TX_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_filter_length
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_filter_length_t length
+)
+{
+ ASSERT(MSS_UART_INVALID_FILTER_LENGTH > length);
+
+ if (MSS_UART_INVALID_FILTER_LENGTH > length)
+ {
+ /* Configure glitch filter length */
+ this_uart->hw_reg->GFR = (uint8_t)length;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_afm
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable RX FIFO till address flag with correct address is received */
+ this_uart->hw_reg->MM2 |= EAFM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_afm
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Enable RX FIFO irrespective of address flag and
+ correct address is received */
+ this_uart->hw_reg->MM2 &= ~EAFM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_afclear
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Enable address flag clearing */
+ /* Disable RX FIFO till another address flag with
+ correct address is received */
+ this_uart->hw_reg->MM2 |= EAFC_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_afclear
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable address flag clearing */
+ this_uart->hw_reg->MM2 &= ~EAFC_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_rx_timeout
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeout
+)
+{
+ /* Load the receive timeout value */
+ this_uart->hw_reg->RTO = timeout;
+
+ /*Enable receiver time-out */
+ this_uart->hw_reg->MM0 |= ERTO_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_rx_timeout
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable receiver time-out */
+ this_uart->hw_reg->MM0 &= ~ERTO_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeguard
+)
+{
+ /* Load the transmitter time guard value */
+ this_uart->hw_reg->TTG = timeguard;
+
+ /* Enable transmitter time guard */
+ this_uart->hw_reg->MM0 |= ETTG_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable transmitter time guard */
+ this_uart->hw_reg->MM0 &= ~ETTG_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_address
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t address
+)
+{
+ this_uart->hw_reg->ADR = address;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_ready_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_ready_mode_t mode
+)
+{
+ ASSERT(MSS_UART_INVALID_READY_MODE > mode);
+
+ if (MSS_UART_INVALID_READY_MODE > mode )
+ {
+ /* Configure mode 0 or mode 1 for TXRDY and RXRDY */
+ ((MSS_UART_READY_MODE0 == mode) ? (this_uart->hw_reg->FCR &= ~RDYMODE_MASK) :
+ (this_uart->hw_reg->FCR |= RDYMODE_MASK) );
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_usart_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_usart_mode_t mode
+)
+{
+ ASSERT(MSS_UART_INVALID_SYNC_MODE > mode);
+
+ if (MSS_UART_INVALID_SYNC_MODE > mode)
+ {
+ /* Nothing to do for the baudrate:
+ operates at PCLK / 2 + glitch filter length */
+ /* Clear the ESYN bits 2:0 */
+ this_uart->hw_reg->MM0 &= ~SYNC_ASYNC_MODE_MASK;
+ this_uart->hw_reg->MM0 |= (uint8_t)mode;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_local_irq
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Make sure to disable interrupt on PLIC as it might have been enabled
+ * when application registered an interrupt handler function or
+ * used MSS_UART_enable_irq() to enable PLIC interrupt */
+ disable_irq(this_uart);
+
+ this_uart->local_irq_enabled = 1u;
+
+ /* Enable local interrupt UART instance.
+ * Local interrupt will be enabled on the HART on which the application
+ * calling this API is being executed*/
+ __enable_local_irq((int8_t)MMUART0_E51_INT);
+}
+
+/*******************************************************************************
+ * Local Functions
+ ******************************************************************************/
+/*******************************************************************************
+ * Global initialization for all modes
+ */
+static void global_init
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ if ((&g_mss_uart0_lo == this_uart))
+ {
+ this_uart->hw_reg = MSS_UART0_LO_BASE;
+ g_uart_axi_pos &= ~0x01u;
+ }
+
+ else if (&g_mss_uart1_lo == this_uart)
+ {
+
+ this_uart->hw_reg = MSS_UART1_LO_BASE;
+ g_uart_axi_pos &= ~0x02u;
+ }
+
+ else if (&g_mss_uart2_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART2_LO_BASE;
+ g_uart_axi_pos &= ~0x04u;
+ }
+
+ else if (&g_mss_uart3_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART3_LO_BASE;
+ g_uart_axi_pos &= ~0x08u;
+ }
+
+ else if (&g_mss_uart4_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART4_LO_BASE;
+ g_uart_axi_pos &= ~0x10u;
+ }
+
+ else if ((&g_mss_uart0_hi == this_uart))
+ {
+ this_uart->hw_reg = MSS_UART0_HI_BASE;
+ g_uart_axi_pos |= 0x01u;
+ }
+
+ else if (&g_mss_uart1_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART1_HI_BASE;
+ g_uart_axi_pos |= 0x02u;
+ }
+
+ else if (&g_mss_uart2_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART2_HI_BASE;
+ g_uart_axi_pos |= 0x04u;
+ }
+
+ else if (&g_mss_uart3_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART3_HI_BASE;
+ g_uart_axi_pos |= 0x08u;
+ }
+
+ else if (&g_mss_uart4_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART4_HI_BASE;
+ g_uart_axi_pos |= 0x10u;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* disable interrupts */
+ this_uart->hw_reg->IER = 0u;
+
+ /* FIFO configuration */
+ this_uart->hw_reg->FCR = 0u;
+
+ /* clear receiver FIFO */
+ this_uart->hw_reg->FCR |= CLEAR_RX_FIFO_MASK;
+
+ /* clear transmitter FIFO */
+ this_uart->hw_reg->FCR |= CLEAR_TX_FIFO_MASK;
+
+ /* set default READY mode : Mode 0*/
+ /* enable RXRDYN and TXRDYN pins. The earlier FCR write to set the TX FIFO
+ * trigger level inadvertently disabled the FCR_RXRDY_TXRDYN_EN bit. */
+ this_uart->hw_reg->FCR |= RXRDY_TXRDYN_EN_MASK;
+
+ /* disable loopback : local * remote */
+ this_uart->hw_reg->MCR &= ~LOOP_MASK;
+
+ this_uart->hw_reg->MCR &= ~RLOOP_MASK;
+
+ /* set default TX endian */
+ this_uart->hw_reg->MM1 &= ~E_MSB_TX_MASK;
+
+ /* set default RX endian */
+ this_uart->hw_reg->MM1 &= ~E_MSB_RX_MASK;
+
+ /* default AFM : disabled */
+ this_uart->hw_reg->MM2 &= ~EAFM_MASK;
+
+ /* disable TX time guard */
+ this_uart->hw_reg->MM0 &= ~ETTG_MASK;
+
+ /* set default RX timeout */
+ this_uart->hw_reg->MM0 &= ~ERTO_MASK;
+
+ /* disable fractional baud-rate */
+ this_uart->hw_reg->MM0 &= ~EFBR_MASK;
+
+ /* disable single wire mode */
+ this_uart->hw_reg->MM2 &= ~ESWM_MASK;
+
+ /* set filter to minimum value */
+ this_uart->hw_reg->GFR = 0u;
+
+ /* set default TX time guard */
+ this_uart->hw_reg->TTG = 0u;
+
+ /* set default RX timeout */
+ this_uart->hw_reg->RTO = 0u;
+
+ /*
+ * Configure baud rate divisors. This uses the fractional baud rate divisor
+ * where possible to provide the most accurate baud rat possible.
+ */
+ config_baud_divisors(this_uart, baud_rate);
+
+ /* set the line control register (bit length, stop bits, parity) */
+ this_uart->hw_reg->LCR = line_config;
+
+ /* Instance setup */
+ this_uart->baudrate = baud_rate;
+ this_uart->lineconfig = line_config;
+ this_uart->tx_buff_size = TX_COMPLETE;
+ this_uart->tx_buffer = (const uint8_t*)0;
+ this_uart->tx_idx = 0u;
+
+ /* Default handlers for MSS UART interrupts */
+ this_uart->rx_handler = NULL_HANDLER;
+ this_uart->tx_handler = NULL_HANDLER;
+ this_uart->linests_handler = NULL_HANDLER;
+ this_uart->modemsts_handler = NULL_HANDLER;
+ this_uart->rto_handler = NULL_HANDLER;
+ this_uart->nack_handler = NULL_HANDLER;
+ this_uart->pid_pei_handler = NULL_HANDLER;
+ this_uart->break_handler = NULL_HANDLER;
+ this_uart->sync_handler = NULL_HANDLER;
+
+ this_uart->local_irq_enabled = 0u;
+
+ /* Initialize the sticky status */
+ this_uart->status = 0u;
+}
+
+/***************************************************************************//**
+ * Configure baud divisors using fractional baud rate if possible.
+ */
+static void
+config_baud_divisors
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baudrate
+)
+{
+ uint32_t baud_value;
+ uint32_t baud_value_by_64;
+ uint32_t baud_value_by_128;
+ uint32_t fractional_baud_value;
+ uint64_t pclk_freq;
+
+ this_uart->baudrate = baudrate;
+
+ pclk_freq = LIBERO_SETTING_MSS_APB_AHB_CLK;
+
+ /*
+ * Compute baud value based on requested baud rate and PCLK frequency.
+ * The baud value is computed using the following equation:
+ * baud_value = PCLK_Frequency / (baud_rate * 16)
+ */
+ baud_value_by_128 = (uint32_t)((8UL * pclk_freq) / baudrate);
+ baud_value_by_64 = baud_value_by_128 / 2u;
+ baud_value = baud_value_by_64 / 64u;
+ fractional_baud_value = baud_value_by_64 - (baud_value * 64u);
+ fractional_baud_value += (baud_value_by_128 - (baud_value * 128u))
+ - (fractional_baud_value * 2u);
+
+ /* Assert if integer baud value fits in 16-bit. */
+ ASSERT(baud_value <= UINT16_MAX);
+
+ if (baud_value <= (uint32_t)UINT16_MAX)
+ {
+ if (baud_value > 1u)
+ {
+ /* Use Fractional baud rate divisors */
+ /* set divisor latch */
+ this_uart->hw_reg->LCR |= DLAB_MASK;
+
+ /* MSB of baud value */
+ this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8);
+
+ /* LSB of baud value */
+ this_uart->hw_reg->DLR = (uint8_t)baud_value;
+
+ /* reset divisor latch */
+ this_uart->hw_reg->LCR &= ~DLAB_MASK;
+
+ /* Enable Fractional baud rate */
+ this_uart->hw_reg->MM0 |= EFBR_MASK;
+
+ /* Load the fractional baud rate register */
+ ASSERT(fractional_baud_value <= (uint32_t)UINT8_MAX);
+ this_uart->hw_reg->DFR = (uint8_t)fractional_baud_value;
+ }
+ else
+ {
+ /* Do NOT use Fractional baud rate divisors. */
+ /* set divisor latch */
+ this_uart->hw_reg->LCR |= DLAB_MASK;
+
+ /* MSB of baud value */
+ this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8u);
+
+ /* LSB of baud value */
+ this_uart->hw_reg->DLR = (uint8_t)baud_value;
+
+ /* reset divisor latch */
+ this_uart->hw_reg->LCR &= ~DLAB_MASK;
+
+ /* Disable Fractional baud rate */
+ this_uart->hw_reg->MM0 &= ~EFBR_MASK;
+ }
+ }
+}
+
+/***************************************************************************//**
+ * Interrupt service routine triggered by any MSS UART interrupt. This routine
+ * will call the handler function appropriate to the interrupt from the
+ * handlers previously registered with the driver through calls to the
+ * MSS_UART_set_*_handler() functions, or it will call the default_tx_handler()
+ * function in response to transmit interrupts if MSS_UART_irq_tx() is used to
+ * transmit data.
+ */
+static void
+uart_isr
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t iirf;
+
+ iirf = this_uart->hw_reg->IIR & IIRF_MASK;
+
+ switch (iirf)
+ {
+ case IIRF_MODEM_STATUS: /* Modem status interrupt */
+ {
+ ASSERT(NULL_HANDLER != this_uart->modemsts_handler);
+ if (NULL_HANDLER != this_uart->modemsts_handler)
+ {
+ (*(this_uart->modemsts_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_THRE: /* Transmitter Holding Register Empty */
+ {
+ ASSERT(NULL_HANDLER != this_uart->tx_handler);
+ if (NULL_HANDLER != this_uart->tx_handler)
+ {
+ (*(this_uart->tx_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_RX_DATA: /* Received Data Available */
+ case IIRF_DATA_TIMEOUT: /* Received Data Timed-out */
+ {
+ ASSERT(NULL_HANDLER != this_uart->rx_handler);
+ if (NULL_HANDLER != this_uart->rx_handler)
+ {
+ (*(this_uart->rx_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_RX_LINE_STATUS: /* Line Status Interrupt */
+ {
+ ASSERT(NULL_HANDLER != this_uart->linests_handler);
+ if (NULL_HANDLER != this_uart->linests_handler)
+ {
+ (*(this_uart->linests_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_MMI:
+ {
+ /* Identify multi-mode interrupts and handle */
+
+ /* Receiver time-out interrupt */
+ if (this_uart->hw_reg->IIM & ERTOI_MASK)
+ {
+ ASSERT(NULL_HANDLER != this_uart->rto_handler);
+
+ if (NULL_HANDLER != this_uart->rto_handler)
+ {
+ (*(this_uart->rto_handler))(this_uart);
+ }
+ }
+
+ /* NACK interrupt */
+ if (this_uart->hw_reg->IIM &ENACKI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->nack_handler);
+
+ if (NULL_HANDLER != this_uart->nack_handler)
+ {
+ (*(this_uart->nack_handler))(this_uart);
+ }
+ }
+
+ /* PID parity error interrupt */
+ if (this_uart->hw_reg->IIM & EPID_PEI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->pid_pei_handler);
+
+ if (NULL_HANDLER != this_uart->pid_pei_handler)
+ {
+ (*(this_uart->pid_pei_handler))(this_uart);
+ }
+ }
+
+ /* LIN break detection interrupt */
+ if (this_uart->hw_reg->IIM & ELINBI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->break_handler);
+
+ if (NULL_HANDLER != this_uart->break_handler)
+ {
+ (*(this_uart->break_handler))(this_uart);
+ }
+ }
+
+ /* LIN Sync detection interrupt */
+ if (this_uart->hw_reg->IIM & ELINSI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->sync_handler);
+
+ if (NULL_HANDLER != this_uart->sync_handler)
+ {
+ (*(this_uart->sync_handler))(this_uart);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ ASSERT(INVALID_INTERRUPT); /* Comment to avoid LDRA warning */
+ }
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+static void
+default_tx_handler
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status;
+
+ ASSERT(( (uint8_t*)0 ) != this_uart->tx_buffer);
+ ASSERT(0u < this_uart->tx_buff_size);
+
+ if ((((uint8_t*)0 ) != this_uart->tx_buffer) &&
+ (0u < this_uart->tx_buff_size))
+ {
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /*
+ * This function should only be called as a result of a THRE interrupt.
+ * Verify that this is true before proceeding to transmit data.
+ */
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t cnt;
+ uint32_t fill_size = TX_FIFO_SIZE;
+ uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;
+
+ /* Calculate the number of bytes to transmit. */
+ if (tx_remain < TX_FIFO_SIZE)
+ {
+ fill_size = tx_remain;
+ }
+
+ /* Fill the TX FIFO with the calculated the number of bytes. */
+ for (cnt = 0u; cnt < fill_size; ++cnt)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx];
+ ++this_uart->tx_idx;
+ }
+ }
+
+ /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */
+ if (this_uart->tx_idx == this_uart->tx_buff_size)
+ {
+ this_uart->tx_buff_size = TX_COMPLETE;
+
+ /* disables TX interrupt */
+ this_uart->hw_reg->IER &= ~ETBEI_MASK;
+ }
+ }
+}
+
+static void
+enable_irq
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ PLIC_IRQn_Type plic_num = 0;
+
+ if(0u == this_uart->local_irq_enabled)
+ {
+ if (((&g_mss_uart0_lo == this_uart)) || ((&g_mss_uart0_hi == this_uart)))
+ {
+ plic_num = MMUART0_PLIC_77;
+ }
+ else if (((&g_mss_uart1_lo == this_uart)) || ((&g_mss_uart1_hi == this_uart)))
+ {
+ plic_num = MMUART1_PLIC;
+ }
+ else if (((&g_mss_uart2_lo == this_uart)) || ((&g_mss_uart2_hi == this_uart)))
+ {
+ plic_num = MMUART2_PLIC;
+ }
+ else if (((&g_mss_uart3_lo == this_uart)) || ((&g_mss_uart3_hi == this_uart)))
+ {
+ plic_num = MMUART3_PLIC;
+ }
+ else if (((&g_mss_uart4_lo == this_uart)) || ((&g_mss_uart4_hi == this_uart)))
+ {
+ plic_num = MMUART4_PLIC;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* Enable UART instance interrupt in PLIC. */
+ PLIC_EnableIRQ(plic_num);
+ }
+}
+
+static void
+disable_irq
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ PLIC_IRQn_Type plic_num = 0;
+
+ if (((&g_mss_uart0_lo == this_uart)) || ((&g_mss_uart0_hi == this_uart)))
+ {
+ plic_num = MMUART0_PLIC_77;
+ }
+ else if (((&g_mss_uart1_lo == this_uart)) || ((&g_mss_uart1_hi == this_uart)))
+ {
+ plic_num = MMUART1_PLIC;
+ }
+ else if (((&g_mss_uart2_lo == this_uart)) || ((&g_mss_uart2_hi == this_uart)))
+ {
+ plic_num = MMUART2_PLIC;
+ }
+ else if (((&g_mss_uart3_lo == this_uart)) || ((&g_mss_uart3_hi == this_uart)))
+ {
+ plic_num = MMUART3_PLIC;
+ }
+ else if (((&g_mss_uart4_lo == this_uart)) || ((&g_mss_uart4_hi == this_uart)))
+ {
+ plic_num = MMUART4_PLIC;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* Disable UART instance interrupt in PLIC. */
+ PLIC_DisableIRQ(plic_num);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart.h
new file mode 100644
index 00000000..49e18448
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart.h
@@ -0,0 +1,3335 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver
+ * public API.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire SoC MSS UART Bare Metal Driver.
+
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor subsystem (MSS) includes five multi-mode UART
+ (MMUART) peripherals for serial communication. This driver provides a set of
+ functions for controlling the MSS MMUARTs as part of a bare metal system
+ where no operating system is available. These drivers can be adapted for use
+ as part of an operating system, but the implementation of the adaptation layer
+ between this driver and the operating system's driver model is outside the
+ scope of this driver.
+ Note: MSS UART is synonymous with MSS MMUART in this document.
+
+ ==============================================================================
+ Hardware Flow Dependencies
+ ==============================================================================
+ The configuration of all features of the MSS MMUART peripherals is covered by
+ this driver with the exception of the PolarFire SoC IOMUX configuration.
+ PolarFire SoC allows multiple non-concurrent uses of some external pins
+ through IOMUX configuration. This feature allows optimization of external pin
+ usage by assigning external pins for use by either the microprocessor
+ subsystem or the FPGA fabric. The MSS MMUART serial signals are routed through
+ IOMUXs to the PolarFire SoC device external pins. The MSS MMUART serial
+ signals may also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
+ For more information on IOMUX, refer to the I/O Configuration section of the
+ PolarFire SoC Microprocessor Subsystem (MSS) User's Guide.
+
+ The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
+ must ensure that the MSS MMUART peripherals are enabled and configured in the
+ PolarFire SoC MSS configurator if you wish to use them. For more information
+ on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
+ Subsystem (MSS) User's Guide.
+
+ On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
+ masters and multiple slaves. Five RISC-V CPUs connect to the Master ports
+ M10 to M14 of the AXI switch. By default, all the APB peripherals are
+ accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB
+ bridges (referred as main APB bus). However, to support logical separation in
+ the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals
+ can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to
+ APB bridges (referred as the AMP APB bus).
+
+ Application must make sure that the desired MMUART instance is appropriately
+ configured on one of the APB bus described above by configuring the PolarFire
+ SoC system registers (SYSREG) as per the application need and that the
+ appropriate data structures are provided to this driver as parameter to the
+ functions provided by this driver.
+
+ The base address and register addresses are defined in this driver as
+ constants. The interrupt number assignment for the MSS MMUART peripherals are
+ defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
+ is included in the project settings of the SoftConsole tool chain and that it
+ is generated into your project.
+
+ ==============================================================================
+ Theory of Operation
+ ==============================================================================
+ The MSS MMUART driver functions are grouped into the following categories:
+ - Initialization and configuration functions
+ - Polled transmit and receive functions
+ - Interrupt driven transmit and receive functions
+
+ --------------------------------
+ Initialization and Configuration
+ --------------------------------
+ The MSS MMUART supports the following four broad modes of operation:
+ - UART or USART mode
+ - LIN mode
+ - IrDA mode
+ - Smartcard or ISO 7816 mode
+
+ The MSS MMUART driver provides the MSS_UART_init(), MSS_UART_lin_init(),
+ MSS_UART_irda_init() and MSS_UART_smartcard_init() functions to initialize the
+ MSS MMUARTs for operation in one of these modes. One of these initialization
+ functions must be called before any other MSS MMUART driver functions can be
+ called. The MSS MMUART operating modes are mutually exclusive; therefore only
+ one of the initialization functions must be called. The first parameter of the
+ initialization functions is a pointer to one of ten global data structures
+ used to store state information for each MSS MMUART. A pointer to these data
+ structures is also used as the first parameter to many of the driver functions
+ to identify which MSS MMUART will be used by the called function. The names of
+ these data structures are:
+ - g_mss_uart0_lo
+ - g_mss_uart1_lo
+ - g_mss_uart2_lo
+ - g_mss_uart3_lo
+ - g_mss_uart4_lo
+ - g_mss_uart0_hi
+ - g_mss_uart1_hi
+ - g_mss_uart2_hi
+ - g_mss_uart3_hi
+ - g_mss_uart4_hi
+
+ Therefore, any call to an MSS MMUART function should be of the form
+ MSS_UART_function_name( &g_mss_uart0_lo, ... ) or
+ MSS_UART_function_name( &g_mss_uart1_hi, ... ).
+
+ UART or USART Mode
+ For the UART or USART modes of operation, the MSS MMUART driver is initialized
+ through a call to the MSS_UART_init() function. This function takes the UART's
+ configuration as its parameters. The MSS_UART_init() function must be called
+ before any other MSS MMUART driver functions can be called.
+ The MSS_UART_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the LIN, IrDA and SmartCard modes.
+
+ LIN mode
+ For the LIN mode of operation, the MSS MMUART driver is initialized through a
+ call to the MSS_UART_lin_init() function. This function takes the LIN node's
+ configuration as its parameters. The MSS_UART_lin_init() function must be
+ called before any other MSS MMUART driver functions can be called. The
+ MSS_UART_lin_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the IrDA and SmartCard modes.
+ The driver also provides the following LIN mode configuration functions:
+ - MSS_UART_set_break()
+ - MSS_UART_clear_break()
+ - MSS_UART_set_pidpei_handler()
+ - MSS_UART_set_linbreak_handler()
+ - MSS_UART_set_linsync_handler()
+
+ Note: These LIN mode configuration functions can only be called after the
+ MSS_UART_lin_init() function is called.
+
+ IrDA mode
+ For the IrDA mode of operation, the driver is initialized through a call to
+ the MSS_UART_irda_init() function. This function takes the IrDA node's
+ configuration as its parameters. The MSS_UART_irda_init() function must be
+ called before any other MSS MMUART driver functions can be called. The
+ MSS_UART_irda_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the LIN and SmartCard modes.
+
+ Smartcard or ISO 7816 mode
+ For the Smartcard or ISO 7816 mode of operation, the driver is initialized
+ through a call to the MSS_UART_smartcard_init() function. This function takes
+ the smartcard configuration as its parameters. The MSS_UART_smartcard_init()
+ function must be called before any other MSS MMUART driver functions can be
+ called. The MSS_UART_smartcard_init() function configures the baud rate based
+ on the input baud rate parameter and if possible uses a fractional baud rate
+ for greater precision. This function disables the LIN and IrDA modes.
+ The driver also provides the following Smartcard mode configuration functions:
+ - MSS_UART_enable_halfduplex()
+ - MSS_UART_disable_halfduplex()
+ - MSS_UART_set_nack_handler()
+
+ Note: These Smartcard mode configuration functions can only be called after
+ the MSS_UART_smartcard_init() function is called.
+
+ Common Configuration Functions
+ The driver also provides the configuration functions that can be used with all
+ MSS MMUART operating modes. These common configuration functions are as
+ follows:
+ - MSS_UART_set_rx_endian()
+ - MSS_UART_set_tx_endian()
+ - MSS_UART_enable_afclear()
+ - MSS_UART_disable_afclear()
+ - MSS_UART_enable_rx_timeout()
+ - MSS_UART_disable_rx_timeout()
+ - MSS_UART_enable_tx_time_guard()
+ - MSS_UART_disable_tx_time_guard()
+ - MSS_UART_set_address()
+ - MSS_UART_set_ready_mode()
+ - MSS_UART_set_usart_mode()
+ - MSS_UART_set_filter_length()
+ - MSS_UART_enable_afm()
+ - MSS_UART_disable_afm()
+
+ Note: These configuration functions can only be called after one of the
+ MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init() or
+ MSS_UART_smartcard_init() functions is called.
+
+ --------------------------------------
+ Polled Transmit and Receive Operations
+ --------------------------------------
+ The driver can be used to transmit and receive data once initialized.
+ Data is transmitted using the MSS_UART_polled_tx() function. This function is
+ blocking, meaning that it will only return once the data passed to the
+ function has been sent to the MSS MMUART hardware transmitter. Data received
+ by the MSS MMUART hardware receiver can be read by the MSS_UART_get_rx()
+ function.
+ The MSS_UART_polled_tx_string() function is provided to transmit a NUL ('\0')
+ terminated string in polled mode. This function is blocking, meaning that it
+ will only return once the data passed to the function has been sent to the MSS
+ MMUART hardware transmitter.
+ The MSS_UART_fill_tx_fifo() function fills the MSS MMUART hardware transmit
+ FIFO with data from a buffer passed as a parameter and returns the number of
+ bytes transferred to the FIFO. If the transmit FIFO is not empty when the
+ MSS_UART_fill_tx_fifo() function is called it returns immediately without
+ transferring any data to the FIFO.
+
+ ---------------------------
+ Interrupt Driven Operations
+ ---------------------------
+ The driver can also transmit or receive data under interrupt control, freeing
+ your application to perform other tasks until an interrupt occurs indicating
+ that the driver's attention is required.
+
+ Local or PLIC interrupt:
+ PolarFire SoC architecture provides flexibility in terms of how the MMUART
+ interrupt is seen by the PolarFire SoC Core Complex. Each of the 5 MMUART
+ instance interrupt line is connected to the PolarFire SoC Core Complex PLIC.
+ The MMUART0 instance interrupt line is also available as local interrupt on
+ E51 processor. The MMUART1 instance interrupt onwards are available as local
+ interrupt on the U54_1 processor onwards. e.g. MMUART2 interrupt is available
+ as local interrupt on U54_2.
+
+ Interrupt Handlers
+ The MSS MMUART driver supports all types of interrupt triggered by the MSS
+ MMUART. The driver's internal top level interrupt handler identifies the
+ source of the MSS MMUART interrupt and calls the corresponding lower level
+ handler function that you previously registered with the driver through calls
+ to the MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(),
+ MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler()
+ functions. You are responsible for creating these lower level interrupt
+ handlers as part of your application program and registering them with the
+ driver.
+ Note: The PolarFire SoC HAL defines the interrupt handler functions for all
+ 5 MMUART instances(with weak linkage) and assigns them as the interrupt
+ service routines (ISR) for the MSS MMUART interrupt inputs to the
+ PolarFire SoC Core Complex PLIC or the Local interrupts on each of the
+ respective CPUs. The MSS MMUART driver provides the implementation
+ functions all these ISRs from which it calls its own internal top level,
+ interrupt handler function.
+
+ The MSS_UART_enable_irq() and MSS_UART_disable_irq() functions are used to
+ enable or disable the received line status, received data available/character
+ time-out, transmit holding register empty and modem status interrupts at the
+ MSS MMUART level. The MSS_UART_enable_irq() function also enables the MSS
+ MMUART instance interrupt at the PolarFire SoC Core Complex level.
+
+ Note that the MSS_UART_enable_irq() and MSS_UART_disable_irq() and all the
+ calls to set the handler functions assume that the MMUART interrupt is
+ connected to the PolarFire SoC Core Complex PLIC. If you want the MMUART
+ interrupt to appear as a local interrupt to the corresponding HART then you
+ must explicitly call the MSS_UART_enable_local_irq() function. This function
+ will disable the PLIC interrupt (if it was previously enable) and enable the
+ local interrupt on the HART on which this function is being executed.
+
+ Transmitting Data
+ Interrupt-driven transmit is initiated by a call to MSS_UART_irq_tx(),
+ specifying the block of data to transmit. Your application is then free to
+ perform other tasks and inquire later whether transmit has completed by
+ calling the MSS_UART_tx_complete() function. The MSS_UART_irq_tx() function
+ enables the UART's transmit holding register empty (THRE) interrupt and then,
+ when the interrupt goes active, the driver's default THRE interrupt handler
+ transfers the data block to the UART until the entire block is transmitted.
+ Note: You can use the MSS_UART_set_tx_handler() function to assign an
+ alternative handler to the THRE interrupt. In this case, you must not
+ use the MSS_UART_irq_tx() function to initiate the transmit, as this
+ will re-assign the driver's default THRE interrupt handler to the THRE
+ interrupt. Instead, your alternative THRE interrupt handler must include
+ a call to the MSS_UART_fill_tx_fifo() function to transfer the data to
+ the UART.
+
+ Receiving Data
+ Interrupt-driven receive is performed by first calling
+ MSS_UART_set_rx_handler() to register a receive handler function that will be
+ called by the driver whenever receive data is available. You must provide this
+ receive handler function which must include a call to the MSS_UART_get_rx()
+ function to actually read the received data.
+
+ -----------
+ UART Status
+ -----------
+ The function MSS_UART_get_rx_status() is used to read the receiver error
+ status. This function returns the overrun, parity, framing, break, and FIFO
+ error status of the receiver.
+ The function MSS_UART_get_tx_status() is used to read the transmitter status.
+ This function returns the transmit empty (TEMT) and transmit holding register
+ empty (THRE) status of the transmitter.
+ The function MSS_UART_get_modem_status() is used to read the modem status
+ flags. This function returns the current value of the modem status register.
+
+ --------
+ Loopback
+ --------
+ The MSS_UART_set_loopback() function can be used to locally loopback the Tx
+ and Rx lines of a UART. This is not to be confused with the loopback of UART0
+ to UART1, which can be achieved through the microprocessor subsystem's system
+ registers.
+
+ *//*=========================================================================*/
+#ifndef __MSS_UART_H_
+#define __MSS_UART_H_ 1
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************************************************************//**
+ Baud rates
+ ==========
+ The following definitions are used to specify standard baud rates as a
+ parameter to the MSS_UART_init() function.
+
+ | Constant | Description |
+ |----------------------|------------------|
+ | MSS_UART_110_BAUD | 110 baud rate |
+ | MSS_UART_300_BAUD | 300 baud rate |
+ | MSS_UART_600_BAUD | 600 baud rate |
+ | MSS_UART_1200_BAUD | 1200 baud rate |
+ | MSS_UART_2400_BAUD | 2400 baud rate |
+ | MSS_UART_4800_BAUD | 4800 baud rate |
+ | MSS_UART_9600_BAUD | 9600 baud rate |
+ | MSS_UART_19200_BAUD | 19200 baud rate |
+ | MSS_UART_38400_BAUD | 38400 baud rate |
+ | MSS_UART_57600_BAUD | 57600 baud rate |
+ | MSS_UART_115200_BAUD | 115200 baud rate |
+ | MSS_UART_230400_BAUD | 230400 baud rate |
+ | MSS_UART_460800_BAUD | 460800 baud rate |
+ | MSS_UART_921600_BAUD | 921600 baud rate |
+
+ */
+#define MSS_UART_110_BAUD 110U
+#define MSS_UART_300_BAUD 300U
+#define MSS_UART_600_BAUD 600U
+#define MSS_UART_1200_BAUD 1200U
+#define MSS_UART_2400_BAUD 2400U
+#define MSS_UART_4800_BAUD 4800U
+#define MSS_UART_9600_BAUD 9600U
+#define MSS_UART_19200_BAUD 19200U
+#define MSS_UART_38400_BAUD 38400U
+#define MSS_UART_57600_BAUD 57600U
+#define MSS_UART_115200_BAUD 115200U
+#define MSS_UART_230400_BAUD 230400U
+#define MSS_UART_460800_BAUD 460800U
+#define MSS_UART_921600_BAUD 921600U
+
+/***************************************************************************//**
+ Data Bits Length
+ ================
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |----------------------|----------------------------|
+ | MSS_UART_DATA_5_BITS | 5 bits of data transmitted |
+ | MSS_UART_DATA_6_BITS | 6 bits of data transmitted |
+ | MSS_UART_DATA_7_BITS | 7 bits of data transmitted |
+ | MSS_UART_DATA_8_BITS | 8 bits of data transmitted |
+
+ */
+#define MSS_UART_DATA_5_BITS ((uint8_t) 0x00)
+#define MSS_UART_DATA_6_BITS ((uint8_t) 0x01)
+#define MSS_UART_DATA_7_BITS ((uint8_t) 0x02)
+#define MSS_UART_DATA_8_BITS ((uint8_t) 0x03)
+
+/***************************************************************************//**
+ Parity
+ ======
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |-------------------------|--------------------------|
+ | MSS_UART_NO_PARITY | No parity |
+ | MSS_UART_ODD_PARITY | Odd Parity |
+ | MSS_UART_EVEN_PARITY | Even parity |
+ | MSS_UART_STICK_PARITY_0 | Stick parity bit to zero |
+ | MSS_UART_STICK_PARITY_1 | Stick parity bit to one |
+
+ */
+#define MSS_UART_NO_PARITY ((uint8_t) 0x00)
+#define MSS_UART_ODD_PARITY ((uint8_t) 0x08)
+#define MSS_UART_EVEN_PARITY ((uint8_t) 0x18)
+#define MSS_UART_STICK_PARITY_0 ((uint8_t) 0x38)
+#define MSS_UART_STICK_PARITY_1 ((uint8_t) 0x28)
+
+/***************************************************************************//**
+ Number of Stop Bits
+ ===================
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |---------------------------|--------------------------|
+ | MSS_UART_ONE_STOP_BIT | One stop bit |
+ | MSS_UART_ONEHALF_STOP_BIT | One and a half stop bits |
+ | MSS_UART_TWO_STOP_BITS | Two stop bits |
+
+ */
+#define MSS_UART_ONE_STOP_BIT ((uint8_t) 0x00)
+#define MSS_UART_ONEHALF_STOP_BIT ((uint8_t) 0x04)
+#define MSS_UART_TWO_STOP_BITS ((uint8_t) 0x04)
+
+/***************************************************************************//**
+ Receiver Error Status
+ =====================
+ The following defines are used to determine the UART receiver error type.
+ These bit mask constants are used with the return value of the
+ MSS_UART_get_rx_status() function to find out if any errors occurred while
+ receiving data.
+
+
+ | Constant | Description |
+ |------------------------|--------------------------------------------|
+ | MSS_UART_NO_ERROR | No error bit mask (0x00) |
+ | MSS_UART_OVERUN_ERROR | Overrun error bit mask (0x02) |
+ | MSS_UART_PARITY_ERROR | Parity error bit mask (0x04) |
+ | MSS_UART_FRAMING_ERROR | Framing error bit mask (0x08) |
+ | MSS_UART_BREAK_ERROR | Break error bit mask (0x10) |
+ | MSS_UART_FIFO_ERROR | FIFO error bit mask (0x80) |
+ | MSS_UART_INVALID_PARAM | Invalid function parameter bit mask (0xFF) |
+
+ */
+#define MSS_UART_INVALID_PARAM ((uint8_t)0xFF)
+#define MSS_UART_NO_ERROR ((uint8_t)0x00 )
+#define MSS_UART_OVERUN_ERROR ((uint8_t)0x02)
+#define MSS_UART_PARITY_ERROR ((uint8_t)0x04)
+#define MSS_UART_FRAMING_ERROR ((uint8_t)0x08)
+#define MSS_UART_BREAK_ERROR ((uint8_t)0x10)
+#define MSS_UART_FIFO_ERROR ((uint8_t)0x80)
+
+/***************************************************************************//**
+ Transmitter Status
+ ==================
+ The following definitions are used to determine the UART transmitter status.
+ These bit mask constants are used with the return value of the
+ MSS_UART_get_tx_status() function to find out the status of the transmitter.
+
+ | Constant | Description |
+ |------------------|----------------------------------------------------|
+ | MSS_UART_TX_BUSY | Transmitter busy (0x00) |
+ | MSS_UART_THRE | Transmitter holding register empty bit mask (0x20) |
+ | MSS_UART_TEMT | Transmitter empty bit mask (0x40) |
+
+ */
+#define MSS_UART_TX_BUSY ((uint8_t) 0x00)
+#define MSS_UART_THRE ((uint8_t) 0x20)
+#define MSS_UART_TEMT ((uint8_t) 0x40)
+
+/***************************************************************************//**
+ Modem Status
+ ============
+ The following defines are used to determine the modem status. These bit
+ mask constants are used with the return value of the
+ MSS_UART_get_modem_status() function to find out the modem status of
+ the UART.
+
+ | Constant | Description |
+ |---------------|-------------------------------------------------|
+ | MSS_UART_DCTS | Delta clear to send bit mask (0x01) |
+ | MSS_UART_DDSR | Delta data set ready bit mask (0x02) |
+ | MSS_UART_TERI | Trailing edge of ring indicator bit mask (0x04) |
+ | MSS_UART_DDCD | Delta data carrier detect bit mask (0x08) |
+ | MSS_UART_CTS | Clear to send bit mask (0x10) |
+ | MSS_UART_DSR | Data set ready bit mask (0x20) |
+ | MSS_UART_RI | Ring indicator bit mask (0x40) |
+ | MSS_UART_DCD | Data carrier detect bit mask (0x80) |
+
+ */
+#define MSS_UART_DCTS ((uint8_t) 0x01)
+#define MSS_UART_DDSR ((uint8_t) 0x02)
+#define MSS_UART_TERI ((uint8_t) 0x04)
+#define MSS_UART_DDCD ((uint8_t) 0x08)
+#define MSS_UART_CTS ((uint8_t) 0x10)
+#define MSS_UART_DSR ((uint8_t) 0x20)
+#define MSS_UART_RI ((uint8_t) 0x40)
+#define MSS_UART_DCD ((uint8_t) 0x80)
+
+/***************************************************************************//**
+ This typedef specifies the irq_mask parameter for the MSS_UART_enable_irq()
+ and MSS_UART_disable_irq() functions. The driver defines a set of bit masks
+ that are used to build the value of the irq_mask parameter. A bitwise OR of
+ these bit masks is used to enable or disable multiple MSS MMUART interrupts.
+ */
+typedef uint16_t mss_uart_irq_t;
+
+/***************************************************************************//**
+ MSS MMUART Interrupts
+ =====================
+ The following defines specify the interrupt masks to enable and disable MSS
+ MMUART interrupts. They are used to build the value of the irq_mask parameter
+ for the MSS_UART_enable_irq() and MSS_UART_disable_irq() functions. A bitwise
+ OR of these constants is used to enable or disable multiple interrupts.
+
+
+ | Constant | Description |
+ |--------------------|---------------------------------------------------------------|
+ | MSS_UART_RBF_IRQ | Receive Data Available Interrupt bit mask (0x001) |
+ | MSS_UART_TBE_IRQ | Transmitter Holding Register Empty interrupt bit mask (0x002) |
+ | MSS_UART_LS_IRQ | Receiver Line Status interrupt bit mask (0x004) |
+ | MSS_UART_MS_IRQ | Modem Status interrupt bit mask (0x008) |
+ | MSS_UART_RTO_IRQ | Receiver time-out interrupt bit mask (0x010) |
+ | MSS_UART_NACK_IRQ | NACK / ERR signal interrupt bit mask (0x020) |
+ | MSS_UART_PIDPE_IRQ | PID parity error interrupt bit mask (0x040) |
+ | MSS_UART_LINB_IRQ | LIN break detection interrupt bit mask (0x080) |
+ | MSS_UART_LINS_IRQ | LIN Sync detection interrupt bit mask (0x100) |
+
+ */
+#define MSS_UART_RBF_IRQ 0x001
+#define MSS_UART_TBE_IRQ 0x002
+#define MSS_UART_LS_IRQ 0x004
+#define MSS_UART_MS_IRQ 0x008
+#define MSS_UART_RTO_IRQ 0x010
+#define MSS_UART_NACK_IRQ 0x020
+#define MSS_UART_PIDPE_IRQ 0x040
+#define MSS_UART_LINB_IRQ 0x080
+#define MSS_UART_LINS_IRQ 0x100
+#define MSS_UART_INVALID_IRQ UINT16_MAX
+
+/***************************************************************************//**
+ This enumeration specifies the receiver FIFO trigger level. This is the number
+ of bytes that must be received before the UART generates a receive data
+ available interrupt. It provides the allowed values for the
+ MSS_UART_set_rx_handler() function trigger_level parameter.
+ */
+typedef enum {
+ MSS_UART_FIFO_SINGLE_BYTE = 0x00,
+ MSS_UART_FIFO_FOUR_BYTES = 0x40,
+ MSS_UART_FIFO_EIGHT_BYTES = 0x80,
+ MSS_UART_FIFO_FOURTEEN_BYTES = 0xC0,
+ MSS_UART_FIFO_INVALID_TRIG_LEVEL
+
+} mss_uart_rx_trig_level_t;
+
+/***************************************************************************//**
+ This enumeration specifies the loopback configuration of the UART. It provides
+ the allowed values for the MSS_UART_set_loopback() function's loopback
+ parameter. Use MSS_UART_LOCAL_LOOPBACK_ON to set up the UART to locally
+ loopback its Tx and Rx lines. Use MSS_UART_REMOTE_LOOPBACK_ON to set up the
+ UART in remote loopback mode.
+ */
+typedef enum {
+ MSS_UART_LOCAL_LOOPBACK_OFF,
+ MSS_UART_LOCAL_LOOPBACK_ON,
+ MSS_UART_REMOTE_LOOPBACK_OFF,
+ MSS_UART_REMOTE_LOOPBACK_ON,
+ MSS_UART_AUTO_ECHO_OFF,
+ MSS_UART_AUTO_ECHO_ON,
+ MSS_UART_INVALID_LOOPBACK
+
+} mss_uart_loopback_t;
+
+/***************************************************************************//**
+ IrDA input / output polarity.
+ This enumeration specifies the RZI modem polarity for input and output signals.
+ This is passed as parameters in MSS_UART_irda_init() function.
+ */
+typedef enum {
+ MSS_UART_ACTIVE_LOW = 0u,
+ MSS_UART_ACTIVE_HIGH = 1u,
+ MSS_UART_INVALID_POLARITY
+
+} mss_uart_rzi_polarity_t;
+
+/***************************************************************************//**
+ IrDA input / output pulse width.
+ This enumeration specifies the RZI modem pulse width for input and output
+ signals. This is passed as parameters in MSS_UART_irda_init() function.
+ */
+typedef enum {
+ MSS_UART_3_BY_16 = 0u,
+ MSS_UART_1_BY_4 = 1u,
+ MSS_UART_INVALID_PW
+
+} mss_uart_rzi_pulsewidth_t;
+
+/***************************************************************************//**
+ Tx / Rx endianess.
+ This enumeration specifies the MSB first or LSB first for MSS UART transmitter
+ and receiver. The parameter of this type shall be passed in
+ MSS_UART_set_rx_endian()and MSS_UART_set_tx_endian() functions.
+ */
+typedef enum {
+ MSS_UART_LITTLEEND,
+ MSS_UART_BIGEND,
+ MSS_UART_INVALID_ENDIAN
+
+} mss_uart_endian_t;
+
+/***************************************************************************//**
+ Glitch filter length.
+ This enumeration specifies the glitch filter length. The function
+ MSS_UART_set_filter_length() accepts the parameter of this type.
+ */
+typedef enum {
+ MSS_UART_LEN0 = 0,
+ MSS_UART_LEN1 = 1,
+ MSS_UART_LEN2 = 2,
+ MSS_UART_LEN3 = 3,
+ MSS_UART_LEN4 = 4,
+ MSS_UART_LEN5 = 5,
+ MSS_UART_LEN6 = 6,
+ MSS_UART_LEN7 = 7,
+ MSS_UART_INVALID_FILTER_LENGTH = 8
+
+} mss_uart_filter_length_t;
+
+/***************************************************************************//**
+ TXRDY and RXRDY mode.
+ This enumeration specifies the TXRDY and RXRDY signal modes. The function
+ MSS_UART_set_ready_mode() accepts the parameter of this type.
+ */
+typedef enum {
+ MSS_UART_READY_MODE0,
+ MSS_UART_READY_MODE1,
+ MSS_UART_INVALID_READY_MODE
+
+} mss_uart_ready_mode_t;
+
+/***************************************************************************//**
+ USART mode of operation.
+ This enumeration specifies the mode of operation of MSS UART when operating
+ as USART. The function MSS_UART_set_usart_mode() accepts the parameter of this
+ type.
+ */
+typedef enum {
+ MSS_UART_ASYNC_MODE = 0,
+ MSS_UART_SYNC_SLAVE_POS_EDGE_CLK = 1,
+ MSS_UART_SYNC_SLAVE_NEG_EDGE_CLK = 2,
+ MSS_UART_SYNC_MASTER_POS_EDGE_CLK = 3,
+ MSS_UART_SYNC_MASTER_NEG_EDGE_CLK = 4,
+ MSS_UART_INVALID_SYNC_MODE = 5
+
+} mss_uart_usart_mode_t;
+
+
+typedef enum {
+ MSS_UART0_LO = 0,
+ MSS_UART1_LO = 1,
+ MSS_UART2_LO = 2,
+ MSS_UART3_LO = 3,
+ MSS_UART4_LO = 4,
+ MSS_UART0_HI = 5,
+ MSS_UART1_HI = 6,
+ MSS_UART2_HI = 7,
+ MSS_UART3_HI = 8,
+ MSS_UAR4_HI = 9,
+
+} mss_uart_num_t;
+
+/***************************************************************************//**
+ MSS UART instance type.
+ This is type definition for MSS UART instance. You need to create and
+ maintain a record of this type. This holds all data regarding the MSS UART
+ instance
+ */
+typedef struct mss_uart_instance mss_uart_instance_t;
+
+/***************************************************************************//**
+ Interrupt handler prototype.
+ This typedef specifies the function prototype for MSS UART interrupt handlers.
+ All interrupt handlers registered with the MSS UART driver must be of this type.
+ The interrupt handlers are registered with the driver through the
+ MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(),
+ MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler()
+ functions.
+ The this_uart parameter is a pointer to either g_mss_uart0 or g_mss_uart1 to
+ identify the MSS UART to associate with the handler function.
+ */
+typedef void (*mss_uart_irq_handler_t)( mss_uart_instance_t * this_uart );
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------- UART -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+typedef struct
+{
+ union
+ {
+ volatile const uint8_t RBR;
+ volatile uint8_t THR;
+ volatile uint8_t DLR;
+ uint32_t RESERVED0;
+ };
+
+ union
+ {
+ volatile uint8_t DMR;
+ volatile uint8_t IER;
+ uint32_t RESERVED1;
+ };
+
+ union
+ {
+ volatile uint8_t IIR;
+ volatile uint8_t FCR;
+ uint32_t RESERVED2;
+ };
+
+ volatile uint8_t LCR;
+ uint8_t RESERVED3[3];
+
+ volatile uint8_t MCR;
+ uint8_t RESERVED4[3];
+
+ volatile const uint8_t LSR;
+ uint8_t RESERVED5[3];
+
+ volatile const uint8_t MSR;
+ uint8_t RESERVED6[3];
+
+ volatile uint8_t SR;
+ uint8_t RESERVED7[7];
+
+ volatile uint8_t IEM;
+ uint8_t RESERVED8[3];
+
+ volatile uint8_t IIM;
+ uint8_t RESERVED9[7];
+
+ volatile uint8_t MM0;
+ uint8_t RESERVED10[3];
+
+ volatile uint8_t MM1;
+ uint8_t RESERVED11[3];
+
+ volatile uint8_t MM2;
+ uint8_t RESERVED12[3];
+
+ volatile uint8_t DFR;
+ uint8_t RESERVED13[7];
+
+ volatile uint8_t GFR;
+ uint8_t RESERVED14[3];
+
+ volatile uint8_t TTG;
+ uint8_t RESERVED15[3];
+
+ volatile uint8_t RTO;
+ uint8_t RESERVED16[3];
+
+ volatile uint8_t ADR;
+ uint8_t RESERVED17[3];
+
+} MSS_UART_TypeDef;
+
+
+/***************************************************************************//**
+ mss_uart_instance.
+ There is one instance of this structure for each instance of the
+ microprocessor subsystem's UARTs. Instances of this structure are used to
+ identify a specific UART. A pointer to an initialized instance of the
+ mss_uart_instance_t structure is passed as the first parameter to
+ MSS UART driver functions to identify which UART should perform the
+ requested operation.
+ */
+struct mss_uart_instance{
+ /* CMSIS related defines identifying the UART hardware. */
+ MSS_UART_TypeDef * hw_reg; /*!< Pointer to UART registers. */
+ uint32_t baudrate; /*!< Operating baud rate. */
+ uint8_t lineconfig; /*!< Line configuration parameters. */
+ uint8_t status; /*!< Sticky line status. */
+
+ /* transmit related info (used with interrupt driven transmit): */
+ const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */
+ uint32_t tx_buff_size; /*!< Transmit buffer size. */
+ uint32_t tx_idx; /*!< Index within transmit buffer of next byte to transmit.*/
+
+ /* line status interrupt handler:*/
+ mss_uart_irq_handler_t linests_handler; /*!< Pointer to user registered line status handler. */
+ /* receive interrupt handler:*/
+ mss_uart_irq_handler_t rx_handler; /*!< Pointer to user registered receiver handler. */
+ /* transmit interrupt handler:*/
+ mss_uart_irq_handler_t tx_handler; /*!< Pointer to user registered transmit handler. */
+ /* modem status interrupt handler:*/
+ mss_uart_irq_handler_t modemsts_handler; /*!< Pointer to user registered modem status handler. */
+ /* receiver timeout interrupt handler */
+ mss_uart_irq_handler_t rto_handler; /*!< Pointer to user registered receiver timeout handler. */
+ /* NACK interrupt handler */
+ mss_uart_irq_handler_t nack_handler; /*!< Pointer to user registered NACK handler. */
+ /* PID parity perror interrupt handler */
+ mss_uart_irq_handler_t pid_pei_handler; /*!< Pointer to user registered PID parity error handler. */
+ /* LIN break interrupt handler */
+ mss_uart_irq_handler_t break_handler; /*!< Pointer to user registered LIN break handler. */
+ /* LIN sync detection interrupt handler */
+ mss_uart_irq_handler_t sync_handler; /*!< Pointer to user registered LIN sync detection handler. */
+ uint8_t local_irq_enabled; /*!< check if local interrupt were enabled on this instance*/
+ void* user_data; /*!< Pointer to user provided pointer for user specific use. */
+
+};
+
+/***************************************************************************//**
+ This instance of mss_uart_instance_t holds all data related to the operations
+ performed by the MMUART. The function MSS_UART_init() initializes this structure.
+ A pointer to g_mss_uart0_lo is passed as the first parameter to MSS UART driver
+ functions to indicate that MMUART0 should perform the requested operation.
+ */
+
+extern mss_uart_instance_t g_mss_uart0_lo;
+extern mss_uart_instance_t g_mss_uart1_lo;
+extern mss_uart_instance_t g_mss_uart2_lo;
+extern mss_uart_instance_t g_mss_uart3_lo;
+extern mss_uart_instance_t g_mss_uart4_lo;
+
+extern mss_uart_instance_t g_mss_uart0_hi;
+extern mss_uart_instance_t g_mss_uart1_hi;
+extern mss_uart_instance_t g_mss_uart2_hi;
+extern mss_uart_instance_t g_mss_uart3_hi;
+extern mss_uart_instance_t g_mss_uart4_hi;
+
+
+/***************************************************************************//**
+ The MSS_UART_init() function initializes and configures one of the PolarFire SoC
+ MSS UARTs with the configuration passed as a parameter. The configuration
+ parameters are the baud_rate which is used to generate the baud value and the
+ line_config which is used to specify the line configuration (bit length,
+ stop bits and parity).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit length,
+ number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The MSS_UART_lin_init() function is used to initialize the MSS UART for
+ LIN mode of operation. The configuration parameters are the baud_rate which is
+ used to generate the baud value and the line_config which is used to specify
+ the line configuration (bit length, stop bits and parity).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit length,
+ number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_lin_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The MSS_UART_irda_init() function is used to initialize the MSS UART instance
+ referenced by the parameter this_uart for IrDA mode of operation. This
+ function must be called before calling any other IrDA functionality specific
+ functions.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit
+ length, number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_irda_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT,
+ MSS_UART_ACTIVE_LOW,
+ MSS_UART_ACTIVE_LOW,
+ MSS_UART_3_BY_16);
+ @endcode
+ */
+void
+MSS_UART_irda_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config,
+ mss_uart_rzi_polarity_t rxpol,
+ mss_uart_rzi_polarity_t txpol,
+ mss_uart_rzi_pulsewidth_t pw
+);
+
+/***************************************************************************//**
+ The MSS_UART_smartcard_init() function is used to initialize the MSS UART
+ for ISO 7816 (smartcard) mode of operation. The configuration parameters are
+ the baud_rate which is used to generate the baud value and the line_config
+ which is used to specify the line configuration (bit length, stop bits and
+ parity). This function disables all other modes of the MSS UART instance
+ pointed by the parameter this_uart.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit
+ length, number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_smartcard_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_smartcard_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The function MSS_UART_polled_tx() is used to transmit data. It transfers the
+ contents of the transmitter data buffer, passed as a function parameter, into
+ the UART's hardware transmitter FIFO. It returns when the full content of the
+ transmit data buffer has been transferred to the UART's transmit FIFO. It is
+ safe to release or reuse the memory used as the transmitter data buffer once
+ this function returns.
+
+ Note: This function reads the UART's line status register (LSR) to poll
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. It
+ transfers data to the transmitter FIFO in blocks of 16 bytes or less and
+ allows the FIFO to empty before transferring the next block of data.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param pbuff
+ The pbuff parameter is a pointer to a buffer containing the data to
+ be transmitted.
+
+ @param tx_size
+ The tx_size parameter specifies the size, in bytes, of the data to
+ be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello World";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ SS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx(&g_mss_uart0_lo, message, sizeof(message));
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_polled_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+
+/***************************************************************************//**
+ The function MSS_UART_polled_tx_string() is used to transmit a NUL ('\0')
+ terminated string. It transfers the text string, from the buffer starting at
+ the address pointed to by p_sz_string into the UART's hardware transmitter
+ FIFO. It returns when the complete string has been transferred to the UART's
+ transmit FIFO. It is safe to release or reuse the memory used as the string
+ buffer once this function returns.
+
+ Note: This function reads the UART's line status register (LSR) to poll
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. It
+ transfers data to the transmitter FIFO in blocks of 16 bytes or less and
+ allows the FIFO to empty before transferring the next block of data.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param p_sz_string
+ The p_sz_string parameter is a pointer to a buffer containing the NUL ('\0')
+ terminated string to be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello World";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx_string(&g_mss_uart0_lo, message);
+
+ return(0);
+ }
+ @endcode
+
+ */
+void
+MSS_UART_polled_tx_string
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * p_sz_string
+);
+
+/***************************************************************************//**
+ The function MSS_UART_irq_tx() is used to initiate an interrupt-driven
+ transmit. It returns immediately after making a note of the transmit buffer
+ location and enabling transmit interrupts both at the UART and the PolarFire
+ SoC Core Complex PLIC level. This function takes a pointer via the pbuff
+ parameter to a memory buffer containing the data to transmit. The memory
+ buffer specified through this pointer must remain allocated and contain the
+ data to transmit until the transmit completion has been detected through calls
+ to function MSS_UART_tx_complete(). The actual transmission over the serial
+ connection is still in progress until calls to the MSS_UART_tx_complete()
+ function indicate transmit completion.
+
+ Note: The MSS_UART_irq_tx() function enables both the transmit holding
+ register empty (THRE) interrupt in the UART and the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC as part of its implementation.
+
+ Note: The MSS_UART_irq_tx() function assigns an internal default transmit
+ interrupt handler function to the UART's THRE interrupt. This interrupt
+ handler overrides any custom interrupt handler that you may have previously
+ registered using the MSS_UART_set_tx_handler() function.
+
+ Note: The MSS_UART_irq_tx() function's default transmit interrupt
+ handler disables the UART's THRE interrupt when all of the data has
+ been transferred to the UART's transmit FIFO.
+
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param pbuff
+ The pbuff parameter is a pointer to a buffer containing the data
+ to be transmitted.
+
+ @param tx_size
+ The tx_size parameter specifies the size, in bytes, of the data
+ to be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_irq_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff));
+
+ while(0 == MSS_UART_tx_complete(&g_mss_uart0_lo))
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_irq_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_tx_complete() function is used to find out if the
+ interrupt-driven transmit previously initiated through a call to
+ MSS_UART_irq_tx() is complete. This is typically used to find out when it is
+ safe to reuse or release the memory buffer holding transmit data.
+
+ Note: The transfer of all of the data from the memory buffer to the UART's
+ transmit FIFO and the actual transmission over the serial connection are both
+ complete when a call to the MSS_UART_tx_complete() function indicates transmit
+ completion.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function return a non-zero value if transmit has completed, otherwise
+ it returns zero.
+
+ Example:
+ See the MSS_UART_irq_tx() function for an example that uses the
+ MSS_UART_tx_complete() function.
+
+ */
+int8_t
+MSS_UART_tx_complete
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_rx() function reads the content of the UART receiver's FIFO
+ and stores it in the receive buffer that is passed via the rx_buff function
+ parameter. It copies either the full contents of the FIFO into the receive
+ buffer, or just enough data from the FIFO to fill the receive buffer,
+ dependent upon the size of the receive buffer passed by the buff_size
+ parameter. The MSS_UART_get_rx() function returns the number of bytes copied
+ into the receive buffer .This function is non-blocking and will return 0
+ immediately if no data has been received.
+
+ Note: The MSS_UART_get_rx() function reads and accumulates the receiver
+ status of the MSS UART instance before reading each byte from the receiver's
+ data register/FIFO. This allows the driver to maintain a sticky record of any
+ receiver errors that occur as the UART receives each data byte; receiver
+ errors would otherwise be lost after each read from the receiver's data
+ register. A call to the MSS_UART_get_rx_status() function returns any receiver
+ errors accumulated during the execution of the MSS_UART_get_rx() function.
+
+ Note: If you need to read the error status for each byte received, set
+ the buff_size to 1 and read the receive line error status for each byte
+ using the MSS_UART_get_rx_status() function.
+
+ The MSS_UART_get_rx() function can be used in polled mode, where it is called
+ at regular intervals to find out if any data has been received, or in
+ interrupt driven-mode, where it is called as part of a receive handler that is
+ called by the driver as a result of data being received.
+
+ Note: In interrupt driven mode you should call the MSS_UART_get_rx()
+ function as part of the receive handler function that you register with
+ the MSS UART driver through a call to MSS_UART_set_rx_handler().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param rx_buff
+ The rx_buff parameter is a pointer to a buffer where the received
+ data is copied.
+
+ @param buff_size
+ The buff_size parameter specifies the size of the receive buffer in bytes.
+
+ @return
+ This function returns the number of bytes that were copied into the
+ rx_buff buffer. It returns 0 if no data has been received.
+
+ Polled mode example:
+ @code
+ int main( void )
+ {
+ uint8_t rx_buff[RX_BUFF_SIZE];
+ uint32_t rx_idx = 0;
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ while(1)
+ {
+ rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_buff, sizeof(rx_buff));
+ if(rx_size > 0)
+ {
+ process_rx_data(rx_buff, rx_size);
+ }
+ task_a();
+ task_b();
+ }
+ return 0;
+ }
+ @endcode
+
+ Interrupt driven example:
+ @code
+ int main( void )
+ {
+ MSS_UART_init(&g_mss_uart1,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart1,
+ uart1_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ while(1)
+ {
+ task_a();
+ task_b();
+ }
+ return 0;
+ }
+
+ void uart1_rx_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t rx_buff[RX_BUFF_SIZE];
+ uint32_t rx_idx = 0;
+ rx_size = MSS_UART_get_rx(this_uart, rx_buff, sizeof(rx_buff));
+ process_rx_data(rx_buff, rx_size);
+ }
+ @endcode
+ */
+size_t
+MSS_UART_get_rx
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t * rx_buff,
+ size_t buff_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_handler() function is used to register a receive handler
+ function that is called by the driver when a UART receive data available (RDA)
+ interrupt occurs. You must create and register the receive handler function
+ to suit your application and it must include a call to the MSS_UART_get_rx()
+ function to actually read the received data.
+
+ Note: The MSS_UART_set_rx_handler() function enables both the RDA
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part
+ of its implementation.
+
+ Note: You can disable the RDA interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a receive interrupt handler function
+ provided by your application that will be called as a result of a UART RDA
+ interrupt. This handler function must be of type mss_uart_irq_handler_t.
+
+ @param trigger_level
+ The trigger_level parameter is the receive FIFO trigger level. This
+ specifies the number of bytes that must be received before the UART
+ triggers an RDA interrupt.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ #define RX_BUFF_SIZE 64
+
+ uint8_t g_rx_buff[RX_BUFF_SIZE];
+
+ void uart0_rx_handler(mss_uart_instance_t * this_uart)
+ {
+ MSS_UART_get_rx(this_uart, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff));
+ }
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart0_lo,
+ uart0_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_rx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler,
+ mss_uart_rx_trig_level_t trigger_level
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_loopback() function is used to locally loop-back the Tx and
+ Rx lines of a UART. This is not to be confused with the loop-back of UART0
+ to UART1, which can be achieved through the microprocessor subsystem's
+ system registers.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param loopback
+ The loopback parameter indicates whether or not the UART's transmit and
+ receive lines should be looped back. Allowed values are as follows:
+ - MSS_UART_LOCAL_LOOPBACK_ON
+ - MSS_UART_LOCAL_LOOPBACK_OFF
+ - MSS_UART_REMOTE_LOOPBACK_ON
+ - MSS_UART_REMOTE_LOOPBACK_OFF
+ - MSS_UART_AUTO_ECHO_ON
+ - MSS_UART_AUTO_ECHO_OFF
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_loopback(&g_mss_uart0_lo, MSS_UART_LOCAL_LOOPBACK_OFF);
+ @endcode
+ */
+void
+MSS_UART_set_loopback
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_loopback_t loopback
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_irq() function enables the MSS UART interrupts specified
+ by the irq_mask parameter. The irq_mask parameter identifies the MSS UART
+ interrupts by bit position, as defined in the interrupt enable register (IER)
+ of MSS UART. The MSS UART interrupts and their identifying irq_mask bit
+ positions are as follows:
+ When an irq_mask bit position is set to 1, this function enables the
+ corresponding MSS UART interrupt in the IER register. When an irq_mask bit
+ position is set to 0, the state of the corresponding interrupt remains
+ unchanged in the IER register.
+
+ Note: The MSS_UART_enable_irq() function also enables the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param irq_mask
+ The irq_mask parameter is used to select which of the MSS UART's interrupts
+ you want to enable. The allowed value for the irq_mask parameter is one of
+ the following constants or a bitwise OR of more than one:
+ - MSS_UART_RBF_IRQ (bit mask = 0x001)
+ - MSS_UART_TBE_IRQ (bit mask = 0x002)
+ - MSS_UART_LS_IRQ (bit mask = 0x004)
+ - MSS_UART_MS_IRQ (bit mask = 0x008)
+ - MSS_UART_RTO_IRQ (bit mask = 0x010)
+ - MSS_UART_NACK_IRQ (bit mask = 0x020)
+ - MSS_UART_PIDPE_IRQ (bit mask = 0x040)
+ - MSS_UART_LINB_IRQ (bit mask = 0x080)
+ - MSS_UART_LINS_IRQ (bit mask = 0x100)
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_irq(&g_mss_uart0_lo,(MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ));
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_enable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_irq() function disables the MSS UART interrupts specified
+ by the irq_mask parameter. The irq_mask parameter identifies the MSS UART
+ interrupts by bit position, as defined in the interrupt enable register (IER)
+ of MSS UART. The MSS UART interrupts and their identifying bit positions are
+ as follows:
+ When an irq_mask bit position is set to 1, this function disables the
+ corresponding MSS UART interrupt in the IER register. When an irq_mask bit
+ position is set to 0, the state of the corresponding interrupt remains
+ unchanged in the IER register.
+
+ Note: If you disable all four of the UART's interrupts, the
+ MSS_UART_disable_irq() function also disables the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param irq_mask
+ The irq_mask parameter is used to select which of the MSS UART's interrupts
+ you want to disable. The allowed value for the irq_mask parameter is one of
+ the following constants or a bitwise OR of more than one:
+ - MSS_UART_RBF_IRQ (bit mask = 0x001)
+ - MSS_UART_TBE_IRQ (bit mask = 0x002)
+ - MSS_UART_LS_IRQ (bit mask = 0x004)
+ - MSS_UART_MS_IRQ (bit mask = 0x008)
+ - MSS_UART_RTO_IRQ (bit mask = 0x010)
+ - MSS_UART_NACK_IRQ (bit mask = 0x020)
+ - MSS_UART_PIDPE_IRQ (bit mask = 0x040)
+ - MSS_UART_LINB_IRQ (bit mask = 0x080)
+ - MSS_UART_LINS_IRQ (bit mask = 0x100)
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_irq(&g_mss_uart0_lo,(MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ));
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_disable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_pidpei_handler() function is used assign a custom interrupt
+ handler for the PIDPEI (PID parity error interrupt) when the MSS UART is
+ operating in LIN mode.
+
+ Note: The MSS_UART_set_pidpei_handler() function enables both the PIDPEI
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the PIDPEI interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_pidpei_handler(&g_mss_uart0_lo, my_pidpei_handler);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_pidpei_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_linbreak_handler () function is used assign a custom
+ interrupt handler for the LIN Break detection interrupt when the MSS UART
+ is operating in LIN mode.
+
+ Note: The MSS_UART_set_linbreak_handler() function enables both the LIN
+ BREAK interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the LIN BREAK interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_linbreak_handler(&g_mss_uart0_lo, my_break_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_linbreak_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_linsync_handler() function is used assign a custom interrupt
+ handler for the LIN Sync character detection interrupt when the MSS UART is
+ operating in LIN mode.
+
+ Note: The MSS_UART_set_linsync_handler() function enables both the LIN
+ SYNC interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the LIN SYNC interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_linsync_handler(&g_mss_uart0_lo, my_linsync_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_linsync_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_nack_handler() function is used assign a custom interrupt
+ handler for the NACK character detection interrupt when the MSS UART
+ is operating in Smartcard mode.
+
+ Note: The MSS_UART_set_nack_handler() function enables both the NAK
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the NAK interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_nack_handler(&g_mss_uart0_lo, my_nack_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_nack_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_timeout_handler() function is used assign a custom
+ interrupt handler for the receiver timeout interrupt when the MSS UART is
+ operating in mode. It finds application in IrDA mode of operation.
+
+ Note: The MSS_UART_set_rx_timeout_handler() function enables both the
+ time-out interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the RX time-out interrupt when required by calling
+ the MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_timeout_handler(&g_mss_uart0_lo, my_rxtimeout_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_rx_timeout_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rxstatus_handler() function is used to register a receiver
+ status handler function that is called by the driver when a UART receiver
+ line status (RLS) interrupt occurs. You must create and register the handler
+ function to suit your application.
+
+ Note: The MSS_UART_set_rxstatus_handler() function enables both the RLS
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+ Note: You can disable the RLS interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a receiver line status interrupt
+ handler function provided by your application that will be called as a
+ result of a UART RLS interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ void uart_rxsts_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_rx_status(this_uart);
+ if(status & MSS_UART_OVERUN_ERROR)
+ {
+ discard_rx_data();
+ }
+ }
+
+ int main(void)
+ {
+ MSS_UART_init( &g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rxstatus_handler(&g_mss_uart0_lo, uart_rxsts_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_rxstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_tx_handler() function is used to register a transmit handler
+ function that is called by the driver when a UART transmit holding register
+ empty (THRE) interrupt occurs. You must create and register the transmit
+ handler function to suit your application. You can use the
+ MSS_UART_fill_tx_fifo() function in your transmit handler function to
+ write data to the transmitter.
+
+ Note: The MSS_UART_set_tx_handler() function enables both the THRE
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+
+ Note: You can disable the THRE interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ Note: The MSS_UART_irq_tx() function does not use the transmit handler
+ function that you register with the MSS_UART_set_tx_handler() function.
+ It uses its own internal THRE interrupt handler function that overrides
+ any custom interrupt handler that you register using the
+ MSS_UART_set_tx_handler() function.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a transmit interrupt handler
+ function provided by your application that will be called as a result
+ of a UART THRE interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ uint8_t * g_tx_buffer;
+ size_t g_tx_size = 0;
+
+ void uart_tx_handler(mss_uart_instance_t * this_uart)
+ {
+ size_t size_in_fifo;
+ size_in_fifo = MSS_UART_fill_tx_fifo(this_uart,
+ (const uint8_t *)g_tx_buffer,
+ g_tx_size);
+
+ if(size_in_fifo == g_tx_size)
+ {
+ g_tx_size = 0;
+ MSS_UART_disable_irq(this_uart, MSS_UART_TBE_IRQ);
+ }
+ else
+ {
+ g_tx_buffer = &g_tx_buffer[size_in_fifo];
+ g_tx_size = g_tx_size - size_in_fifo;
+ }
+ }
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello world";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ g_tx_buffer = message;
+ g_tx_size = sizeof(message);
+
+ MSS_UART_set_tx_handler(&g_mss_uart0_lo, uart_tx_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_tx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_modemstatus_handler() function is used to register a modem
+ status handler function that is called by the driver when a UART modem status
+ (MS) interrupt occurs. You must create and register the handler function to
+ suit your application.
+
+ Note: The MSS_UART_set_modemstatus_handler() function enables both the MS
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+ Note: You can disable the MS interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent
+ upon your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a modem status interrupt handler
+ function provided by your application that will be called as a result
+ of a UART MS interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ void uart_modem_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_modem_status(this_uart);
+ if(status & MSS_UART_CTS)
+ {
+ uart_cts_handler();
+ }
+ }
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_modemstatus_handler(&g_mss_uart0_lo, uart_modem_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+
+void
+MSS_UART_set_modemstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_fill_tx_fifo() function fills the UART's hardware transmitter
+ FIFO with the data found in the transmitter buffer that is passed via the
+ tx_buffer function parameter. If the transmitter FIFO is not empty when
+ the function is called, the function returns immediately without transferring
+ any data to the FIFO; otherwise, the function transfers data from the
+ transmitter buffer to the FIFO until it is full or until the complete
+ contents of the transmitter buffer have been copied into the FIFO. The
+ function returns the number of bytes copied into the UART's transmitter FIFO.
+
+ Note: This function reads the UART's line status register (LSR) to check
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. If
+ THRE is 0, the function returns immediately, without transferring any data
+ to the FIFO. If THRE is 1, the function transfers up to 16 bytes of data
+ to the FIFO and then returns.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param tx_buffer
+ The tx_buffer parameter is a pointer to a buffer containing the data
+ to be transmitted.
+
+ @param tx_size
+ The tx_size parameter is the size in bytes, of the data to be transmitted.
+
+ @return
+ This function returns the number of bytes copied into the UART's
+ transmitter FIFO.
+
+ Example:
+ @code
+ void send_using_interrupt(uint8_t * pbuff, size_t tx_size)
+ {
+ size_t size_in_fifo;
+ size_in_fifo = MSS_UART_fill_tx_fifo(&g_mss_uart0_lo, pbuff, tx_size);
+ }
+ @endcode
+ */
+size_t
+MSS_UART_fill_tx_fifo
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * tx_buffer,
+ size_t tx_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_rx_status() function returns the receiver error status of the
+ MSS UART instance. It reads both the current error status of the receiver from
+ the UART's line status register (LSR) and the accumulated error status from
+ preceding calls to the MSS_UART_get_rx() function, and it combines them using
+ a bitwise OR. It returns the cumulative overrun, parity, framing, break and
+ FIFO error status of the receiver, since the previous call to
+ MSS_UART_get_rx_status(), as an 8-bit encoded value.
+
+ Note: The MSS_UART_get_rx() function reads and accumulates the receiver
+ status of the MSS UART instance before reading each byte from the receiver's
+ data register/FIFO. The driver maintains a sticky record of the cumulative
+ receiver error status, which persists after the MSS_UART_get_rx() function
+ returns. The MSS_UART_get_rx_status() function clears the driver's sticky
+ receiver error record before returning.
+
+ Note: The driver's transmit functions also read the line status
+ register (LSR) as part of their implementation. When the driver reads the
+ LSR, the UART clears any active receiver error bits in the LSR. This could
+ result in the driver losing receiver errors. To avoid any loss of receiver
+ errors, the transmit functions also update the driver's sticky record of the
+ cumulative receiver error status whenever they read the LSR.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns the UART's receiver error status as an 8-bit unsigned
+ integer. The returned value is 0 if no receiver errors occurred. The driver
+ provides a set of bit mask constants that should be compared with and/or
+ used to mask the returned value to determine the receiver error status.
+ When the return value is compared to the following bit masks, a non-zero
+ result indicates that the corresponding error occurred:
+ - MSS_UART_OVERRUN_ERROR (bit mask = 0x02)
+ - MSS_UART_PARITY_ERROR (bit mask = 0x04)
+ - MSS_UART_FRAMING_ERROR (bit mask = 0x08)
+ - MSS_UART_BREAK_ERROR (bit mask = 0x10)
+ - MSS_UART_FIFO_ERROR (bit mask = 0x80)
+
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that no error occurred:
+ - MSS_UART_NO_ERROR (bit mask = 0x00)
+
+ Upon unsuccessful execution, this function returns:
+ - MSS_UART_INVALID_PARAM (bit mask = 0xFF)
+
+ Example:
+ @code
+ uint8_t rx_data[MAX_RX_DATA_SIZE];
+ uint8_t err_status;
+ err_status = MSS_UART_get_rx_status(&g_mss_uart0);
+
+ if(MSS_UART_NO_ERROR == err_status)
+ {
+ rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_data, MAX_RX_DATA_SIZE);
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_rx_status
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_modem_status() function returns the modem status of the
+ MSS UART instance. It reads the modem status register (MSR) and returns
+ the 8 bit value. The bit encoding of the returned value is exactly the
+ same as the definition of the bits in the MSR.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns current state of the UART's MSR as an 8 bit
+ unsigned integer. The driver provides the following set of bit mask
+ constants that should be compared with and/or used to mask the
+ returned value to determine the modem status:
+ - MSS_UART_DCTS (bit mask = 0x01)
+ - MSS_UART_DDSR (bit mask = 0x02)
+ - MSS_UART_TERI (bit mask = 0x04)
+ - MSS_UART_DDCD (bit mask = 0x08)
+ - MSS_UART_CTS (bit mask = 0x10)
+ - MSS_UART_DSR (bit mask = 0x20)
+ - MSS_UART_RI (bit mask = 0x40)
+ - MSS_UART_DCD (bit mask = 0x80)
+
+ Example:
+ @code
+ void uart_modem_status_isr(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_modem_status(this_uart);
+ if( status & MSS_UART_DCTS )
+ {
+ uart_dcts_handler();
+ }
+ if( status & MSS_UART_CTS )
+ {
+ uart_cts_handler();
+ }
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_modem_status
+(
+ const mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_tx_status() function returns the transmitter status of the
+ MSS UART instance. It reads both the UART's line status register (LSR) and
+ returns the status of the transmit holding register empty (THRE) and
+ transmitter empty (TEMT) bits.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns the UART's transmitter status as an 8-bit unsigned
+ integer. The returned value is 0 if the transmitter status bits are not
+ set or the function execution failed. The driver provides a set of bit
+ mask constants that should be compared with and/or used to mask the
+ returned value to determine the transmitter status.
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that the corresponding transmitter status bit is set:
+ - MSS_UART_THRE (bit mask = 0x20)
+ - MSS_UART_TEMT (bit mask = 0x40)
+
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that the transmitter is busy or the function execution
+ failed.
+ - MSS_UART_TX_BUSY (bit mask = 0x00)
+
+ Example:
+ @code
+ uint8_t tx_buff[10] = "abcdefghi";
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff));
+
+ while(!(MSS_UART_TEMT & MSS_UART_get_tx_status(&g_mss_uart0)))
+ {
+ ;
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_tx_status
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_break() function is used to send the break
+ (9 zeros after stop bit) signal on the TX line. This function can be used
+ only when the MSS UART is initialized in LIN mode by using MSS_UART_lin_init().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_break(&g_mss_uart0);
+ @endcode
+ */
+void
+MSS_UART_set_break
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_clear_break() function is used to remove the break signal on the
+ TX line. This function can be used only when the MSS UART is initialized in
+ LIN mode by using MSS_UART_lin_init().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_clear_break(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_clear_break
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_half_duplex() function is used to enable the half-duplex
+ (single wire) mode for the MSS UART. Though it finds application in Smartcard
+ mode, half-duplex mode can be used in other modes as well.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_half_duplex(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_half_duplex() function is used to disable the half-duplex
+ (single wire) mode for the MSS UART. Though it finds application in Smartcard
+ mode, half-duplex mode can be used in other modes as well.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_half_duplex(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_endian() function is used to configure the LSB first or
+ MSB first setting for MSS UART receiver
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param endian
+ The endian parameter tells the LSB first or MSB first configuration.
+ This parameter is of type mss_uart_endian_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_endian(&g_mss_uart0_lo, MSS_UART_LITTLEEND);
+ @endcode
+ */
+void
+MSS_UART_set_rx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_tx_endian() function is used to configure the LSB first or
+ MSB first setting for MSS UART transmitter.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param endian
+ The endian parameter tells the LSB first or MSB first configuration.
+ This parameter is of type mss_uart_endian_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_tx_endian(&g_mss_uart0_lo, MSS_UART_LITTLEEND);
+ @endcode
+ */
+void
+MSS_UART_set_tx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_filter_length () function is used to configure the glitch
+ filter length of the MSS UART. This should be configured in accordance with
+ the chosen baud rate.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param length
+ The length parameter is of mss_uart_filter_length_t type that determines
+ the length of the glitch filter.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_filter_length(&g_mss_uart0_lo, MSS_UART_LEN2);
+ @endcode
+ */
+void
+MSS_UART_set_filter_length
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_filter_length_t length
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_afm() function is used to enable address flag detection
+ mode of the MSS UART
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_afm(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_afm
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_afm() function is used to disable address flag detection
+ mode of the MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_afm(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_afm
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_afclear () function is used to enable address flag clear
+ of the MSS UART. This should be used in conjunction with address flag
+ detection mode (AFM).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_afclear(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_afclear
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_afclear () function is used to disable address flag
+ clear of the MSS UART. This should be used in conjunction with address flag
+ detection mode (AFM).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_afclear(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_afclear
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_rx_timeout() function is used to enable and configure
+ the receiver timeout functionality of MSS UART. This function accepts the
+ timeout parameter and applies the timeout based up on the baud rate as per
+ the formula 4 x timeout x bit time.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param timeout
+ The timeout parameter specifies the receiver timeout multiple.
+ It should be configured according to the baud rate in use.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_rx_timeout(&g_mss_uart0_lo, 24);
+ @endcode
+ */
+void
+MSS_UART_enable_rx_timeout
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeout
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_rx_timeout() function is used to disable the receiver
+ timeout functionality of MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_rx_timeout(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_rx_timeout
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_tx_time_guard() function is used to enable and configure
+ the transmitter time guard functionality of MSS UART. This function accepts
+ the timeguard parameter and applies the timeguard based up on the baud rate
+ as per the formula timeguard x bit time.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param timeguard
+ The timeguard parameter specifies the transmitter time guard multiple.
+ It should be configured according to the baud rate in use.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_tx_time_guard(&g_mss_uart0_lo, 24);
+ @endcode
+ */
+void
+MSS_UART_enable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeguard
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_tx_time_guard() function is used to disable the
+ transmitter time guard functionality of MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_tx_time_guard(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_address() function is used to set the 8-bit address for
+ the MSS UART referenced by this_uart parameter.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param address
+ The address parameter is the 8-bit address which is to be configured
+ to the MSS UART referenced by this_uart parameter.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_address(&g_mss_uart0_lo, 0xAA);
+ @endcode
+ */
+void
+MSS_UART_set_address
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t address
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_ready_mode() function is used to configure the MODE0 or MODE1
+ to the TXRDY and RXRDY signals of the MSS UART referenced by this_uart
+ parameter. The mode parameter is used to provide the mode to be configured.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param mode
+ The mode parameter is the mss_uart_ready_mode_t type which is used to
+ configure the TXRDY and RXRDY signal modes.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_ready_mode(&g_mss_uart0_lo, MSS_UART_READY_MODE0);
+ @endcode
+ */
+void
+MSS_UART_set_ready_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_ready_mode_t mode
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_usart_mode() function is used to configure the MSS UART
+ referenced by the parameter this_uart in USART mode. Various USART modes
+ are supported which can be configured by the parameter mode of type
+ mss_uart_usart_mode_t.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param mode
+ The mode parameter is the USART mode to be configured.
+ This parameter is of type mss_uart_usart_mode_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_usart_mode(&g_mss_uart0_lo, MSS_UART_SYNC_MASTER_POS_EDGE_CLK);
+ @endcode
+ */
+void
+MSS_UART_set_usart_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_usart_mode_t mode
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_local_irq() function is used to enable the MMUART
+ interrupt as a local interrupt to the hart rather than via PLIC.
+ MMUART interrupt can be configured to trigger an interrupt via PLIC or it
+ can be configured to trigger a local interrupt. The arrangement is such that
+ the UART0 interrupt can appear as local interrupt on E51. The UART1 to UART4
+ interrupts can appear as local interrupt to U51_1 to U54_4 respectively.
+ The UART0 to UART4 can appear as PLIC interrupt. Multiple HARTs can enable
+ and receive the PLIC interrupt, the HART that claims the interrupt processes
+ it. For rest of the HARTs the IRQ gets silently skipped as the interrupt
+ claim has already been taken.
+
+ By default, the PLIC interrupt is enabled by this driver when
+ MSS_UART_enable_irq() or the APIs to set the interrupt handler is called.
+ To enable the local interrupt application must explicitly call
+ MSS_UART_enable_local_irq() function. Note that this function disables the
+ interrupt over PLIC if it was previously enabled.
+
+ This function must be called after the MMUART is initialized, the required
+ interrupt hander functions are set and before initiating any data transfers.
+ If you want to register multiple register handlers such as tx handler, rx
+ handler etc. then this function must be called after all such handlers are set.
+
+ Call to this function is treated as one time activity. The driver gives no
+ option to disable the local interrupt and enable the PLIC interrupt again at
+ runtime.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+
+
+ __enable_irq();
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart0_lo,
+ uart0_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ MSS_UART_enable_local_irq(&g_mss_uart0_lo);
+
+ @endcode
+ */
+void
+MSS_UART_enable_local_irq
+(
+ mss_uart_instance_t * this_uart
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_UART_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h
new file mode 100644
index 00000000..d550810a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h
@@ -0,0 +1,133 @@
+ /*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Register bit offsets and masks definitions for PolarFire SoC MSS MMUART
+ *
+ */
+
+#ifndef MSS_UART_REGS_H_
+#define MSS_UART_REGS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ Register Bit definitions
+ */
+
+/* Line Control register bit definitions */
+#define SB 6u /* Set break */
+#define DLAB 7u /* Divisor latch access bit */
+
+/* Line Control register bit masks */
+#define SB_MASK (0x01u << SB) /* Set break */
+#define DLAB_MASK (0x01u << DLAB) /* Divisor latch access bit */
+
+/* FIFO Control register bit definitions */
+#define RXRDY_TXRDYN_EN 0u /* Enable TXRDY and RXRDY signals */
+#define CLEAR_RX_FIFO 1u /* Clear receiver FIFO */
+#define CLEAR_TX_FIFO 2u /* Clear transmitter FIFO */
+#define RDYMODE 3u /* Mode 0 or Mode 1 for TXRDY and RXRDY */
+
+/* FIFO Control register bit MASKS */
+#define RXRDY_TXRDYN_EN_MASK (0x01u << 0u) /* Enable TXRDY and RXRDY signals */
+#define CLEAR_RX_FIFO_MASK (0x01u << 1u) /* Clear receiver FIFO */
+#define CLEAR_TX_FIFO_MASK (0x01u << 2u) /* Clear transmitter FIFO */
+#define RDYMODE_MASK (0x01u << 3u) /* Mode 0 or Mode 1 for TXRDY and RXRDY */
+
+/* Modem Control register bit definitions */
+#define LOOP 4u /* Local loopback */
+#define RLOOP 5u /* Remote loopback */
+#define ECHO 6u /* Automatic echo */
+
+/* Modem Control register bit MASKS */
+#define LOOP_MASK (0x01u << 4u) /* Local loopback */
+#define RLOOP_MASK (0x01u << 5u) /* Remote loopback & Automatic echo*/
+#define ECHO_MASK (0x01u << 6u) /* Automatic echo */
+
+/* Line Status register bit definitions */
+#define DR 0u /* Data ready */
+#define THRE 5u /* Transmitter holding register empty */
+#define TEMT 6u /* Transmitter empty */
+
+/* Line Status register bit MASKS */
+#define DR_MASK (0x01u << 0u) /* Data ready */
+#define THRE_MASK (0x01u << 5u) /* Transmitter holding register empty */
+#define TEMT_MASK (0x01u << 6u) /* Transmitter empty */
+
+/* Interrupt Enable register bit definitions */
+#define ERBFI 0u /* Enable receiver buffer full interrupt */
+#define ETBEI 1u /* Enable transmitter buffer empty interrupt */
+#define ELSI 2u /* Enable line status interrupt */
+#define EDSSI 3u /* Enable modem status interrupt */
+
+/* Interrupt Enable register bit MASKS */
+#define ERBFI_MASK (0x01u << 0u) /* Enable receiver buffer full interrupt */
+#define ETBEI_MASK (0x01u << 1u) /* Enable transmitter buffer empty interrupt */
+#define ELSI_MASK (0x01u << 2u) /* Enable line status interrupt */
+#define EDSSI_MASK (0x01u << 3u) /* Enable modem status interrupt */
+
+/* Multimode register 0 bit definitions */
+#define ELIN 3u /* Enable LIN header detection */
+#define ETTG 5u /* Enable transmitter time guard */
+#define ERTO 6u /* Enable receiver time-out */
+#define EFBR 7u /* Enable fractional baud rate mode */
+
+/* Multimode register 0 bit MASKS */
+#define ELIN_MASK (0x01u << 3u) /* Enable LIN header detection */
+#define ETTG_MASK (0x01u << 5u) /* Enable transmitter time guard */
+#define ERTO_MASK (0x01u << 6u) /* Enable receiver time-out */
+#define EFBR_MASK (0x01u << 7u) /* Enable fractional baud rate mode */
+
+/* Multimode register 1 bit definitions */
+#define E_MSB_RX 0u /* MSB / LSB first for receiver */
+#define E_MSB_TX 1u /* MSB / LSB first for transmitter */
+#define EIRD 2u /* Enable IrDA modem */
+#define EIRX 3u /* Input polarity for IrDA modem */
+#define EITX 4u /* Output polarity for IrDA modem */
+#define EITP 5u /* Output pulse width for IrDA modem */
+
+/* Multimode register 1 bit MASKS */
+#define E_MSB_RX_MASK (0x01u << 0u) /* MSB / LSB first for receiver */
+#define E_MSB_TX_MASK (0x01u << 1u) /* MSB / LSB first for transmitter */
+#define EIRD_MASK (0x01u << 2u) /* Enable IrDA modem */
+#define EIRX_MASK (0x01u << 3u) /* Input polarity for IrDA modem */
+#define EITX_MASK (0x01u << 4u) /* Output polarity for IrDA modem */
+#define EITP_MASK (0x01u << 5u) /* Output pulse width for IrDA modem */
+
+/* Multimode register 2 bit definitions */
+#define EERR 0u /* Enable ERR / NACK during stop time */
+#define EAFM 1u /* Enable 9-bit address flag mode */
+#define EAFC 2u /* Enable address flag clear */
+#define ESWM 3u /* Enable single wire half-duplex mode */
+
+/* Multimode register 2 bit MASKS */
+#define EERR_MASK (0x01u << 0u) /* Enable ERR / NACK during stop time */
+#define EAFM_MASK (0x01u << 1u) /* Enable 9-bit address flag mode */
+#define EAFC_MASK (0x01u << 2u) /* Enable address flag clear */
+#define ESWM_MASK (0x01u << 3u) /* Enable single wire half-duplex mode */
+
+/* Multimode Interrupt Enable register and
+ Multimode Interrupt Identification register definitions */
+#define ERTOI 0u /* Enable receiver timeout interrupt */
+#define ENACKI 1u /* Enable NACK / ERR interrupt */
+#define EPID_PEI 2u /* Enable PID parity error interrupt */
+#define ELINBI 3u /* Enable LIN break interrupt */
+#define ELINSI 4u /* Enable LIN sync detection interrupt */
+
+/* Multimode Interrupt Enable register and
+ Multimode Interrupt Identification register MASKS */
+#define ERTOI_MASK (0x01u << 0u) /* Enable receiver timeout interrupt */
+#define ENACKI_MASK (0x01u << 1u) /* Enable NACK / ERR interrupt */
+#define EPID_PEI_MASK (0x01u << 2u) /* Enable PID parity error interrupt */
+#define ELINBI_MASK (0x01u << 3u) /* Enable LIN break interrupt */
+#define ELINSI_MASK (0x01u << 4u) /* Enable LIN sync detection interrupt */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_UART_REGS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/cpu_types.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/cpu_types.h
new file mode 100644
index 00000000..55cfac93
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/cpu_types.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+#ifndef CPU_TYPES_H
+#define CPU_TYPES_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long size_t;
+
+/*------------------------------------------------------------------------------
+ * addr_t: address type.
+ * Used to specify the address of peripherals present in the processor's memory
+ * map.
+ */
+typedef unsigned long addr_t;
+
+/*------------------------------------------------------------------------------
+ * psr_t: processor state register.
+ * Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the
+ * processor's state between disabling and restoring interrupts.
+ */
+typedef unsigned long psr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CPU_TYPES_H */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal.h
new file mode 100644
index 00000000..658ab2a0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal.h
@@ -0,0 +1,241 @@
+/***************************************************************************//**
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Hardware abstraction layer functions.
+ *
+ * Legacy register interrupt functions
+ * Pointers are now recommended for use in drivers
+ *
+ */
+#ifndef HAL_H
+#define HAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cpu_types.h"
+#include "hw_reg_access.h"
+#include "hal/hal_assert.h"
+/***************************************************************************//**
+ * Enable all interrupts at the processor level.
+ */
+void HAL_enable_interrupts( void );
+
+/***************************************************************************//**
+ * Disable all interrupts at the processor core level.
+ * Return the interrupts enable state before disabling occurred so that it can
+ * later be restored.
+ */
+psr_t HAL_disable_interrupts( void );
+
+/***************************************************************************//**
+ * Restore the interrupts enable state at the processor core level.
+ * This function is normally passed the value returned from a previous call to
+ * HAL_disable_interrupts().
+ */
+void HAL_restore_interrupts( psr_t saved_psr );
+
+/***************************************************************************//**
+ */
+#define FIELD_OFFSET(FIELD_NAME) (FIELD_NAME##_OFFSET)
+#define FIELD_SHIFT(FIELD_NAME) (FIELD_NAME##_SHIFT)
+#define FIELD_MASK(FIELD_NAME) (FIELD_NAME##_MASK)
+
+/***************************************************************************//**
+ * The macro HAL_set_32bit_reg() allows writing a 32 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint32_t containing the value to write.
+ */
+#define HAL_set_32bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_32bit_reg() is used to read the value of a 32 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint32_t value.
+ */
+#define HAL_get_32bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)) ))
+
+/***************************************************************************//**
+ * The macro HAL_set_32bit_reg_field() is used to write a field within a
+ * 32 bits wide register. The field written can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint32_t containing the field value to write.
+ */
+#define HAL_set_32bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_32bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_32bit_reg_field() is used to read a register field from
+ * within a 32 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint32_t value.
+ */
+#define HAL_get_32bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_32bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+/***************************************************************************//**
+ * The macro HAL_set_16bit_reg() allows writing a 16 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint_fast16_t containing the value to write.
+ */
+#define HAL_set_16bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_16bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_16bit_reg() is used to read the value of a 16 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint16_t value.
+ */
+#define HAL_get_16bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_16bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
+
+/***************************************************************************//**
+ * The macro HAL_set_16bit_reg_field() is used to write a field within a
+ * 16 bits wide register. The field written can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint16_t containing the field value to write.
+ */
+#define HAL_set_16bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_16bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_16bit_reg_field() is used to read a register field from
+ * within a 8 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint16_t value.
+ */
+#define HAL_get_16bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_16bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+/***************************************************************************//**
+ * The macro HAL_set_8bit_reg() allows writing a 8 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint_fast8_t containing the value to write.
+ */
+#define HAL_set_8bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_8bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_8bit_reg() is used to read the value of a 8 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint8_t value.
+ */
+#define HAL_get_8bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_8bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
+
+/***************************************************************************//**
+ */
+#define HAL_set_8bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_8bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_8bit_reg_field() is used to read a register field from
+ * within a 8 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint8_t value.
+ */
+#define HAL_get_8bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_8bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*HAL_H*/
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_assert.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_assert.h
new file mode 100644
index 00000000..8d64b3c5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_assert.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+#ifndef HAL_ASSERT_HEADER
+#define HAL_ASSERT_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * ASSERT() implementation.
+ ******************************************************************************/
+/* Disable assertions if we do not recognize the compiler. */
+#if defined ( __GNUC__ )
+#if defined(NDEBUG)
+#define ASSERT(CHECK)
+#else
+#define ASSERT(CHECK)\
+ do { \
+ if (!(CHECK)) \
+ { \
+ __asm volatile ("ebreak"); \
+ }\
+ } while(0);
+#endif /* NDEBUG check */
+#endif /* compiler check */
+
+#if defined(NDEBUG)
+/***************************************************************************//**
+ * HAL_ASSERT() is defined out when the NDEBUG symbol is used.
+ ******************************************************************************/
+#define HAL_ASSERT(CHECK)
+
+#else
+/***************************************************************************//**
+ * Default behaviour for HAL_ASSERT() macro:
+ *------------------------------------------------------------------------------
+ The behaviour is toolchain specific and project setting specific.
+ ******************************************************************************/
+#define HAL_ASSERT(CHECK) ASSERT(CHECK);
+
+#endif /* NDEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_ASSERT_HEADER */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_irq.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_irq.c
new file mode 100644
index 00000000..2fea28e1
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_irq.c
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Legacy interrupt control functions for the Microchip driver library hardware
+ * abstraction layer.
+ *
+ */
+#include
+#include "hal/hal.h"
+#include "mpfs_hal/common/mss_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void HAL_enable_interrupts(void) {
+ __enable_irq();
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+psr_t HAL_disable_interrupts(void) {
+ psr_t psr;
+ psr = read_csr(mstatus);
+ __disable_irq();
+ return(psr);
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void HAL_restore_interrupts(psr_t saved_psr) {
+ write_csr(mstatus, saved_psr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_version.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_version.h
new file mode 100644
index 00000000..7d4d31c8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hal_version.h
@@ -0,0 +1,50 @@
+#ifndef HAL_VERSION_H
+#define HAL_VERSION_H
+
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ *
+ */
+
+/*******************************************************************************
+ * @file mpfs_halversion.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MICROCHIP FPGA Embedded Software Hardware Abstraction layer - HAL
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HAL_VERSION_MAJOR 1
+#define HAL_VERSION_MINOR 8
+#define HAL_VERSION_PATCH 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_macros.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_macros.h
new file mode 100644
index 00000000..cab09353
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_macros.h
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * Hardware registers access macros.
+ *
+ * THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USE FOR NEW
+ * DEVELOPMENT.
+ *
+ * These macros are used to access peripheral registers. They allow access to
+ * 8, 16 and 32 bit wide registers. All accesses to peripheral registers should
+ * be done through these macros in order to ease porting across different
+ * processors/bus architectures.
+ *
+ * Some of these macros also allow access to a specific register field.
+ *
+ */
+
+#ifndef HW_MACROS_H
+#define HW_MACROS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ * 32 bits registers access:
+ */
+#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint32_t) \
+ ( \
+ (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 32 bits memory access:
+ */
+#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))
+
+#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))
+
+/*------------------------------------------------------------------------------
+ * 16 bits registers access:
+ */
+#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint16_t) \
+ ( \
+ (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 8 bits registers access:
+ */
+#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint8_t) \
+ ( \
+ (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 8 bits memory access:
+ */
+#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))
+
+#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#endif /* HW_MACROS_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_reg_access.S b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_reg_access.S
new file mode 100644
index 00000000..31352f60
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_reg_access.S
@@ -0,0 +1,214 @@
+/***************************************************************************//**
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ * Hardware registers access functions.
+ * The implementation of these function is platform and toolchain specific.
+ * The functions declared here are implemented using assembler as part of the
+ * processor/toolchain specific HAL.
+ *
+ */
+
+.section .text
+ .globl HW_set_32bit_reg
+ .globl HW_get_32bit_reg
+ .globl HW_set_32bit_reg_field
+ .globl HW_get_32bit_reg_field
+ .globl HW_set_16bit_reg
+ .globl HW_get_16bit_reg
+ .globl HW_set_16bit_reg_field
+ .globl HW_get_16bit_reg_field
+ .globl HW_set_8bit_reg
+ .globl HW_get_8bit_reg
+ .globl HW_set_8bit_reg_field
+ .globl HW_get_8bit_reg_field
+
+
+/***************************************************************************//**
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint32_t value
+ */
+HW_set_32bit_reg:
+ sw a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 32 bits value read from the peripheral register.
+ */
+HW_get_32bit_reg:
+ lw a0, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint32_t mask
+ * a3: uint32_t value
+ */
+HW_set_32bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lw t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sw t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_32bit_reg_field is used to read the content of a field out of a
+ * 32 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint32_t mask
+ *
+ * @return 32 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_32bit_reg_field:
+ lw a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+/***************************************************************************//**
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint_fast16_t value
+ */
+HW_set_16bit_reg:
+ sh a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 16 bits value read from the peripheral register.
+ */
+HW_get_16bit_reg:
+ lh a0, (a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast16_t mask
+ * a3: uint_fast16_t value
+ * @param value Value to be written in the specified field.
+ */
+HW_set_16bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lh t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sh t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_16bit_reg_field is used to read the content of a field from a
+ * 16 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast16_t mask
+ *
+ * @return 16 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_16bit_reg_field:
+ lh a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+/***************************************************************************//**
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint_fast8_t value
+ */
+HW_set_8bit_reg:
+ sb a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 8 bits value read from the peripheral register.
+ */
+HW_get_8bit_reg:
+ lb a0, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr,
+ * a1: int_fast8_t shift
+ * a2: uint_fast8_t mask
+ * a3: uint_fast8_t value
+ */
+HW_set_8bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lb t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sb t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_8bit_reg_field is used to read the content of a field from a
+ * 8 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast8_t mask
+ *
+ * @return 8 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_8bit_reg_field:
+ lb a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+.end
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_reg_access.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_reg_access.h
new file mode 100644
index 00000000..10ae5469
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/hw_reg_access.h
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Hardware registers access functions.
+ * The implementation of these function is platform and tool-chain specific.
+ * The functions declared here are implemented using assembler as part of the
+ * processor/tool-chain specific HAL.
+ *
+ */
+#ifndef HW_REG_ACCESS
+#define HW_REG_ACCESS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "cpu_types.h"
+/***************************************************************************//**
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_32bit_reg
+(
+ addr_t reg_addr,
+ uint32_t value
+);
+
+/***************************************************************************//**
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 32 bits value read from the peripheral register.
+ */
+uint32_t
+HW_get_32bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void
+HW_set_32bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint32_t mask,
+ uint32_t value
+);
+
+/***************************************************************************//**
+ * HW_get_32bit_reg_field is used to read the content of a field out of a
+ * 32 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 32 bits value containing the register field value specified
+ * as parameter.
+ */
+uint32_t
+HW_get_32bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint32_t mask
+);
+
+/***************************************************************************//**
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_16bit_reg
+(
+ addr_t reg_addr,
+ uint_fast16_t value
+);
+
+/***************************************************************************//**
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 16 bits value read from the peripheral register.
+ */
+uint16_t
+HW_get_16bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void HW_set_16bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast16_t mask,
+ uint_fast16_t value
+);
+
+/***************************************************************************//**
+ * HW_get_16bit_reg_field is used to read the content of a field from a
+ * 16 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 16 bits value containing the register field value specified
+ * as parameter.
+ */
+uint16_t HW_get_16bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast16_t mask
+);
+
+/***************************************************************************//**
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_8bit_reg
+(
+ addr_t reg_addr,
+ uint_fast8_t value
+);
+
+/***************************************************************************//**
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 8 bits value read from the peripheral register.
+ */
+uint8_t
+HW_get_8bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void HW_set_8bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast8_t mask,
+ uint_fast8_t value
+);
+
+/***************************************************************************//**
+ * HW_get_8bit_reg_field is used to read the content of a field from a
+ * 8 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 8 bits value containing the register field value specified
+ * as parameter.
+ */
+uint8_t HW_get_8bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast8_t mask
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HW_REG_ACCESS */
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/readme.md b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/readme.md
new file mode 100644
index 00000000..ce9ae8f6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/hal/readme.md
@@ -0,0 +1,41 @@
+===============================================================================
+# hal folder
+===============================================================================
+
+The HAL folder provides support code for use by the bare metal drivers for the
+fabric IP cores.
+The HAL folder contains files using a combination of C and assembly source code.
+
+The hal folder should be included in a PolarFire SoC Embedded project under the
+platform directory. See location in the drawing below.
+
+The hal folder contains:
+
+* register access functions
+* assert macros
+
+### Project directory strucutre, showing where hal folder sits.
+
+ +---------+ +-----------+
+ | src +----->|application|
+ +---------+ | +-----------+
+ |
+ | +-----------+
+ +-->|modules |
+ | +-----------+
+ |
+ | +-----------+ +---------+
+ +-->|platform +---->|config |
+ +-----------+ | +---------+
+ |
+ | +---------+
+ +->|drivers |
+ | +---------+
+ |
+ | +---------+
+ +->|hal |
+ | +---------+
+ |
+ | +---------+
+ +->|mpfs_hal |
+ +---------+
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/atomic.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/atomic.h
new file mode 100644
index 00000000..48110f00
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/atomic.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+
+#ifndef RISCV_ATOMIC_H
+#define RISCV_ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define mb() asm volatile ("fence" ::: "memory")
+#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val)
+#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr))
+
+#ifdef __riscv_atomic
+# define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp)
+# define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc)
+#else
+#define atomic_binop(ptr, inc, op) ({ \
+ long flags = disable_irqsave(); \
+ typeof(*(ptr)) res = atomic_read(ptr); \
+ atomic_set(ptr, op); \
+ enable_irqrestore(flags); \
+ res; })
+#define atomic_or(ptr, inc) atomic_binop(ptr, inc, res | (inc))
+#define atomic_swap(ptr, swp) atomic_binop(ptr, swp, (swp))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //RISCV_ATOMIC_H
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/bits.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/bits.h
new file mode 100644
index 00000000..b2df5f55
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/bits.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+#ifndef RISCV_BITS_H
+#define RISCV_BITS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define likely(x) __builtin_expect((x), 1)
+#define unlikely(x) __builtin_expect((x), 0)
+
+#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
+#define ROUNDDOWN(a, b) ((a)/(b)*(b))
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
+
+#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
+#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
+
+#define STR(x) XSTR(x)
+#define XSTR(x) #x
+
+#if __riscv_xlen == 64
+# define SLL32 sllw
+# define STORE sd
+# define LOAD ld
+# define LWU lwu
+# define LOG_REGBYTES 3
+#else
+# define SLL32 sll
+# define STORE sw
+# define LOAD lw
+# define LWU lw
+# define LOG_REGBYTES 2
+#endif
+#define REGBYTES (1 << LOG_REGBYTES)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //RISCV_BITS_H
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/encoding.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/encoding.h
new file mode 100644
index 00000000..c86fb172
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/encoding.h
@@ -0,0 +1,1532 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+
+
+#ifndef RISCV_CSR_ENCODING_H
+#define RISCV_CSR_ENCODING_H
+
+#define MSTATUS_UIE 0x00000001
+#define MSTATUS_SIE 0x00000002
+#define MSTATUS_HIE 0x00000004
+#define MSTATUS_MIE 0x00000008
+#define MSTATUS_UPIE 0x00000010
+#define MSTATUS_SPIE 0x00000020
+#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_MPIE 0x00000080
+#define MSTATUS_SPP 0x00000100
+#define MSTATUS_HPP 0x00000600
+#define MSTATUS_MPP 0x00001800
+#define MSTATUS_FS 0x00006000
+#define MSTATUS_XS 0x00018000
+#define MSTATUS_MPRV 0x00020000
+#define MSTATUS_SUM 0x00040000
+#define MSTATUS_MXR 0x00080000
+#define MSTATUS_TVM 0x00100000
+#define MSTATUS_TW 0x00200000
+#define MSTATUS_TSR 0x00400000
+#define MSTATUS32_SD 0x80000000
+#define MSTATUS64_SD 0x8000000000000000
+
+#define MCAUSE32_CAUSE 0x7FFFFFFF
+#define MCAUSE64_CAUSE 0x7FFFFFFFFFFFFFFF
+#define MCAUSE32_INT 0x80000000
+#define MCAUSE64_INT 0x8000000000000000
+
+#define SSTATUS_UIE 0x00000001
+#define SSTATUS_SIE 0x00000002
+#define SSTATUS_UPIE 0x00000010
+#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_SPP 0x00000100
+#define SSTATUS_FS 0x00006000
+#define SSTATUS_XS 0x00018000
+#define SSTATUS_SUM 0x00040000
+#define SSTATUS_MXR 0x00080000
+#define SSTATUS32_SD 0x80000000
+#define SSTATUS64_SD 0x8000000000000000
+
+#define DCSR_XDEBUGVER (3U<<30)
+#define DCSR_NDRESET (1<<29)
+#define DCSR_FULLRESET (1<<28)
+#define DCSR_EBREAKM (1<<15)
+#define DCSR_EBREAKH (1<<14)
+#define DCSR_EBREAKS (1<<13)
+#define DCSR_EBREAKU (1<<12)
+#define DCSR_STOPCYCLE (1<<10)
+#define DCSR_STOPTIME (1<<9)
+#define DCSR_CAUSE (7<<6)
+#define DCSR_DEBUGINT (1<<5)
+#define DCSR_HALT (1<<3)
+#define DCSR_STEP (1<<2)
+#define DCSR_PRV (3<<0)
+
+#define DCSR_CAUSE_NONE 0
+#define DCSR_CAUSE_SWBP 1
+#define DCSR_CAUSE_HWBP 2
+#define DCSR_CAUSE_DEBUGINT 3
+#define DCSR_CAUSE_STEP 4
+#define DCSR_CAUSE_HALT 5
+
+#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
+#define MCONTROL_SELECT (1U<<19)
+#define MCONTROL_TIMING (1U<<18)
+#define MCONTROL_ACTION (0x3fU<<12)
+#define MCONTROL_CHAIN (1U<<11)
+#define MCONTROL_MATCH (0xfU<<7)
+#define MCONTROL_M (1U<<6)
+#define MCONTROL_H (1U<<5)
+#define MCONTROL_S (1U<<4)
+#define MCONTROL_U (1U<<3)
+#define MCONTROL_EXECUTE (1U<<2)
+#define MCONTROL_STORE (1U<<1)
+#define MCONTROL_LOAD (1U<<0)
+
+#define MCONTROL_TYPE_NONE 0
+#define MCONTROL_TYPE_MATCH 2
+
+#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
+#define MCONTROL_ACTION_DEBUG_MODE 1
+#define MCONTROL_ACTION_TRACE_START 2
+#define MCONTROL_ACTION_TRACE_STOP 3
+#define MCONTROL_ACTION_TRACE_EMIT 4
+
+#define MCONTROL_MATCH_EQUAL 0
+#define MCONTROL_MATCH_NAPOT 1
+#define MCONTROL_MATCH_GE 2
+#define MCONTROL_MATCH_LT 3
+#define MCONTROL_MATCH_MASK_LOW 4
+#define MCONTROL_MATCH_MASK_HIGH 5
+
+#define MIP_SSIP (1U << IRQ_S_SOFT)
+#define MIP_HSIP (1U << IRQ_H_SOFT)
+#define MIP_MSIP (1U << IRQ_M_SOFT)
+#define MIP_STIP (1U << IRQ_S_TIMER)
+#define MIP_HTIP (1U << IRQ_H_TIMER)
+#define MIP_MTIP (1U << IRQ_M_TIMER)
+#define MIP_SEIP (1U << IRQ_S_EXT)
+#define MIP_HEIP (1U << IRQ_H_EXT)
+#define MIP_MEIP (1U << IRQ_M_EXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+#define SPTBR32_MODE 0x80000000
+#define SPTBR32_ASID 0x7FC00000
+#define SPTBR32_PPN 0x003FFFFF
+#define SPTBR64_MODE 0xF000000000000000
+#define SPTBR64_ASID 0x0FFFF00000000000
+#define SPTBR64_PPN 0x00000FFFFFFFFFFF
+
+#define SPTBR_MODE_OFF 0
+#define SPTBR_MODE_SV32 1
+#define SPTBR_MODE_SV39 8
+#define SPTBR_MODE_SV48 9
+#define SPTBR_MODE_SV57 10
+#define SPTBR_MODE_SV64 11
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_L 0x80
+#define PMP_SHIFT 2
+
+#define PMP_TOR 0x08
+#define PMP_NA4 0x10
+#define PMP_NAPOT 0x18
+
+#define IRQ_S_SOFT 1
+#define IRQ_H_SOFT 2
+#define IRQ_M_SOFT 3
+#define IRQ_S_TIMER 5
+#define IRQ_H_TIMER 6
+#define IRQ_M_TIMER 7
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10
+#define IRQ_M_EXT 11
+#define IRQ_COP 12
+#define IRQ_HOST 13
+
+#define DEFAULT_RSTVEC 0x00001000
+#define CLINT_BASE 0x02000000
+#define CLINT_SIZE 0x000c0000
+#define EXT_IO_BASE 0x40000000
+#define DRAM_BASE 0x80000000
+
+// page table entry (PTE) fields
+#define PTE_V 0x001 // Valid
+#define PTE_R 0x002 // Read
+#define PTE_W 0x004 // Write
+#define PTE_X 0x008 // Execute
+#define PTE_U 0x010 // User
+#define PTE_G 0x020 // Global
+#define PTE_A 0x040 // Accessed
+#define PTE_D 0x080 // Dirty
+#define PTE_SOFT 0x300 // Reserved for Software
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
+
+#ifdef __riscv
+
+#if __riscv_xlen == 64
+# define MSTATUS_SD MSTATUS64_SD
+# define SSTATUS_SD SSTATUS64_SD
+# define RISCV_PGLEVEL_BITS 9
+# define SPTBR_MODE SPTBR64_MODE
+# define MCAUSE_INT MCAUSE64_INT //ML added- should we be using later encoding.h?
+# define MCAUSE_CAUSE MCAUSE64_CAUSE //ML added- should we be using later encoding.h?
+#else
+# define MSTATUS_SD MSTATUS32_SD
+# define SSTATUS_SD SSTATUS32_SD
+# define RISCV_PGLEVEL_BITS 10
+# define SPTBR_MODE SPTBR32_MODE
+# define MCAUSE_INT MCAUSE32_INT //ML added- should we be using later encoding.h?
+# define MCAUSE_CAUSE MCAUSE32_CAUSE //ML added- should we be using later encoding.h?
+#endif
+#define RISCV_PGSHIFT 12
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#ifndef __ASSEMBLER__
+
+#ifdef __GNUC__
+
+#define read_reg(reg) ({ unsigned long __tmp; \
+ asm volatile ("mv %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define read_csr(reg) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define write_csr(reg, val) __extension__({ \
+ asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
+
+#define swap_csr(reg, val) ({ unsigned long __tmp; \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
+ __tmp; })
+
+#define set_csr(reg, bit) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#define clear_csr(reg, bit) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#if 0
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ asm volatile ("csrw " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+#endif
+
+#define rdtime() read_csr(time)
+#define rdcycle() read_csr(cycle)
+#define rdinstret() read_csr(instret)
+
+#endif
+
+#endif
+
+#endif
+
+#endif
+/* Automatically generated by parse-opcodes. */
+#ifndef RISCV_ENCODING_H
+#define RISCV_ENCODING_H
+#define MATCH_BEQ 0x63
+#define MASK_BEQ 0x707f
+#define MATCH_BNE 0x1063
+#define MASK_BNE 0x707f
+#define MATCH_BLT 0x4063
+#define MASK_BLT 0x707f
+#define MATCH_BGE 0x5063
+#define MASK_BGE 0x707f
+#define MATCH_BLTU 0x6063
+#define MASK_BLTU 0x707f
+#define MATCH_BGEU 0x7063
+#define MASK_BGEU 0x707f
+#define MATCH_JALR 0x67
+#define MASK_JALR 0x707f
+#define MATCH_JAL 0x6f
+#define MASK_JAL 0x7f
+#define MATCH_LUI 0x37
+#define MASK_LUI 0x7f
+#define MATCH_AUIPC 0x17
+#define MASK_AUIPC 0x7f
+#define MATCH_ADDI 0x13
+#define MASK_ADDI 0x707f
+#define MATCH_SLLI 0x1013
+#define MASK_SLLI 0xfc00707f
+#define MATCH_SLTI 0x2013
+#define MASK_SLTI 0x707f
+#define MATCH_SLTIU 0x3013
+#define MASK_SLTIU 0x707f
+#define MATCH_XORI 0x4013
+#define MASK_XORI 0x707f
+#define MATCH_SRLI 0x5013
+#define MASK_SRLI 0xfc00707f
+#define MATCH_SRAI 0x40005013
+#define MASK_SRAI 0xfc00707f
+#define MATCH_ORI 0x6013
+#define MASK_ORI 0x707f
+#define MATCH_ANDI 0x7013
+#define MASK_ANDI 0x707f
+#define MATCH_ADD 0x33
+#define MASK_ADD 0xfe00707f
+#define MATCH_SUB 0x40000033
+#define MASK_SUB 0xfe00707f
+#define MATCH_SLL 0x1033
+#define MASK_SLL 0xfe00707f
+#define MATCH_SLT 0x2033
+#define MASK_SLT 0xfe00707f
+#define MATCH_SLTU 0x3033
+#define MASK_SLTU 0xfe00707f
+#define MATCH_XOR 0x4033
+#define MASK_XOR 0xfe00707f
+#define MATCH_SRL 0x5033
+#define MASK_SRL 0xfe00707f
+#define MATCH_SRA 0x40005033
+#define MASK_SRA 0xfe00707f
+#define MATCH_OR 0x6033
+#define MASK_OR 0xfe00707f
+#define MATCH_AND 0x7033
+#define MASK_AND 0xfe00707f
+#define MATCH_ADDIW 0x1b
+#define MASK_ADDIW 0x707f
+#define MATCH_SLLIW 0x101b
+#define MASK_SLLIW 0xfe00707f
+#define MATCH_SRLIW 0x501b
+#define MASK_SRLIW 0xfe00707f
+#define MATCH_SRAIW 0x4000501b
+#define MASK_SRAIW 0xfe00707f
+#define MATCH_ADDW 0x3b
+#define MASK_ADDW 0xfe00707f
+#define MATCH_SUBW 0x4000003b
+#define MASK_SUBW 0xfe00707f
+#define MATCH_SLLW 0x103b
+#define MASK_SLLW 0xfe00707f
+#define MATCH_SRLW 0x503b
+#define MASK_SRLW 0xfe00707f
+#define MATCH_SRAW 0x4000503b
+#define MASK_SRAW 0xfe00707f
+#define MATCH_LB 0x3
+#define MASK_LB 0x707f
+#define MATCH_LH 0x1003
+#define MASK_LH 0x707f
+#define MATCH_LW 0x2003
+#define MASK_LW 0x707f
+#define MATCH_LD 0x3003
+#define MASK_LD 0x707f
+#define MATCH_LBU 0x4003
+#define MASK_LBU 0x707f
+#define MATCH_LHU 0x5003
+#define MASK_LHU 0x707f
+#define MATCH_LWU 0x6003
+#define MASK_LWU 0x707f
+#define MATCH_SB 0x23
+#define MASK_SB 0x707f
+#define MATCH_SH 0x1023
+#define MASK_SH 0x707f
+#define MATCH_SW 0x2023
+#define MASK_SW 0x707f
+#define MATCH_SD 0x3023
+#define MASK_SD 0x707f
+#define MATCH_FENCE 0xf
+#define MASK_FENCE 0x707f
+#define MATCH_FENCE_I 0x100f
+#define MASK_FENCE_I 0x707f
+#define MATCH_MUL 0x2000033
+#define MASK_MUL 0xfe00707f
+#define MATCH_MULH 0x2001033
+#define MASK_MULH 0xfe00707f
+#define MATCH_MULHSU 0x2002033
+#define MASK_MULHSU 0xfe00707f
+#define MATCH_MULHU 0x2003033
+#define MASK_MULHU 0xfe00707f
+#define MATCH_DIV 0x2004033
+#define MASK_DIV 0xfe00707f
+#define MATCH_DIVU 0x2005033
+#define MASK_DIVU 0xfe00707f
+#define MATCH_REM 0x2006033
+#define MASK_REM 0xfe00707f
+#define MATCH_REMU 0x2007033
+#define MASK_REMU 0xfe00707f
+#define MATCH_MULW 0x200003b
+#define MASK_MULW 0xfe00707f
+#define MATCH_DIVW 0x200403b
+#define MASK_DIVW 0xfe00707f
+#define MATCH_DIVUW 0x200503b
+#define MASK_DIVUW 0xfe00707f
+#define MATCH_REMW 0x200603b
+#define MASK_REMW 0xfe00707f
+#define MATCH_REMUW 0x200703b
+#define MASK_REMUW 0xfe00707f
+#define MATCH_AMOADD_W 0x202f
+#define MASK_AMOADD_W 0xf800707f
+#define MATCH_AMOXOR_W 0x2000202f
+#define MASK_AMOXOR_W 0xf800707f
+#define MATCH_AMOOR_W 0x4000202f
+#define MASK_AMOOR_W 0xf800707f
+#define MATCH_AMOAND_W 0x6000202f
+#define MASK_AMOAND_W 0xf800707f
+#define MATCH_AMOMIN_W 0x8000202f
+#define MASK_AMOMIN_W 0xf800707f
+#define MATCH_AMOMAX_W 0xa000202f
+#define MASK_AMOMAX_W 0xf800707f
+#define MATCH_AMOMINU_W 0xc000202f
+#define MASK_AMOMINU_W 0xf800707f
+#define MATCH_AMOMAXU_W 0xe000202f
+#define MASK_AMOMAXU_W 0xf800707f
+#define MATCH_AMOSWAP_W 0x800202f
+#define MASK_AMOSWAP_W 0xf800707f
+#define MATCH_LR_W 0x1000202f
+#define MASK_LR_W 0xf9f0707f
+#define MATCH_SC_W 0x1800202f
+#define MASK_SC_W 0xf800707f
+#define MATCH_AMOADD_D 0x302f
+#define MASK_AMOADD_D 0xf800707f
+#define MATCH_AMOXOR_D 0x2000302f
+#define MASK_AMOXOR_D 0xf800707f
+#define MATCH_AMOOR_D 0x4000302f
+#define MASK_AMOOR_D 0xf800707f
+#define MATCH_AMOAND_D 0x6000302f
+#define MASK_AMOAND_D 0xf800707f
+#define MATCH_AMOMIN_D 0x8000302f
+#define MASK_AMOMIN_D 0xf800707f
+#define MATCH_AMOMAX_D 0xa000302f
+#define MASK_AMOMAX_D 0xf800707f
+#define MATCH_AMOMINU_D 0xc000302f
+#define MASK_AMOMINU_D 0xf800707f
+#define MATCH_AMOMAXU_D 0xe000302f
+#define MASK_AMOMAXU_D 0xf800707f
+#define MATCH_AMOSWAP_D 0x800302f
+#define MASK_AMOSWAP_D 0xf800707f
+#define MATCH_LR_D 0x1000302f
+#define MASK_LR_D 0xf9f0707f
+#define MATCH_SC_D 0x1800302f
+#define MASK_SC_D 0xf800707f
+#define MATCH_ECALL 0x73
+#define MASK_ECALL 0xffffffff
+#define MATCH_EBREAK 0x100073
+#define MASK_EBREAK 0xffffffff
+#define MATCH_URET 0x200073
+#define MASK_URET 0xffffffff
+#define MATCH_SRET 0x10200073
+#define MASK_SRET 0xffffffff
+#define MATCH_HRET 0x20200073
+#define MASK_HRET 0xffffffff
+#define MATCH_MRET 0x30200073
+#define MASK_MRET 0xffffffff
+#define MATCH_DRET 0x7b200073
+#define MASK_DRET 0xffffffff
+#define MATCH_SFENCE_VMA 0x12000073
+#define MASK_SFENCE_VMA 0xfe007fff
+#define MATCH_WFI 0x10500073
+#define MASK_WFI 0xffffffff
+#define MATCH_CSRRW 0x1073
+#define MASK_CSRRW 0x707f
+#define MATCH_CSRRS 0x2073
+#define MASK_CSRRS 0x707f
+#define MATCH_CSRRC 0x3073
+#define MASK_CSRRC 0x707f
+#define MATCH_CSRRWI 0x5073
+#define MASK_CSRRWI 0x707f
+#define MATCH_CSRRSI 0x6073
+#define MASK_CSRRSI 0x707f
+#define MATCH_CSRRCI 0x7073
+#define MASK_CSRRCI 0x707f
+#define MATCH_FADD_S 0x53
+#define MASK_FADD_S 0xfe00007f
+#define MATCH_FSUB_S 0x8000053
+#define MASK_FSUB_S 0xfe00007f
+#define MATCH_FMUL_S 0x10000053
+#define MASK_FMUL_S 0xfe00007f
+#define MATCH_FDIV_S 0x18000053
+#define MASK_FDIV_S 0xfe00007f
+#define MATCH_FSGNJ_S 0x20000053
+#define MASK_FSGNJ_S 0xfe00707f
+#define MATCH_FSGNJN_S 0x20001053
+#define MASK_FSGNJN_S 0xfe00707f
+#define MATCH_FSGNJX_S 0x20002053
+#define MASK_FSGNJX_S 0xfe00707f
+#define MATCH_FMIN_S 0x28000053
+#define MASK_FMIN_S 0xfe00707f
+#define MATCH_FMAX_S 0x28001053
+#define MASK_FMAX_S 0xfe00707f
+#define MATCH_FSQRT_S 0x58000053
+#define MASK_FSQRT_S 0xfff0007f
+#define MATCH_FADD_D 0x2000053
+#define MASK_FADD_D 0xfe00007f
+#define MATCH_FSUB_D 0xa000053
+#define MASK_FSUB_D 0xfe00007f
+#define MATCH_FMUL_D 0x12000053
+#define MASK_FMUL_D 0xfe00007f
+#define MATCH_FDIV_D 0x1a000053
+#define MASK_FDIV_D 0xfe00007f
+#define MATCH_FSGNJ_D 0x22000053
+#define MASK_FSGNJ_D 0xfe00707f
+#define MATCH_FSGNJN_D 0x22001053
+#define MASK_FSGNJN_D 0xfe00707f
+#define MATCH_FSGNJX_D 0x22002053
+#define MASK_FSGNJX_D 0xfe00707f
+#define MATCH_FMIN_D 0x2a000053
+#define MASK_FMIN_D 0xfe00707f
+#define MATCH_FMAX_D 0x2a001053
+#define MASK_FMAX_D 0xfe00707f
+#define MATCH_FCVT_S_D 0x40100053
+#define MASK_FCVT_S_D 0xfff0007f
+#define MATCH_FCVT_D_S 0x42000053
+#define MASK_FCVT_D_S 0xfff0007f
+#define MATCH_FSQRT_D 0x5a000053
+#define MASK_FSQRT_D 0xfff0007f
+#define MATCH_FADD_Q 0x6000053
+#define MASK_FADD_Q 0xfe00007f
+#define MATCH_FSUB_Q 0xe000053
+#define MASK_FSUB_Q 0xfe00007f
+#define MATCH_FMUL_Q 0x16000053
+#define MASK_FMUL_Q 0xfe00007f
+#define MATCH_FDIV_Q 0x1e000053
+#define MASK_FDIV_Q 0xfe00007f
+#define MATCH_FSGNJ_Q 0x26000053
+#define MASK_FSGNJ_Q 0xfe00707f
+#define MATCH_FSGNJN_Q 0x26001053
+#define MASK_FSGNJN_Q 0xfe00707f
+#define MATCH_FSGNJX_Q 0x26002053
+#define MASK_FSGNJX_Q 0xfe00707f
+#define MATCH_FMIN_Q 0x2e000053
+#define MASK_FMIN_Q 0xfe00707f
+#define MATCH_FMAX_Q 0x2e001053
+#define MASK_FMAX_Q 0xfe00707f
+#define MATCH_FCVT_S_Q 0x40300053
+#define MASK_FCVT_S_Q 0xfff0007f
+#define MATCH_FCVT_Q_S 0x46000053
+#define MASK_FCVT_Q_S 0xfff0007f
+#define MATCH_FCVT_D_Q 0x42300053
+#define MASK_FCVT_D_Q 0xfff0007f
+#define MATCH_FCVT_Q_D 0x46100053
+#define MASK_FCVT_Q_D 0xfff0007f
+#define MATCH_FSQRT_Q 0x5e000053
+#define MASK_FSQRT_Q 0xfff0007f
+#define MATCH_FLE_S 0xa0000053
+#define MASK_FLE_S 0xfe00707f
+#define MATCH_FLT_S 0xa0001053
+#define MASK_FLT_S 0xfe00707f
+#define MATCH_FEQ_S 0xa0002053
+#define MASK_FEQ_S 0xfe00707f
+#define MATCH_FLE_D 0xa2000053
+#define MASK_FLE_D 0xfe00707f
+#define MATCH_FLT_D 0xa2001053
+#define MASK_FLT_D 0xfe00707f
+#define MATCH_FEQ_D 0xa2002053
+#define MASK_FEQ_D 0xfe00707f
+#define MATCH_FLE_Q 0xa6000053
+#define MASK_FLE_Q 0xfe00707f
+#define MATCH_FLT_Q 0xa6001053
+#define MASK_FLT_Q 0xfe00707f
+#define MATCH_FEQ_Q 0xa6002053
+#define MASK_FEQ_Q 0xfe00707f
+#define MATCH_FCVT_W_S 0xc0000053
+#define MASK_FCVT_W_S 0xfff0007f
+#define MATCH_FCVT_WU_S 0xc0100053
+#define MASK_FCVT_WU_S 0xfff0007f
+#define MATCH_FCVT_L_S 0xc0200053
+#define MASK_FCVT_L_S 0xfff0007f
+#define MATCH_FCVT_LU_S 0xc0300053
+#define MASK_FCVT_LU_S 0xfff0007f
+#define MATCH_FMV_X_S 0xe0000053
+#define MASK_FMV_X_S 0xfff0707f
+#define MATCH_FCLASS_S 0xe0001053
+#define MASK_FCLASS_S 0xfff0707f
+#define MATCH_FCVT_W_D 0xc2000053
+#define MASK_FCVT_W_D 0xfff0007f
+#define MATCH_FCVT_WU_D 0xc2100053
+#define MASK_FCVT_WU_D 0xfff0007f
+#define MATCH_FCVT_L_D 0xc2200053
+#define MASK_FCVT_L_D 0xfff0007f
+#define MATCH_FCVT_LU_D 0xc2300053
+#define MASK_FCVT_LU_D 0xfff0007f
+#define MATCH_FMV_X_D 0xe2000053
+#define MASK_FMV_X_D 0xfff0707f
+#define MATCH_FCLASS_D 0xe2001053
+#define MASK_FCLASS_D 0xfff0707f
+#define MATCH_FCVT_W_Q 0xc6000053
+#define MASK_FCVT_W_Q 0xfff0007f
+#define MATCH_FCVT_WU_Q 0xc6100053
+#define MASK_FCVT_WU_Q 0xfff0007f
+#define MATCH_FCVT_L_Q 0xc6200053
+#define MASK_FCVT_L_Q 0xfff0007f
+#define MATCH_FCVT_LU_Q 0xc6300053
+#define MASK_FCVT_LU_Q 0xfff0007f
+#define MATCH_FMV_X_Q 0xe6000053
+#define MASK_FMV_X_Q 0xfff0707f
+#define MATCH_FCLASS_Q 0xe6001053
+#define MASK_FCLASS_Q 0xfff0707f
+#define MATCH_FCVT_S_W 0xd0000053
+#define MASK_FCVT_S_W 0xfff0007f
+#define MATCH_FCVT_S_WU 0xd0100053
+#define MASK_FCVT_S_WU 0xfff0007f
+#define MATCH_FCVT_S_L 0xd0200053
+#define MASK_FCVT_S_L 0xfff0007f
+#define MATCH_FCVT_S_LU 0xd0300053
+#define MASK_FCVT_S_LU 0xfff0007f
+#define MATCH_FMV_S_X 0xf0000053
+#define MASK_FMV_S_X 0xfff0707f
+#define MATCH_FCVT_D_W 0xd2000053
+#define MASK_FCVT_D_W 0xfff0007f
+#define MATCH_FCVT_D_WU 0xd2100053
+#define MASK_FCVT_D_WU 0xfff0007f
+#define MATCH_FCVT_D_L 0xd2200053
+#define MASK_FCVT_D_L 0xfff0007f
+#define MATCH_FCVT_D_LU 0xd2300053
+#define MASK_FCVT_D_LU 0xfff0007f
+#define MATCH_FMV_D_X 0xf2000053
+#define MASK_FMV_D_X 0xfff0707f
+#define MATCH_FCVT_Q_W 0xd6000053
+#define MASK_FCVT_Q_W 0xfff0007f
+#define MATCH_FCVT_Q_WU 0xd6100053
+#define MASK_FCVT_Q_WU 0xfff0007f
+#define MATCH_FCVT_Q_L 0xd6200053
+#define MASK_FCVT_Q_L 0xfff0007f
+#define MATCH_FCVT_Q_LU 0xd6300053
+#define MASK_FCVT_Q_LU 0xfff0007f
+#define MATCH_FMV_Q_X 0xf6000053
+#define MASK_FMV_Q_X 0xfff0707f
+#define MATCH_FLW 0x2007
+#define MASK_FLW 0x707f
+#define MATCH_FLD 0x3007
+#define MASK_FLD 0x707f
+#define MATCH_FLQ 0x4007
+#define MASK_FLQ 0x707f
+#define MATCH_FSW 0x2027
+#define MASK_FSW 0x707f
+#define MATCH_FSD 0x3027
+#define MASK_FSD 0x707f
+#define MATCH_FSQ 0x4027
+#define MASK_FSQ 0x707f
+#define MATCH_FMADD_S 0x43
+#define MASK_FMADD_S 0x600007f
+#define MATCH_FMSUB_S 0x47
+#define MASK_FMSUB_S 0x600007f
+#define MATCH_FNMSUB_S 0x4b
+#define MASK_FNMSUB_S 0x600007f
+#define MATCH_FNMADD_S 0x4f
+#define MASK_FNMADD_S 0x600007f
+#define MATCH_FMADD_D 0x2000043
+#define MASK_FMADD_D 0x600007f
+#define MATCH_FMSUB_D 0x2000047
+#define MASK_FMSUB_D 0x600007f
+#define MATCH_FNMSUB_D 0x200004b
+#define MASK_FNMSUB_D 0x600007f
+#define MATCH_FNMADD_D 0x200004f
+#define MASK_FNMADD_D 0x600007f
+#define MATCH_FMADD_Q 0x6000043
+#define MASK_FMADD_Q 0x600007f
+#define MATCH_FMSUB_Q 0x6000047
+#define MASK_FMSUB_Q 0x600007f
+#define MATCH_FNMSUB_Q 0x600004b
+#define MASK_FNMSUB_Q 0x600007f
+#define MATCH_FNMADD_Q 0x600004f
+#define MASK_FNMADD_Q 0x600007f
+#define MATCH_C_NOP 0x1
+#define MASK_C_NOP 0xffff
+#define MATCH_C_ADDI16SP 0x6101
+#define MASK_C_ADDI16SP 0xef83
+#define MATCH_C_JR 0x8002
+#define MASK_C_JR 0xf07f
+#define MATCH_C_JALR 0x9002
+#define MASK_C_JALR 0xf07f
+#define MATCH_C_EBREAK 0x9002
+#define MASK_C_EBREAK 0xffff
+#define MATCH_C_LD 0x6000
+#define MASK_C_LD 0xe003
+#define MATCH_C_SD 0xe000
+#define MASK_C_SD 0xe003
+#define MATCH_C_ADDIW 0x2001
+#define MASK_C_ADDIW 0xe003
+#define MATCH_C_LDSP 0x6002
+#define MASK_C_LDSP 0xe003
+#define MATCH_C_SDSP 0xe002
+#define MASK_C_SDSP 0xe003
+#define MATCH_C_ADDI4SPN 0x0
+#define MASK_C_ADDI4SPN 0xe003
+#define MATCH_C_FLD 0x2000
+#define MASK_C_FLD 0xe003
+#define MATCH_C_LW 0x4000
+#define MASK_C_LW 0xe003
+#define MATCH_C_FLW 0x6000
+#define MASK_C_FLW 0xe003
+#define MATCH_C_FSD 0xa000
+#define MASK_C_FSD 0xe003
+#define MATCH_C_SW 0xc000
+#define MASK_C_SW 0xe003
+#define MATCH_C_FSW 0xe000
+#define MASK_C_FSW 0xe003
+#define MATCH_C_ADDI 0x1
+#define MASK_C_ADDI 0xe003
+#define MATCH_C_JAL 0x2001
+#define MASK_C_JAL 0xe003
+#define MATCH_C_LI 0x4001
+#define MASK_C_LI 0xe003
+#define MATCH_C_LUI 0x6001
+#define MASK_C_LUI 0xe003
+#define MATCH_C_SRLI 0x8001
+#define MASK_C_SRLI 0xec03
+#define MATCH_C_SRAI 0x8401
+#define MASK_C_SRAI 0xec03
+#define MATCH_C_ANDI 0x8801
+#define MASK_C_ANDI 0xec03
+#define MATCH_C_SUB 0x8c01
+#define MASK_C_SUB 0xfc63
+#define MATCH_C_XOR 0x8c21
+#define MASK_C_XOR 0xfc63
+#define MATCH_C_OR 0x8c41
+#define MASK_C_OR 0xfc63
+#define MATCH_C_AND 0x8c61
+#define MASK_C_AND 0xfc63
+#define MATCH_C_SUBW 0x9c01
+#define MASK_C_SUBW 0xfc63
+#define MATCH_C_ADDW 0x9c21
+#define MASK_C_ADDW 0xfc63
+#define MATCH_C_J 0xa001
+#define MASK_C_J 0xe003
+#define MATCH_C_BEQZ 0xc001
+#define MASK_C_BEQZ 0xe003
+#define MATCH_C_BNEZ 0xe001
+#define MASK_C_BNEZ 0xe003
+#define MATCH_C_SLLI 0x2
+#define MASK_C_SLLI 0xe003
+#define MATCH_C_FLDSP 0x2002
+#define MASK_C_FLDSP 0xe003
+#define MATCH_C_LWSP 0x4002
+#define MASK_C_LWSP 0xe003
+#define MATCH_C_FLWSP 0x6002
+#define MASK_C_FLWSP 0xe003
+#define MATCH_C_MV 0x8002
+#define MASK_C_MV 0xf003
+#define MATCH_C_ADD 0x9002
+#define MASK_C_ADD 0xf003
+#define MATCH_C_FSDSP 0xa002
+#define MASK_C_FSDSP 0xe003
+#define MATCH_C_SWSP 0xc002
+#define MASK_C_SWSP 0xe003
+#define MATCH_C_FSWSP 0xe002
+#define MASK_C_FSWSP 0xe003
+#define MATCH_CUSTOM0 0xb
+#define MASK_CUSTOM0 0x707f
+#define MATCH_CUSTOM0_RS1 0x200b
+#define MASK_CUSTOM0_RS1 0x707f
+#define MATCH_CUSTOM0_RS1_RS2 0x300b
+#define MASK_CUSTOM0_RS1_RS2 0x707f
+#define MATCH_CUSTOM0_RD 0x400b
+#define MASK_CUSTOM0_RD 0x707f
+#define MATCH_CUSTOM0_RD_RS1 0x600b
+#define MASK_CUSTOM0_RD_RS1 0x707f
+#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
+#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM1 0x2b
+#define MASK_CUSTOM1 0x707f
+#define MATCH_CUSTOM1_RS1 0x202b
+#define MASK_CUSTOM1_RS1 0x707f
+#define MATCH_CUSTOM1_RS1_RS2 0x302b
+#define MASK_CUSTOM1_RS1_RS2 0x707f
+#define MATCH_CUSTOM1_RD 0x402b
+#define MASK_CUSTOM1_RD 0x707f
+#define MATCH_CUSTOM1_RD_RS1 0x602b
+#define MASK_CUSTOM1_RD_RS1 0x707f
+#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
+#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM2 0x5b
+#define MASK_CUSTOM2 0x707f
+#define MATCH_CUSTOM2_RS1 0x205b
+#define MASK_CUSTOM2_RS1 0x707f
+#define MATCH_CUSTOM2_RS1_RS2 0x305b
+#define MASK_CUSTOM2_RS1_RS2 0x707f
+#define MATCH_CUSTOM2_RD 0x405b
+#define MASK_CUSTOM2_RD 0x707f
+#define MATCH_CUSTOM2_RD_RS1 0x605b
+#define MASK_CUSTOM2_RD_RS1 0x707f
+#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
+#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM3 0x7b
+#define MASK_CUSTOM3 0x707f
+#define MATCH_CUSTOM3_RS1 0x207b
+#define MASK_CUSTOM3_RS1 0x707f
+#define MATCH_CUSTOM3_RS1_RS2 0x307b
+#define MASK_CUSTOM3_RS1_RS2 0x707f
+#define MATCH_CUSTOM3_RD 0x407b
+#define MASK_CUSTOM3_RD 0x707f
+#define MATCH_CUSTOM3_RD_RS1 0x607b
+#define MASK_CUSTOM3_RD_RS1 0x707f
+#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
+#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_SSTATUS 0x100
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_SBADADDR 0x143
+#define CSR_SIP 0x144
+#define CSR_SPTBR 0x180
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MBADADDR 0x343
+#define CSR_MIP 0x344
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_SUPERVISOR_ECALL 0x9
+#define CAUSE_HYPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#endif
+#ifdef DECLARE_INSN
+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
+DECLARE_INSN(or, MATCH_OR, MASK_OR)
+DECLARE_INSN(and, MATCH_AND, MASK_AND)
+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
+DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
+DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
+DECLARE_INSN(uret, MATCH_URET, MASK_URET)
+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(hret, MATCH_HRET, MASK_HRET)
+DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
+DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
+DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)
+DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
+DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)
+DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)
+DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)
+DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)
+DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)
+DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)
+DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)
+DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)
+DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)
+DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)
+DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)
+DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)
+DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)
+DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)
+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
+DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)
+DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)
+DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)
+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
+DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
+DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)
+DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)
+DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)
+DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)
+DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
+DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)
+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
+DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
+DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
+DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
+DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
+DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
+DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
+DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
+DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)
+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
+DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
+DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
+DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
+DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
+DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
+DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
+DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
+DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
+DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)
+DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
+DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
+DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
+DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
+DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
+DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
+DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
+DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
+DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
+DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
+DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
+DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
+DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
+DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)
+DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
+DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
+DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
+DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
+DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)
+DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
+DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)
+DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)
+DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)
+DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
+DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
+DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
+DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
+DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
+DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
+DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)
+DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
+DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)
+DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
+DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
+DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)
+DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
+DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)
+DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
+DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
+DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
+DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
+DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
+DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
+DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
+DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
+DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
+DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
+DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
+DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
+DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
+DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
+DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
+DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
+DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
+DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
+DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
+DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
+DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
+DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
+DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
+DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
+#endif
+#ifdef DECLARE_CSR
+DECLARE_CSR(fflags, CSR_FFLAGS)
+DECLARE_CSR(frm, CSR_FRM)
+DECLARE_CSR(fcsr, CSR_FCSR)
+DECLARE_CSR(cycle, CSR_CYCLE)
+DECLARE_CSR(time, CSR_TIME)
+DECLARE_CSR(instret, CSR_INSTRET)
+DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)
+DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)
+DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)
+DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)
+DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)
+DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)
+DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)
+DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)
+DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)
+DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)
+DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)
+DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)
+DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)
+DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)
+DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)
+DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)
+DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)
+DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)
+DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)
+DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)
+DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)
+DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)
+DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)
+DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)
+DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)
+DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)
+DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)
+DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)
+DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
+DECLARE_CSR(sstatus, CSR_SSTATUS)
+DECLARE_CSR(sie, CSR_SIE)
+DECLARE_CSR(stvec, CSR_STVEC)
+DECLARE_CSR(scounteren, CSR_SCOUNTEREN)
+DECLARE_CSR(sscratch, CSR_SSCRATCH)
+DECLARE_CSR(sepc, CSR_SEPC)
+DECLARE_CSR(scause, CSR_SCAUSE)
+DECLARE_CSR(sbadaddr, CSR_SBADADDR)
+DECLARE_CSR(sip, CSR_SIP)
+DECLARE_CSR(sptbr, CSR_SPTBR)
+DECLARE_CSR(mstatus, CSR_MSTATUS)
+DECLARE_CSR(misa, CSR_MISA)
+DECLARE_CSR(medeleg, CSR_MEDELEG)
+DECLARE_CSR(mideleg, CSR_MIDELEG)
+DECLARE_CSR(mie, CSR_MIE)
+DECLARE_CSR(mtvec, CSR_MTVEC)
+DECLARE_CSR(mcounteren, CSR_MCOUNTEREN)
+DECLARE_CSR(mscratch, CSR_MSCRATCH)
+DECLARE_CSR(mepc, CSR_MEPC)
+DECLARE_CSR(mcause, CSR_MCAUSE)
+DECLARE_CSR(mbadaddr, CSR_MBADADDR)
+DECLARE_CSR(mip, CSR_MIP)
+DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
+DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
+DECLARE_CSR(pmpcfg2, CSR_PMPCFG2)
+DECLARE_CSR(pmpcfg3, CSR_PMPCFG3)
+DECLARE_CSR(pmpaddr0, CSR_PMPADDR0)
+DECLARE_CSR(pmpaddr1, CSR_PMPADDR1)
+DECLARE_CSR(pmpaddr2, CSR_PMPADDR2)
+DECLARE_CSR(pmpaddr3, CSR_PMPADDR3)
+DECLARE_CSR(pmpaddr4, CSR_PMPADDR4)
+DECLARE_CSR(pmpaddr5, CSR_PMPADDR5)
+DECLARE_CSR(pmpaddr6, CSR_PMPADDR6)
+DECLARE_CSR(pmpaddr7, CSR_PMPADDR7)
+DECLARE_CSR(pmpaddr8, CSR_PMPADDR8)
+DECLARE_CSR(pmpaddr9, CSR_PMPADDR9)
+DECLARE_CSR(pmpaddr10, CSR_PMPADDR10)
+DECLARE_CSR(pmpaddr11, CSR_PMPADDR11)
+DECLARE_CSR(pmpaddr12, CSR_PMPADDR12)
+DECLARE_CSR(pmpaddr13, CSR_PMPADDR13)
+DECLARE_CSR(pmpaddr14, CSR_PMPADDR14)
+DECLARE_CSR(pmpaddr15, CSR_PMPADDR15)
+DECLARE_CSR(tselect, CSR_TSELECT)
+DECLARE_CSR(tdata1, CSR_TDATA1)
+DECLARE_CSR(tdata2, CSR_TDATA2)
+DECLARE_CSR(tdata3, CSR_TDATA3)
+DECLARE_CSR(dcsr, CSR_DCSR)
+DECLARE_CSR(dpc, CSR_DPC)
+DECLARE_CSR(dscratch, CSR_DSCRATCH)
+DECLARE_CSR(mcycle, CSR_MCYCLE)
+DECLARE_CSR(minstret, CSR_MINSTRET)
+DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)
+DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)
+DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)
+DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)
+DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)
+DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)
+DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)
+DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)
+DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)
+DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)
+DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)
+DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)
+DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)
+DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)
+DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)
+DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)
+DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)
+DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)
+DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)
+DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)
+DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)
+DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)
+DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)
+DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)
+DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)
+DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
+DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
+DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
+DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
+DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
+DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
+DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
+DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)
+DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)
+DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)
+DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)
+DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)
+DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)
+DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)
+DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)
+DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)
+DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)
+DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)
+DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)
+DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)
+DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)
+DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)
+DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)
+DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)
+DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)
+DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)
+DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)
+DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)
+DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)
+DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)
+DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)
+DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)
+DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)
+DECLARE_CSR(mvendorid, CSR_MVENDORID)
+DECLARE_CSR(marchid, CSR_MARCHID)
+DECLARE_CSR(mimpid, CSR_MIMPID)
+DECLARE_CSR(mhartid, CSR_MHARTID)
+DECLARE_CSR(cycleh, CSR_CYCLEH)
+DECLARE_CSR(timeh, CSR_TIMEH)
+DECLARE_CSR(instreth, CSR_INSTRETH)
+DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)
+DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)
+DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)
+DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)
+DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)
+DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)
+DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)
+DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)
+DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)
+DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)
+DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)
+DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)
+DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)
+DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)
+DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)
+DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)
+DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)
+DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)
+DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)
+DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)
+DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)
+DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)
+DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)
+DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)
+DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)
+DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)
+DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)
+DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)
+DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)
+DECLARE_CSR(mcycleh, CSR_MCYCLEH)
+DECLARE_CSR(minstreth, CSR_MINSTRETH)
+DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)
+DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)
+DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)
+DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)
+DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)
+DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)
+DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)
+DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)
+DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)
+DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)
+DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)
+DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)
+DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)
+DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)
+DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)
+DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)
+DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)
+DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)
+DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)
+DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)
+DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)
+DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)
+DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)
+DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)
+DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)
+DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)
+DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)
+DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)
+DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
+#endif
+#ifdef DECLARE_CAUSE
+DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
+DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
+DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
+DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
+DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
+DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
+DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
+DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
+DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
+DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
+DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
+DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
+DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
+DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
+DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_assert.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_assert.h
new file mode 100644
index 00000000..ebd70632
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_assert.h
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+#ifndef HAL_ASSERT_HEADER
+#define HAL_ASSERT_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * ASSERT() implementation.
+ ******************************************************************************/
+/* Disable assertions if we do not recognize the compiler. */
+#if defined ( __GNUC__ )
+#if defined(NDEBUG)
+#define ASSERT(CHECK)
+#else
+#define ASSERT(CHECK)\
+ do { \
+ if (!(CHECK)) \
+ { \
+ __asm volatile ("ebreak"); \
+ }\
+ } while(0);
+#endif /* NDEBUG check */
+#endif /* compiler check */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_ASSERT_HEADER */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_axiswitch.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_axiswitch.c
new file mode 100644
index 00000000..c324cdbd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_axiswitch.c
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_axiswitch.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS AXI switch configuration
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*Returns the value of AXI_HW_CFG_REG register*/
+uint32_t MSS_AXISW_get_hwcfg(void)
+{
+ return (AXISW->HWCFG);
+}
+
+/*Returns the value of AXI_VERSION_ID_REG register*/
+uint32_t MSS_AXISW_get_vid(void)
+{
+ return (AXISW->VID);
+}
+
+/*Performs write operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+
+
+ Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+
+ Burstiness peak rate and transaction rate can be configured using other APIs.
+
+ data: QoS value to be programmed
+ return value: As received form AXI_ERR_BIT in CMD register.
+
+ * */
+uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t data)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = data & AXISW_DATA_QOSVAL_MASK; /*only valid values of bits[3:0]*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_QOS_VAL |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ * Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+ *
+ * returns the data returned by AXI SWITCH read operation for QoS command
+ *
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ */
+uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t* rd_data)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) | (MSS_AXISW_QOS_VAL) | AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *rd_data = AXISW->DATA & AXISW_DATA_QOSVAL_MASK;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the peak rate and transaction rate value for the given master port
+ read/write address channel
+
+ NOTE: Peak rate and transaction rate are programmed simultaneously in one command.
+ So we must make sure that both desired valid values must be provided.
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t peak_rate,
+ mss_axisw_rate_t xct_rate)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+ AXISW->DATA = ((peak_rate) << AXISW_DATA_PEAKRT) | ((xct_rate) << AXISW_DATA_XCTRT) ;
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the peak rate and transaction rate value for the given master port
+read/write address channel
+peak_rate: returns the value of peak rate
+xct_rate: returns the value of transaction rate
+return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t* peak_rate,
+ mss_axisw_rate_t* xct_rate)
+{
+ uint32_t temp = 0u;
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ temp = AXISW->DATA;
+
+ *peak_rate = (temp & AXISW_DATA_PEAKRT_MASK) >> AXISW_DATA_PEAKRT;
+ *xct_rate = (temp & AXISW_DATA_XCTRT_MASK) >> AXISW_DATA_XCTRT;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the burstiness value for the given master port read/write address channel
+
+burstiness_val: burstiness value to be programmed
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+regulator_en: QoS regulator Enable 1= enable, 0 = disable
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t burstiness_val,
+ uint32_t regulator_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ /*Write burstiness value and enable burstiness regulator.
+ * Burstiness_val=0 is not valid.
+ Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1*/
+
+ if(burstiness_val == 0)
+ {
+ return -1;
+ }
+ else
+ {
+ AXISW->DATA = ((burstiness_val - 1u) << AXISW_DATA_BURSTI) | (regulator_en & 0x01);
+ }
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the burstiness value for the given master port read/write address channel
+
+burstiness_val: Return parameter bit 23:16 shows the burstiness value.
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t* burstiness_val)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *burstiness_val = ((AXISW->DATA & AXISW_DATA_BURSTI_MASK) >> AXISW_DATA_BURSTI) + 1u;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t slave_ready_en)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = slave_ready_en & 0x01; /*only valid value of bit0*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_SLV_RDY |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ *
+ * slave_ready_en: returns the data returned by AXI SWITCH read operation for slave ready command
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ *
+ */
+uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t* slave_ready_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_SLV_RDY) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *slave_ready_en = AXISW->DATA & 0x01;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_axiswitch.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_axiswitch.h
new file mode 100644
index 00000000..437ea9bd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_axiswitch.h
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef __MSS_AXISW_H_
+#define __MSS_AXISW_H_ 1
+
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+
+ */
+
+typedef enum {
+ MSS_AXISW_FIC0_RD_CHAN = 0x000,
+ MSS_AXISW_FIC0_WR_CHAN,
+ MSS_AXISW_FIC1_RD_CHAN,
+ MSS_AXISW_FIC1_WR_CHAN,
+ MSS_AXISW_FIC2_RD_CHAN,
+ MSS_AXISW_FIC2_WR_CHAN,
+ MSS_AXISW_ATHENA_RD_CHAN,
+ MSS_AXISW_ATHENA_WR_CHAN,
+ MSS_AXISW_GEM0_RD_CHAN,
+ MSS_AXISW_GEM0_WR_CHAN,
+ MSS_AXISW_GEM1_RD_CHAN,
+ MSS_AXISW_GEM1_WR_CHAN,
+ MSS_AXISW_MMC_RD_CHAN,
+ MSS_AXISW_MMC_WR_CHAN,
+ MSS_AXISW_USB_RD_CHAN,
+ MSS_AXISW_USB_WR_CHAN,
+ MSS_AXISW_SCB_RD_CHAN,
+ MSS_AXISW_SCB_WR_CHAN,
+ MSS_AXISW_CPLEX_D0_RD_CHAN,
+ MSS_AXISW_CPLEX_D0_WR_CHAN,
+ MSS_AXISW_CPLEX_D1_RD_CHAN,
+ MSS_AXISW_CPLEX_D1_WR_CHAN,
+ MSS_AXISW_CPLEX_F0_RD_CHAN,
+ MSS_AXISW_CPLEX_F0_WR_CHAN,
+ MSS_AXISW_CPLEX_F1_RD_CHAN,
+ MSS_AXISW_CPLEX_F1_WR_CHAN,
+ MSS_AXISW_CPLEX_NC_RD_CHAN,
+ MSS_AXISW_CPLEX_NC_WR_CHAN,
+ MSS_AXISW_TRACE_RD_CHAN,
+ MSS_AXISW_TRACE_WR_CHAN,
+} mss_axisw_mport_t;
+
+
+typedef enum {
+ MSS_AXISW_BURSTINESS_EN = 0x00,
+ MSS_AXISW_PEAKRT_XCTRT,
+ MSS_AXISW_QOS_VAL,
+ MSS_AXISW_SLV_RDY,
+} mss_axisw_cmd_t;
+
+typedef enum {
+ MSS_AXISW_MASTER_RD_CHAN = 0x00,
+ MSS_AXISW_MASTER_WR_CHAN = 0x01,
+} mss_axisw_mchan_t;
+
+/*
+The Peak rate and transaction rates are encoded as follows.
+1000_0000_0000 1/2
+0100_0000_0000 1/4
+0010_0000_0000 1/8
+0001_0000_0000 1/16
+0000_1000_0000 1/32
+0000_0100_0000 1/64
+0000_0010_0000 1/128
+0000_0001_0000 1/256
+0000_0000_1000 1/512
+0000_0000_0100 1/1024
+0000_0000_0010 1/2048
+0000_0000_0001 1/4096
+
+Programming the transaction rate as 0000_0000_0000 disables token generation and
+traffic is not regulated based on the tokens.
+
+Programming the peak rate as 0000_0000_0000 disables the peak rate control logic and
+traffic is not regulated by the peak rate logic.
+*/
+typedef enum {
+ MSS_AXISW_TXNRATE_BY4096 = 0x001,
+ MSS_AXISW_TXNRATE_BY2098 = 0x002,
+ MSS_AXISW_TXNRATE_BY1024 = 0x004,
+ MSS_AXISW_TXNRATE_BY512 = 0x008,
+ MSS_AXISW_TXNRATE_BY256 = 0x010,
+ MSS_AXISW_TXNRATE_BY128 = 0x020,
+ MSS_AXISW_TXNRATE_BY64 = 0x040,
+ MSS_AXISW_TXNRATE_BY32 = 0x080,
+ MSS_AXISW_TXNRATE_BY16 = 0x100,
+ MSS_AXISW_TXNRATE_BY8 = 0x200,
+ MSS_AXISW_TXNRATE_BY4 = 0x400,
+ MSS_AXISW_TXNRATE_BY2 = 0x800,
+ MSS_AXISW_TXNRATE_DISABLE = 0x0,
+} mss_axisw_rate_t;
+
+#define AXISW_CMD_EN 31U
+#define AXISW_CMD_EN_MASK (uint32_t)(0x01U << AXISW_CMD_EN)
+
+#define AXISW_CMD_RW 30U
+#define AXISW_CMD_RW_MASK (uint32_t)(0x01U << AXISW_CMD_RW)
+
+#define AXISW_CMD_SWRST 29U
+#define AXISW_CMD_SWRST_MASK (uint32_t)(0x01U << AXISW_CMD_SWRST)
+
+#define AXISW_CMD_ERR 28U
+#define AXISW_CMD_ERR_MASK (uint32_t)(0x01U << AXISW_CMD_ERR)
+
+//#define AXISW_CMD_MPORT 8U
+//#define AXISW_CMD_MPORT_MASK (0x0F << AXISW_CMD_MPORT)
+
+#define AXISW_CMD_RWCHAN 7U
+#define AXISW_CMD_RWCHAN_MASK (uint32_t)(0x1F << AXISW_CMD_RWCHAN)
+
+#define AXISW_CMD_CMD 0U
+#define AXISW_CMD_CMD_MASK (0x01U << AXISW_CMD_CMD)
+
+#define AXISW_DATA_PEAKRT 20U
+#define AXISW_DATA_PEAKRT_MASK (0xFFFU << AXISW_DATA_PEAKRT)
+
+#define AXISW_DATA_XCTRT 4U
+#define AXISW_DATA_XCTRT_MASK (0xFFFU << AXISW_DATA_XCTRT)
+
+#define AXISW_DATA_BURSTI 16U
+#define AXISW_DATA_BURSTI_MASK (0xFFU << AXISW_DATA_BURSTI)
+
+#define AXISW_DATA_QOSVAL 0U
+#define AXISW_DATA_QOSVAL_MASK (0xFU << AXISW_DATA_QOSVAL)
+
+typedef struct
+{
+ __IO uint32_t VID;
+ __IO uint32_t HWCFG;
+ __IO uint32_t CMD;
+ __IO uint32_t DATA;
+} AXISW_TypeDef;
+
+
+#define AXISW ((AXISW_TypeDef*)0x20004000UL)
+
+
+uint32_t MSS_AXISW_get_hwcfg(void);
+uint32_t MSS_AXISW_get_vid(void);
+uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t data);
+uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t* rd_data);
+uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t peak_rate,
+ mss_axisw_rate_t xct_rate);
+uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t* peak_rate,
+ mss_axisw_rate_t* xct_rate);
+int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t burstiness_val,
+ uint32_t regulator_en);
+uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t* burstiness_val);
+uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t slave_ready_en);
+uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t* slave_ready_en);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_AXISW_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_clint.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_clint.c
new file mode 100644
index 00000000..cd1558ac
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_clint.c
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_clint.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief CLINT access data structures and functions.
+ *
+ */
+#include
+#include "mpfs_hal/mss_hal.h"
+
+static uint64_t g_systick_increment[5] = {0ULL,0ULL,0ULL,0ULL,0ULL};
+
+/**
+ * call once at startup
+ * @return
+ */
+void reset_mtime(void)
+{
+#if ROLLOVER_TEST
+ CLINT->MTIME = 0xFFFFFFFFFFFFF000ULL;
+#else
+ CLINT->MTIME = 0ULL;
+#endif
+}
+
+/**
+ * readmtime
+ * @return mtime
+ */
+uint64_t readmtime(void)
+{
+ return (CLINT->MTIME);
+}
+
+/**
+ * Configure system tick
+ * @return SUCCESS or FAIL
+ */
+uint32_t SysTick_Config(void)
+{
+ const uint32_t tick_rate[5] = {HART0_TICK_RATE_MS, HART1_TICK_RATE_MS ,HART2_TICK_RATE_MS ,HART3_TICK_RATE_MS ,HART4_TICK_RATE_MS};
+ volatile uint32_t ret_val = ERROR;
+
+ uint64_t mhart_id = read_csr(mhartid);
+
+ /*
+ * We are assuming the tick rate is in milli-seconds
+ *
+ * convert RTC frequency into milliseconds and multiple by the tick rate
+ *
+ */
+
+ g_systick_increment[mhart_id] = ((LIBERO_SETTING_MSS_RTC_TOGGLE_CLK/1000U) * tick_rate[mhart_id]);
+
+ if (g_systick_increment[mhart_id] > 0ULL)
+ {
+
+ CLINT->MTIMECMP[mhart_id] = CLINT->MTIME + g_systick_increment[mhart_id];
+
+ set_csr(mie, MIP_MTIP); /* mie Register - Machine Timer Interrupt Enable */
+
+ __enable_irq();
+
+ ret_val = SUCCESS;
+ }
+
+ return (ret_val);
+}
+
+/**
+ * Disable system tick interrupt
+ */
+void disable_systick(void)
+{
+ clear_csr(mie, MIP_MTIP); /* mie Register - Machine Timer Interrupt Enable */
+ return;
+}
+
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for machine timer interrupts.
+ */
+void handle_m_timer_interrupt(void)
+{
+
+ volatile uint64_t hart_id = read_csr(mhartid);
+ volatile uint32_t error_loop;
+ clear_csr(mie, MIP_MTIP);
+
+ switch(hart_id)
+ {
+ case 0U:
+ SysTick_Handler_h0_IRQHandler();
+ break;
+ case 1U:
+ SysTick_Handler_h1_IRQHandler();
+ break;
+ case 2U:
+ SysTick_Handler_h2_IRQHandler();
+ break;
+ case 3U:
+ SysTick_Handler_h3_IRQHandler();
+ break;
+ case 4U:
+ SysTick_Handler_h4_IRQHandler();
+ break;
+ default:
+ while (hart_id != 0U)
+ {
+ error_loop++;
+ }
+ break;
+ }
+
+ CLINT->MTIMECMP[read_csr(mhartid)] = CLINT->MTIME + g_systick_increment[hart_id];
+
+ set_csr(mie, MIP_MTIP);
+
+}
+
+
+/**
+ *
+ */
+void handle_m_soft_interrupt(void)
+{
+ volatile uint64_t hart_id = read_csr(mhartid);
+ volatile uint32_t error_loop;
+
+ switch(hart_id)
+ {
+ case 0U:
+ Software_h0_IRQHandler();
+ break;
+ case 1U:
+ Software_h1_IRQHandler();
+ break;
+ case 2U:
+ Software_h2_IRQHandler();
+ break;
+ case 3U:
+ Software_h3_IRQHandler();
+ break;
+ case 4U:
+ Software_h4_IRQHandler();
+ break;
+ default:
+ while (hart_id != 0U)
+ {
+ error_loop++;
+ }
+ break;
+ }
+
+ /*Clear software interrupt*/
+ clear_soft_interrupt();
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_clint.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_clint.h
new file mode 100644
index 00000000..86b4a1cd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_clint.h
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_clint.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief CLINT access data structures and functions.
+ *
+ */
+#ifndef MSS_CLINT_H
+#define MSS_CLINT_H
+
+#include
+#include "encoding.h"
+#include "atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTC_PRESCALER 100U
+#define SUCCESS 0U
+#define ERROR 1U
+
+
+/*==============================================================================
+ * CLINT: Core Local Interrupter
+ */
+typedef struct CLINT_Type_t
+{
+ volatile uint32_t MSIP[5];
+ volatile uint32_t reserved1[(0x4000U - 0x14U)/4U];
+ volatile uint64_t MTIMECMP[5]; /* mtime compare value for each hart. When mtime equals this value, interrupt is generated for particular hart */
+ volatile uint32_t reserved2[((0xbff8U - 0x4028U)/4U)];
+ volatile uint64_t MTIME; /* contains the current mtime value */
+} CLINT_Type;
+
+#define CLINT ((CLINT_Type *)CLINT_BASE)
+
+
+/*==============================================================================
+ * The function raise_soft_interrupt() raises a synchronous software interrupt by
+ * writing into the MSIP register.
+ */
+static inline void raise_soft_interrupt(unsigned long hart_id)
+{
+ /*You need to make sure that the global interrupt is enabled*/
+ /*Note: set_csr(mie, MIP_MSIP) needs to be set on hart you are setting sw interrupt */
+ CLINT->MSIP[hart_id] = 0x01U; /*raise soft interrupt for hart(x) where x== hart ID*/
+ mb();
+}
+
+/*==============================================================================
+ * The function clear_soft_interrupt() clears a synchronous software interrupt by
+ * clearing the MSIP register.
+ */
+static inline void clear_soft_interrupt(void)
+{
+ volatile uint32_t reg;
+ uint64_t hart_id = read_csr(mhartid);
+ CLINT->MSIP[hart_id] = 0x00U; /*clear soft interrupt for hart0*/
+ reg = CLINT->MSIP[hart_id]; /* we read back to make sure it has been written before moving on */
+ /* todo: verify line above guaranteed and best way to achieve result */
+ (void)reg; /* use reg to avoid compiler warning */
+}
+
+/*
+ * return mtime
+ */
+uint64_t readmtime(void);
+
+/**
+ * call once at startup
+ * @return
+ */
+void reset_mtime(void);
+
+/**
+ * Configure system tick
+ * @return SUCCESS or FAIL
+ */
+uint32_t SysTick_Config(void);
+
+/**
+ * Disable system tick interrupt
+ */
+void disable_systick(void);
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for machine timer interrupts.
+ */
+void handle_m_timer_interrupt(void);
+
+/**
+ *
+ */
+void handle_m_soft_interrupt(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_CLINT_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_h2f.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_h2f.c
new file mode 100644
index 00000000..2a1c10b5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_h2f.c
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_h2f.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief H2F access data structures and functions.
+ *
+ */
+#include "mss_plic.h"
+#include "mss_h2f.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+#define H2F_MAPPING_INVALID 255U
+
+/*==============================================================================
+ * H2F_int_mapping, source to H2F output lines
+ * The internal interrupt are multiplexed to fabric I/O lines.
+ * That is, each line will contain several interrupts.
+ */
+
+const uint8_t H2F_int_mapping[BUS_ERROR_UNIT_HART_4]= { \
+
+ H2F_MAPPING_INVALID /*INVALID_IRQn = 0*/, \
+ H2F_MAPPING_INVALID /*L2_METADATA_CORR_IRQn = 1*/, \
+ H2F_MAPPING_INVALID /*L2_METADAT_UNCORR_IRQn = 2*/, \
+ H2F_MAPPING_INVALID /*L2_DATA_CORR_IRQn = 3*/, \
+ H2F_MAPPING_INVALID /*L2_DATA_UNCORR_IRQn = 4*/, \
+ H2F_MAPPING_INVALID /*DMA_CH0_DONE_IRQn = 5*/, \
+ H2F_MAPPING_INVALID /*DMA_CH0_ERR_IRQn = 6*/, \
+ H2F_MAPPING_INVALID /*DMA_CH1_DONE_IRQn = 7*/, \
+ H2F_MAPPING_INVALID /*DMA_CH1_ERR_IRQn = 8*/, \
+ H2F_MAPPING_INVALID /*DMA_CH2_DONE_IRQn = 9*/, \
+ H2F_MAPPING_INVALID /*DMA_CH2_ERR_IRQn = 10*/, \
+ H2F_MAPPING_INVALID /*DMA_CH3_DONE_IRQn = 11*/, \
+ H2F_MAPPING_INVALID /*DMA_CH3_ERR_IRQn = 12*/, \
+
+ 0x00U /*GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0 = 0 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1 = 1 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2 = 2 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3 = 3 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4 = 4 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5 = 5 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6 = 6 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7 = 7 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8 = 8 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9 = 9 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10 = 10 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11 = 11 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12 = 12 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO0_BIT14_or_GPIO2_BIT13_PLIC_13 = 13 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14 = 14 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15 = 15 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16 = 16 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17 = 17 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18 = 18 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19 = 19 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT6_or_GPIO2_BIT20_PLIC_20 = 20 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT7_or_GPIO2_BIT21_PLIC_21 = 21 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT8_or_GPIO2_BIT22_PLIC_22 = 22 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT9_or_GPIO2_BIT23_PLIC_23 = 23 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT10_or_GPIO2_BIT24_PLIC_24 = 24 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT11_or_GPIO2_BIT25_PLIC_25 = 25 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT12_or_GPIO2_BIT26_PLIC_26 = 26 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT13_or_GPIO2_BIT27_PLIC_27 = 27 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO1_BIT14_or_GPIO2_BIT28_PLIC_28 = 28 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT15_or_GPIO2_BIT29_PLIC_29 = 29 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT16_or_GPIO2_BIT30_PLIC_30 = 30 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT17_or_GPIO2_BIT31_PLIC_31 = 31 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO1_BIT18_PLIC_32 = 32 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT19_PLIC_33 = 33 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT20_PLIC_34 = 34 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT21_PLIC_35 = 35 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT22_PLIC_36 = 36 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT23_PLIC_37 = 37 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO0_NON_DIRECT_PLI =38 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_NON_DIRECT_PLIC =39 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO2_NON_DIRECT_PLIC =40 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x01U /*SPI0_PLIC =41 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*SPI1_PLIC =42 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*CAN0_PLIC =43 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*CAN1_PLIC =44 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_MAIN_PLIC =45 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_ALERT_PLIC =46 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_SUS_PLIC =47 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_MAIN_PLIC =48 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_ALERT_PLIC =49 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_SUS_PLIC =50 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_INT_PLIC =51 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE1_PLIC =52 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE2_PLIC =53 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE3_PLIC =54 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_eMAC_PLIC =55 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_MMSL_PLIC =56 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_int_PLIC =57 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE1_PLIC =58 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE2_PLIC =59 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE3_PLIC =60 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_EMAC_PLIC =61 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_MMSL_PLIC =62 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x09U /*DDRC_TRAIN_PLIC =63 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x07U /*SCB_INTERRUPT_PLIC =64 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*ECC_ERROR_PLIC =65 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*ECC_CORRECT_PLIC =66 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*RTC_WAKEUP_PLIC =67 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*RTC_MATCH_PLIC =68 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0CU /*TIMER1_PLIC =69 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0CU /*TIMER2_PLIC =70 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*ENVM_PLIC =71 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*QSPI_PLIC =72 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0EU /*USB_DMA_PLIC =73 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0EU /*USB_MC_PLIC =74 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0FU /*MMC_main_PLIC =75 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0FU /*MMC_wakeup_PLIC =76 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART0_PLIC_77 =77 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART1_PLIC =78 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART2_PLIC =79 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART3_PLIC =80 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART4_PLIC =81 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0AU /*G5C_DEVRST_PLIC =82 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x08U /*g5c_MESSAGE_PLIC =83 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_VC_INTERRUPT_PLIC =84 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_SMB_INTERRUPT_PLIC =85 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*E51_0_MAINTENACE_PLIC =86 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG0_MRVP_PLIC =87 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG1_MRVP_PLIC =88 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG2_MRVP_PLIC =89 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG3_MRVP_PLIC =90 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG4_MRVP_PLIC =91 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG0_TOUT_PLIC =92 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG1_TOUT_PLIC =93 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG2_TOUT_PLIC =94 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG3_TOUT_PLIC =95 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG4_TOUT_PLIC =96 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*G5C_MSS_SPI_PLIC =97 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*VOLT_TEMP_ALARM_PLIC =98 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_COMPLETE_PLIC =99 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_ALARM_PLIC =100 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_BUS_ERROR_PLIC =101 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_AXIC_US_PLIC =102 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_AXIC_DS_PLIC =103 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_0_PLIC = 105 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_1_PLIC = 106 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_2_PLIC = 107 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_3_PLIC = 108 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_4_PLIC = 109 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_5_PLIC = 110 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_6_PLIC = 111 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_7_PLIC = 112 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_8_PLIC = 113 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_9_PLIC = 114 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_10_PLIC = 115 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_11_PLIC = 116 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_12_PLIC = 117 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_13_PLIC = 118 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_14_PLIC = 119 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_15_PLIC = 120 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_16_PLIC = 121 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_17_PLIC = 122 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_18_PLIC = 123 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_19_PLIC = 124 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_20_PLIC = 125 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_21_PLIC = 126 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_22_PLIC = 127 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_23_PLIC = 128 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_24_PLIC = 129 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_25_PLIC = 130 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_26_PLIC = 131 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_27_PLIC = 132 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_28_PLIC = 133 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_29_PLIC = 134 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_30_PLIC = 135 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_31_PLIC = 136 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_32_PLIC = 137 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_33_PLIC = 138 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_34_PLIC = 139 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_35_PLIC = 140 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_36_PLIC = 141 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_37_PLIC = 142 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_38_PLIC = 143 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_39_PLIC = 144 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_40_PLIC = 145 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_41_PLIC = 146 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_42_PLIC = 147 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_43_PLIC = 148 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_44_PLIC = 149 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_45_PLIC = 150 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_46_PLIC = 151 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_47_PLIC = 152 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_48_PLIC = 153 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_49_PLIC = 154 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_50_PLIC = 155 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_51_PLIC = 156 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_52_PLIC = 157 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_53_PLIC = 158 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_54_PLIC = 159 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_55_PLIC = 160 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_56_PLIC = 161 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_57_PLIC = 162 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_58_PLIC = 163 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_59_PLIC = 164 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_60_PLIC = 165 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_61_PLIC = 166 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_62_PLIC = 167 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_63_PLIC = 168 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_0 = 182*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_1 = 183*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_2 = 184*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_3 = 185*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_4 = 186 */
+
+};
+
+
+/**
+ * get source to fabric signal mapping
+ * @param source_int
+ * @return
+ */
+static uint32_t get_corresponding_h2f_output(uint32_t source_int)
+{
+ uint32_t h2f_line = H2F_int_mapping[source_int];
+
+ if(h2f_line < H2F_MAPPING_INVALID) /* if no error */
+ {
+ return(0x01U << h2f_line);
+ }
+
+ return(h2f_line);
+
+}
+
+/**
+ * set H2F controller to reset to defaults- disabled
+ */
+void reset_h2f(void)
+{
+ uint8_t index = 0U;
+ H2F_CONTROLLER->ENABLE = 0U;
+ while(index < 4U)
+ {
+ H2F_CONTROLLER->PLENABLE[index] = 0U;
+ index++;
+ }
+}
+
+/**
+ * enables output which will mirror PLIC input. PLIC mapping given above for reference
+ * @param source_int
+ */
+void enable_h2f_int_output(uint32_t source_int)
+{
+
+ uint32_t output_signal = get_corresponding_h2f_output(source_int);
+
+ if(output_signal != H2F_MAPPING_INVALID)
+ {
+ source_int -= OFFSET_TO_MSS_GLOBAL_INTS;
+
+ /* enable the input */
+ H2F_CONTROLLER->PLENABLE[source_int/32U] |= (0x01U << (source_int % 32U));
+
+ /* enable the output */
+ H2F_CONTROLLER->ENABLE |= ((output_signal<<16U) | 0x01U);
+ }
+}
+
+
+/**
+ * enables output which will mirror PLIC input. PLIC mapping given above for reference
+ * @param source_int
+ */
+void disable_h2f_int_output(uint32_t source_int)
+{
+ uint32_t output_signal = get_corresponding_h2f_output(source_int);
+
+ if(output_signal != H2F_MAPPING_INVALID)
+ {
+ /* enable the input */
+ H2F_CONTROLLER->PLENABLE[source_int/32U] &= ~(source_int % 32U);
+ /* enable the output */
+ H2F_CONTROLLER->ENABLE &= ~(((output_signal<<16U)));
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_h2f.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_h2f.h
new file mode 100644
index 00000000..280e465b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_h2f.h
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_h2f.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief H2F access data structures and functions.
+ *
+ * Definitions and functions associated with host to fabric interrupt controller.
+ *
+ */
+
+#ifndef MSS_H2F_H
+#define MSS_H2F_H
+
+#include "mpfs_hal_config/mss_sw_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+H2F line Group Ored (no of interrupts ored to one output line)
+0 GPIO 41
+1 MMUART,SPI,CAN 9
+2 I2C 6
+3 MAC0 6
+4 MAC1 6
+5 WATCHDOGS 10
+6 Maintenance 3
+7 SCB 1
+8 G5C-Message 1
+9 DDRC 1
+10 G5C-DEVRST 2
+11 RTC/USOC 4
+12 TIMER 2
+13 ENVM, QSPI 2
+14 USB 2
+15 MMC/SDIO 2
+*/
+
+/*==============================================================================
+ * Host to Fabric interrupt controller
+ *
+ * For an interrupt to activate the PENABLE and appropriate HENABLE and PENABLE bits must be set.
+ *
+ * Note. Since Interrupts 127:94 are not used in the system the enable registers are non-write-able and always read as zeros.
+ *
+ */
+
+typedef struct
+{
+ volatile uint32_t ENABLE; /* bit o: Enables all the H2FINT outputs, bit 31:16 Enables individual H2F outputs */
+ volatile uint32_t H2FSTATUS; /* 15:0 Read back of the 16-bit H2F Interrupts before the H2F and global enable */
+ uint32_t filler[2U]; /* fill the gap in the memory map */
+ volatile uint32_t PLSTATUS[4U]; /* Indicates that the PLINT interrupt is active before the PLINT enable
+ i.e. direct read of the PLINT inputs [31:0] from PLSTATUS[0]
+ direct read of the PLINT inputs [63:32] from PLSTATUS[1]
+ etc */
+ volatile uint32_t PLENABLE[4U]; /* Enables PLINT interrupts PLENABLE[0] 31:0, PLENABLE[1] 63:32, 95:64, 127:96 */
+} H2F_CONTROLLER_Type;
+
+#ifndef H2F_BASE_ADDRESS
+#if (LIBERO_SETTING_APBBUS_CR & (1U<<23U))
+#define H2F_BASE_ADDRESS 0x28126000
+#else
+#define H2F_BASE_ADDRESS 0x20126000
+#endif
+#endif
+
+#define H2F_CONTROLLER ((H2F_CONTROLLER_Type *)H2F_BASE_ADDRESS)
+
+void reset_h2f(void);
+void enable_h2f_int_output(uint32_t source_int);
+void disable_h2f_int_output(uint32_t source_int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_H2F_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_hart_ints.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_hart_ints.h
new file mode 100644
index 00000000..c559d193
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_hart_ints.h
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_hart_ints.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS local interrupt definitions
+ *
+ * Definitions and functions associated with local interrupts for each hart.
+ *
+ */
+#ifndef MSS_HART_INTS_H
+#define MSS_HART_INTS_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct BEU_Type_
+{
+ volatile uint64_t CAUSE;
+ volatile uint64_t VALUE;
+ volatile uint64_t ENABLE;
+ volatile uint64_t PLIC_INT;
+ volatile uint64_t ACCRUED;
+ volatile uint64_t LOCAL_INT;
+ volatile uint64_t reserved2[((0x1000U/8U) - 0x6U)];
+} BEU_Type;
+
+typedef struct BEU_Types_
+{
+ volatile BEU_Type regs[5];
+} BEU_Types;
+
+#define MSS_BUS_ERROR_UNIT_H0 0x01700000UL
+#define MSS_BUS_ERROR_UNIT_H1 0x01701000UL
+#define MSS_BUS_ERROR_UNIT_H2 0x01702000UL
+#define MSS_BUS_ERROR_UNIT_H3 0x01703000UL
+#define MSS_BUS_ERROR_UNIT_H4 0x01704000UL
+
+#define BEU ((BEU_Types *)MSS_BUS_ERROR_UNIT_H0)
+
+/*
+ * Interrupt numbers U0
+ */
+
+#define MAINTENANCE_E51_INT 0
+#define USOC_SMB_INTERRUPT_E51_INT 1
+#define USOC_VC_INTERRUPT_E51_INT 2
+#define G5C_MESSAGE_E51_INT 3
+#define G5C_DEVRST_E51_INT 4
+#define WDOG4_TOUT_E51_INT 5
+#define WDOG3_TOUT_E51_INT 6
+#define WDOG2_TOUT_E51_INT 7
+#define WDOG1_TOUT_E51_INT 8
+#define WDOG0_TOUT_E51_INT 9
+#define WDOG0_MVRP_E51_INT 10
+#define MMUART0_E51_INT 11
+#define ENVM_E51_INT 12
+#define ECC_CORRECT_E51_INT 13
+#define ECC_ERROR_E51_INT 14
+#define scb_INTERRUPT_E51_INT 15
+#define FABRIC_F2H_32_E51_INT 16
+#define FABRIC_F2H_33_E51_INT 17
+#define FABRIC_F2H_34_E51_INT 18
+#define FABRIC_F2H_35_E51_INT 19
+#define FABRIC_F2H_36_E51_INT 20
+#define FABRIC_F2H_37_E51_INT 21
+#define FABRIC_F2H_38_E51_INT 22
+#define FABRIC_F2H_39_E51_INT 23
+#define FABRIC_F2H_40_E51_INT 24
+#define FABRIC_F2H_41_E51_INT 25
+
+#define FABRIC_F2H_42_E51_INT 26
+#define FABRIC_F2H_43_E51_INT 27
+#define FABRIC_F2H_44_E51_INT 28
+#define FABRIC_F2H_45_E51_INT 29
+#define FABRIC_F2H_46_E51_INT 30
+#define FABRIC_F2H_47_E51_INT 31
+#define FABRIC_F2H_48_E51_INT 32
+#define FABRIC_F2H_49_E51_INT 33
+#define FABRIC_F2H_50_E51_INT 34
+#define FABRIC_F2H_51_E51_INT 35
+
+#define FABRIC_F2H_52_E51_INT 36
+#define FABRIC_F2H_53_E51_INT 37
+#define FABRIC_F2H_54_E51_INT 38
+#define FABRIC_F2H_55_E51_INT 39
+#define FABRIC_F2H_56_E51_INT 40
+#define FABRIC_F2H_57_E51_INT 41
+#define FABRIC_F2H_58_E51_INT 42
+#define FABRIC_F2H_59_E51_INT 43
+#define FABRIC_F2H_60_E51_INT 44
+#define FABRIC_F2H_61_E51_INT 45
+
+#define FABRIC_F2H_62_E51_INT 46
+#define FABRIC_F2H_63_E51_INT 47
+
+#define LOCAL_INT_MAX 47U /* Highest numbered */
+#define LOCAL_INT_UNUSED 127U /* Signifies unused interrupt */
+/*
+ * Interrupts associated with
+ * MAINTENANCE_E51_INT
+ *
+ * A group of interrupt events are grouped into a single maintenance interrupt to the E51 CPU,
+ * on receiving this interrupt the E51 should read the maintenance system register to find out
+ * the interrupt source. The maintenance interrupts are defined below
+ */
+#define MAINTENANCE_E51_pll_INT 0
+#define MAINTENANCE_E51_mpu_INT 1
+#define MAINTENANCE_E51_lp_state_enter_INT 2
+#define MAINTENANCE_E51_lp_state_exit_INT 3
+#define MAINTENANCE_E51_ff_start_INT 4
+#define MAINTENANCE_E51_ff_end_INT 5
+#define MAINTENANCE_E51_fpga_on_INT 6
+#define MAINTENANCE_E51_fpga_off_INT 7
+#define MAINTENANCE_E51_scb_error_INT 8
+#define MAINTENANCE_E51_scb_fault_INT 9
+#define MAINTENANCE_E51_mesh_error_INT 10
+#define MAINTENANCE_E51_io_bank_b2_on_INT 12
+#define MAINTENANCE_E51_io_bank_b4_on_INT 13
+#define MAINTENANCE_E51_io_bank_b5_on_INT 14
+#define MAINTENANCE_E51_io_bank_b6_on_INT 15
+#define MAINTENANCE_E51_io_bank_b2_off_INT 16
+#define MAINTENANCE_E51_io_bank_b4_off_INT 17
+#define MAINTENANCE_E51_io_bank_b5_off_INT 18
+#define MAINTENANCE_E51_io_bank_b6_off_INT 19
+
+
+/*
+ * E51-0 is Maintenance Interrupt CPU needs to read status register to determine exact cause:
+ * These defines added here for clarity need to replay with status register defines
+ * for determining interrupt cause
+ */
+#ifndef FOR_CLARITY
+# define FOR_CLARITY 0
+#endif
+
+#if FOR_CLARITY
+# define mpu_fail_plic 0
+# define lp_state_enter_plic 1
+# define lp_state_exit_plic 2
+# define ff_start_plic 3
+# define ff_end_plic 4
+# define fpga_on_plic 5
+# define fpga_off_plic 6
+# define scb_error_plic 7
+# define scb_fault_plic 8
+# define mesh_fail_plic 9
+#endif
+
+/*
+ * Interrupt numbers U54's
+ */
+
+/* U0 (first U54) and U1 connected to mac0 */
+#define MAC0_INT_U54_INT 8 /* determine source mac using hart ID */
+#define MAC0_QUEUE1_U54_INT 7
+#define MAC0_QUEUE2_U54_INT 6
+#define MAC0_QUEUE3_U54_INT 5
+#define MAC0_EMAC_U54_INT 4
+#define MAC0_MMSL_U54_INT 3
+
+/* U2 and U3 connected to mac1 */
+#define MAC1_INT_U54_INT 8 /* determine source mac using hart ID */
+#define MAC1_QUEUE1_U54_INT 7
+#define MAC1_QUEUE2_U54_INT 6
+#define MAC1_QUEUE3_U54_INT 5
+#define MAC1_EMAC_U54_INT 4
+#define MAC1_MMSL_U54_INT 3
+
+/* MMUART1 connected to U54 0 */
+/* MMUART2 connected to U54 1 */
+/* MMUART3 connected to U54 2 */
+/* MMUART4 connected to U54 3 */
+#define MMUARTx_U54_INT 11 /* MMUART1 connected to U54 0 */
+#define WDOGx_MVRP_U54_INT 10 /* determine source mac using hart ID */
+#define WDOGx_TOUT_U54_INT 9 /* determine source mac using hart ID */
+
+#define H2_FABRIC_F2H_0_U54_INT 16
+#define H2_FABRIC_F2H_1_U54_INT 17
+#define H2_FABRIC_F2H_2_U54_INT 18
+#define H2_FABRIC_F2H_3_U54_INT 19
+#define H2_FABRIC_F2H_4_U54_INT 20
+#define H2_FABRIC_F2H_5_U54_INT 21
+#define H2_FABRIC_F2H_6_U54_INT 22
+#define H2_FABRIC_F2H_7_U54_INT 23
+#define H2_FABRIC_F2H_8_U54_INT 24
+#define H2_FABRIC_F2H_9_U54_INT 25
+
+#define H2_FABRIC_F2H_10_U54_INT 26
+#define H2_FABRIC_F2H_11_U54_INT 27
+#define H2_FABRIC_F2H_12_U54_INT 28
+#define H2_FABRIC_F2H_13_U54_INT 29
+#define H2_FABRIC_F2H_14_U54_INT 30
+#define H2_FABRIC_F2H_15_U54_INT 31
+#define H2_FABRIC_F2H_16_U54_INT 32
+#define H2_FABRIC_F2H_17_U54_INT 33
+#define H2_FABRIC_F2H_18_U54_INT 34
+#define H2_FABRIC_F2H_19_U54_INT 35
+
+#define H2_FABRIC_F2H_20_U54_INT 36
+#define H2_FABRIC_F2H_21_U54_INT 37
+#define H2_FABRIC_F2H_22_U54_INT 38
+#define H2_FABRIC_F2H_23_U54_INT 39
+#define H2_FABRIC_F2H_24_U54_INT 40
+#define H2_FABRIC_F2H_25_U54_INT 41
+#define H2_FABRIC_F2H_26_U54_INT 42
+#define H2_FABRIC_F2H_27_U54_INT 43
+#define H2_FABRIC_F2H_28_U54_INT 44
+#define H2_FABRIC_F2H_29_U54_INT 45
+
+#define H2_FABRIC_F2H_30_U54_INT 46
+#define H2_FABRIC_F2H_31_U54_INT 47
+
+
+void handle_m_ext_interrupt(void);
+void Software_h0_IRQHandler(void);
+void Software_h1_IRQHandler(void);
+void Software_h2_IRQHandler(void);
+void Software_h3_IRQHandler(void);
+void Software_h4_IRQHandler(void);
+void SysTick_Handler_h0_IRQHandler(void);
+void SysTick_Handler_h1_IRQHandler(void);
+void SysTick_Handler_h2_IRQHandler(void);
+void SysTick_Handler_h3_IRQHandler(void);
+void SysTick_Handler_h4_IRQHandler(void);
+
+/*
+ *
+ * Local interrupt defines
+ *
+ */
+void maintenance_e51_local_IRQHandler_0(void);
+void usoc_smb_interrupt_e51_local_IRQHandler_1(void);
+void usoc_vc_interrupt_e51_local_IRQHandler_2(void);
+void g5c_message_e51_local_IRQHandler_3(void);
+void g5c_devrst_e51_local_IRQHandler_4(void);
+void wdog4_tout_e51_local_IRQHandler_5(void);
+void wdog3_tout_e51_local_IRQHandler_6(void);
+void wdog2_tout_e51_local_IRQHandler_7(void);
+void wdog1_tout_e51_local_IRQHandler_8(void);
+void wdog0_tout_e51_local_IRQHandler_9(void);
+void wdog0_mvrp_e51_local_IRQHandler_10(void);
+void mmuart0_e51_local_IRQHandler_11(void);
+void envm_e51_local_IRQHandler_12(void);
+void ecc_correct_e51_local_IRQHandler_13(void);
+void ecc_error_e51_local_IRQHandler_14(void);
+void scb_interrupt_e51_local_IRQHandler_15(void);
+void fabric_f2h_32_e51_local_IRQHandler_16(void);
+void fabric_f2h_33_e51_local_IRQHandler_17(void);
+void fabric_f2h_34_e51_local_IRQHandler_18(void);
+void fabric_f2h_35_e51_local_IRQHandler_19(void);
+void fabric_f2h_36_e51_local_IRQHandler_20(void);
+void fabric_f2h_37_e51_local_IRQHandler_21(void);
+void fabric_f2h_38_e51_local_IRQHandler_22(void);
+void fabric_f2h_39_e51_local_IRQHandler_23(void);
+void fabric_f2h_40_e51_local_IRQHandler_24(void);
+void fabric_f2h_41_e51_local_IRQHandler_25(void);
+void fabric_f2h_42_e51_local_IRQHandler_26(void);
+void fabric_f2h_43_e51_local_IRQHandler_27(void);
+void fabric_f2h_44_e51_local_IRQHandler_28(void);
+void fabric_f2h_45_e51_local_IRQHandler_29(void);
+void fabric_f2h_46_e51_local_IRQHandler_30(void);
+void fabric_f2h_47_e51_local_IRQHandler_31(void);
+void fabric_f2h_48_e51_local_IRQHandler_32(void);
+void fabric_f2h_49_e51_local_IRQHandler_33(void);
+void fabric_f2h_50_e51_local_IRQHandler_34(void);
+void fabric_f2h_51_e51_local_IRQHandler_35(void);
+void fabric_f2h_52_e51_local_IRQHandler_36(void);
+void fabric_f2h_53_e51_local_IRQHandler_37(void);
+void fabric_f2h_54_e51_local_IRQHandler_38(void);
+void fabric_f2h_55_e51_local_IRQHandler_39(void);
+void fabric_f2h_56_e51_local_IRQHandler_40(void);
+void fabric_f2h_57_e51_local_IRQHandler_41(void);
+void fabric_f2h_58_e51_local_IRQHandler_42(void);
+void fabric_f2h_59_e51_local_IRQHandler_43(void);
+void fabric_f2h_60_e51_local_IRQHandler_44(void);
+void fabric_f2h_61_e51_local_IRQHandler_45(void);
+void fabric_f2h_62_e51_local_IRQHandler_46(void);
+void fabric_f2h_63_e51_local_IRQHandler_47(void);
+
+/*
+ * U54
+ */
+void spare_u54_local_IRQHandler_0(void);
+void spare_u54_local_IRQHandler_1(void);
+void spare_u54_local_IRQHandler_2(void);
+
+void mac_mmsl_u54_1_local_IRQHandler_3(void);
+void mac_emac_u54_1_local_IRQHandler_4(void);
+void mac_queue3_u54_1_local_IRQHandler_5(void);
+void mac_queue2_u54_1_local_IRQHandler_6(void);
+void mac_queue1_u54_1_local_IRQHandler_7(void);
+void mac_int_u54_1_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_2_local_IRQHandler_3(void);
+void mac_emac_u54_2_local_IRQHandler_4(void);
+void mac_queue3_u54_2_local_IRQHandler_5(void);
+void mac_queue2_u54_2_local_IRQHandler_6(void);
+void mac_queue1_u54_2_local_IRQHandler_7(void);
+void mac_int_u54_2_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_3_local_IRQHandler_3(void);
+void mac_emac_u54_3_local_IRQHandler_4(void);
+void mac_queue3_u54_3_local_IRQHandler_5(void);
+void mac_queue2_u54_3_local_IRQHandler_6(void);
+void mac_queue1_u54_3_local_IRQHandler_7(void);
+void mac_int_u54_3_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_4_local_IRQHandler_3(void);
+void mac_emac_u54_4_local_IRQHandler_4(void);
+void mac_queue3_u54_4_local_IRQHandler_5(void);
+void mac_queue2_u54_4_local_IRQHandler_6(void);
+void mac_queue1_u54_4_local_IRQHandler_7(void);
+void mac_int_u54_4_local_IRQHandler_8(void);
+
+void wdog_tout_u54_h1_local_IRQHandler_9(void);
+void wdog_tout_u54_h2_local_IRQHandler_9(void);
+void wdog_tout_u54_h3_local_IRQHandler_9(void);
+void wdog_tout_u54_h4_local_IRQHandler_9(void);
+void mvrp_u54_local_IRQHandler_10(void);
+void mmuart_u54_h1_local_IRQHandler_11(void);
+void mmuart_u54_h2_local_IRQHandler_11(void);
+void mmuart_u54_h3_local_IRQHandler_11(void);
+void mmuart_u54_h4_local_IRQHandler_11(void);
+void spare_u54_local_IRQHandler_12(void);
+void spare_u54_local_IRQHandler_13(void);
+void spare_u54_local_IRQHandler_14(void);
+void spare_u54_local_IRQHandler_15(void);
+void fabric_f2h_0_u54_local_IRQHandler_16(void);
+void fabric_f2h_1_u54_local_IRQHandler_17(void);
+void fabric_f2h_2_u54_local_IRQHandler_18(void);
+void fabric_f2h_3_u54_local_IRQHandler_19(void);
+void fabric_f2h_4_u54_local_IRQHandler_20(void);
+void fabric_f2h_5_u54_local_IRQHandler_21(void);
+void fabric_f2h_6_u54_local_IRQHandler_22(void);
+void fabric_f2h_7_u54_local_IRQHandler_23(void);
+void fabric_f2h_8_u54_local_IRQHandler_24(void);
+void fabric_f2h_9_u54_local_IRQHandler_25(void);
+void fabric_f2h_10_u54_local_IRQHandler_26(void);
+void fabric_f2h_11_u54_local_IRQHandler_27(void);
+void fabric_f2h_12_u54_local_IRQHandler_28(void);
+void fabric_f2h_13_u54_local_IRQHandler_29(void);
+void fabric_f2h_14_u54_local_IRQHandler_30(void);
+void fabric_f2h_15_u54_local_IRQHandler_31(void);
+void fabric_f2h_16_u54_local_IRQHandler_32(void);
+void fabric_f2h_17_u54_local_IRQHandler_33(void);
+void fabric_f2h_18_u54_local_IRQHandler_34(void);
+void fabric_f2h_19_u54_local_IRQHandler_35(void);
+void fabric_f2h_20_u54_local_IRQHandler_36(void);
+void fabric_f2h_21_u54_local_IRQHandler_37(void);
+void fabric_f2h_22_u54_local_IRQHandler_38(void);
+void fabric_f2h_23_u54_local_IRQHandler_39(void);
+void fabric_f2h_24_u54_local_IRQHandler_40(void);
+void fabric_f2h_25_u54_local_IRQHandler_41(void);
+void fabric_f2h_26_u54_local_IRQHandler_42(void);
+void fabric_f2h_27_u54_local_IRQHandler_43(void);
+void fabric_f2h_28_u54_local_IRQHandler_44(void);
+void fabric_f2h_29_u54_local_IRQHandler_45(void);
+void fabric_f2h_30_u54_local_IRQHandler_46(void);
+void fabric_f2h_31_u54_local_IRQHandler_47(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_HART_INTS_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c
new file mode 100644
index 00000000..6194ae57
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c
@@ -0,0 +1,1663 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_irq_handler_stubs.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS MSS Interrupt Function stubs.
+ *
+ * The functions below will only be linked with the application code if the user
+ * does not provide an implementation for these functions. These functions are
+ * defined with weak linking so that they can be overridden by a function with
+ * same prototype in the user's application code.
+ *
+ */
+#include
+#include "mpfs_hal/mss_hal.h"
+
+
+__attribute__((weak)) void handle_m_ext_interrupt(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h0_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h1_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h2_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h3_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h4_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h0_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h1_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h2_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h3_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h4_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) uint8_t Invalid_IRQHandler(void)
+{
+ return(0U);
+}
+#ifdef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t External_1_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_2_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_3_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t USART0_plic_4_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_5_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_6_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_7_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_8_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_9_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_10_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_11_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_12_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_13_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_14_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_15_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_16_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_17_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_18_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_19_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_20_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_21_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_22_IRQHandler(void)
+{
+ return(0U);
+}
+#endif
+
+__attribute__((weak)) uint8_t dma_ch0_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch0_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch1_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch1_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch2_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch2_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch3_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch3_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+#ifdef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t External_31_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t External_32_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_33_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_34_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_35_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_36_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_37_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_38_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_39_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_40_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_41_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_42_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_43_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_44_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_45_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_46_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_47_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_48_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_49_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_50_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_51_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_52_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t MAC0_plic_53_IRQHandler(void)
+{
+ return(0U);
+}
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t l2_metadata_corr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_metadata_uncorr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_data_corr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_data_uncorr_IRQHandler(void)
+{
+ return(0U);
+}
+#endif /* ifndef SIFIVE_HIFIVE_UNLEASHED */
+
+
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler(void)
+ {
+ return(0U);
+ }
+
+__attribute__((weak)) uint8_t gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio1_bit18_plic_32_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit19_plic_33_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit20_plic_34_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit21_plic_35_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit22_plic_36_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit23_plic_37_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio0_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio2_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t spi0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t spi1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t external_can0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t can1_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_i2c0_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_i2c0_alert_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c0_sus_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_alert_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_sus_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_int_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_emac_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_mmsl_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_int_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_emac_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_mmsl_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ddrc_train_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t scb_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ecc_error_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ecc_correct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t rtc_wakeup_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t rtc_match_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t timer1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t timer2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t envm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t qspi_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usb_dma_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usb_mc_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmc_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmc_wakeup_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart0_plic_77_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t g5c_devrst_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t g5c_message_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usoc_vc_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usoc_smb_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t e51_0_Maintence_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t wdog0_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog1_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog2_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog3_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog4_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog0_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog1_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog2_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog3_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog4_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t g5c_mss_spi_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t volt_temp_alarm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_complete_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_alarm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_bus_error_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t usoc_axic_us_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t usoc_axic_ds_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t reserved_104_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+
+__attribute__((weak)) uint8_t fabric_f2h_0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_5_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_6_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_7_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_8_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_9_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_10_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_11_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_12_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_13_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_14_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_15_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_16_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_17_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_18_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_19_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_20_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_21_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_22_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_23_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_24_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_25_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_26_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_27_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_28_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_29_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_30_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_31_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_32_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_33_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_34_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_35_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_36_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_37_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_38_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_39_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_40_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_41_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_42_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_43_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_44_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_45_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_46_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_47_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_48_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_49_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_50_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_51_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_52_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_53_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_54_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_55_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_56_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_57_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_58_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_59_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_60_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_61_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_62_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_63_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+/* Local interrupt stubs */
+__attribute__((weak)) void maintenance_e51_local_IRQHandler_0(void)
+{
+}
+__attribute__((weak)) void usoc_smb_interrupt_e51_local_IRQHandler_1(void)
+{
+}
+__attribute__((weak)) void usoc_vc_interrupt_e51_local_IRQHandler_2(void)
+{
+}
+__attribute__((weak)) void g5c_message_e51_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void g5c_devrst_e51_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void wdog4_tout_e51_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void wdog3_tout_e51_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void wdog2_tout_e51_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void wdog1_tout_e51_local_IRQHandler_8(void)
+{
+}
+__attribute__((weak)) void wdog0_tout_e51_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog0_mvrp_e51_local_IRQHandler_10(void)
+{
+}
+
+__attribute__((weak)) void mmuart0_e51_local_IRQHandler_11(void)
+{
+}
+
+__attribute__((weak)) void envm_e51_local_IRQHandler_12(void)
+{
+}
+
+__attribute__((weak)) void ecc_correct_e51_local_IRQHandler_13(void)
+{
+}
+
+__attribute__((weak)) void ecc_error_e51_local_IRQHandler_14(void)
+{
+}
+
+__attribute__((weak)) void scb_interrupt_e51_local_IRQHandler_15(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_32_e51_local_IRQHandler_16(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_33_e51_local_IRQHandler_17(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_34_e51_local_IRQHandler_18(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_35_e51_local_IRQHandler_19(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_36_e51_local_IRQHandler_20(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_37_e51_local_IRQHandler_21(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_38_e51_local_IRQHandler_22(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_39_e51_local_IRQHandler_23(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_40_e51_local_IRQHandler_24(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_41_e51_local_IRQHandler_25(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_42_e51_local_IRQHandler_26(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_43_e51_local_IRQHandler_27(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_44_e51_local_IRQHandler_28(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_45_e51_local_IRQHandler_29(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_46_e51_local_IRQHandler_30(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_47_e51_local_IRQHandler_31(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_48_e51_local_IRQHandler_32(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_49_e51_local_IRQHandler_33(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_50_e51_local_IRQHandler_34(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_51_e51_local_IRQHandler_35(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_52_e51_local_IRQHandler_36(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_53_e51_local_IRQHandler_37(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_54_e51_local_IRQHandler_38(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_55_e51_local_IRQHandler_39(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_56_e51_local_IRQHandler_40(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_57_e51_local_IRQHandler_41(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_58_e51_local_IRQHandler_42(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_59_e51_local_IRQHandler_43(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_60_e51_local_IRQHandler_44(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_61_e51_local_IRQHandler_45(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_62_e51_local_IRQHandler_46(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_63_e51_local_IRQHandler_47(void)
+{
+}
+
+
+/*
+ * U54
+ */
+__attribute__((weak)) void spare_u54_local_IRQHandler_0(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_1(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_2(void)
+{
+}
+
+/* Ethernet MACs - GEM0 is on U54s 1 and 2, GEM1 is on U54s 3 and 4 */
+
+/* U54 1 */
+__attribute__((weak)) void mac_mmsl_u54_1_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_1_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_1_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_1_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_1_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_1_local_IRQHandler_8(void)
+{
+}
+
+/* U54 2 */
+__attribute__((weak)) void mac_mmsl_u54_2_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_2_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_2_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_2_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_2_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_2_local_IRQHandler_8(void)
+{
+}
+
+/* U54 3 */
+__attribute__((weak)) void mac_mmsl_u54_3_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_3_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_3_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_3_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_3_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_3_local_IRQHandler_8(void)
+{
+}
+
+/* U54 4 */
+__attribute__((weak)) void mac_mmsl_u54_4_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_4_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_4_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_4_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_4_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_4_local_IRQHandler_8(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h1_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h2_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h3_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h4_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void mvrp_u54_local_IRQHandler_10(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h1_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h2_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h3_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h4_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_12(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_13(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_14(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_15(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_0_u54_local_IRQHandler_16(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_1_u54_local_IRQHandler_17(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_2_u54_local_IRQHandler_18(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_3_u54_local_IRQHandler_19(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_4_u54_local_IRQHandler_20(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_5_u54_local_IRQHandler_21(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_6_u54_local_IRQHandler_22(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_7_u54_local_IRQHandler_23(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_8_u54_local_IRQHandler_24(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_9_u54_local_IRQHandler_25(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_10_u54_local_IRQHandler_26(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_11_u54_local_IRQHandler_27(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_12_u54_local_IRQHandler_28(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_13_u54_local_IRQHandler_29(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_14_u54_local_IRQHandler_30(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_15_u54_local_IRQHandler_31(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_16_u54_local_IRQHandler_32(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_17_u54_local_IRQHandler_33(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_18_u54_local_IRQHandler_34(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_19_u54_local_IRQHandler_35(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_20_u54_local_IRQHandler_36(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_21_u54_local_IRQHandler_37(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_22_u54_local_IRQHandler_38(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_23_u54_local_IRQHandler_39(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_24_u54_local_IRQHandler_40(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_25_u54_local_IRQHandler_41(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_26_u54_local_IRQHandler_42(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_27_u54_local_IRQHandler_43(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_28_u54_local_IRQHandler_44(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_29_u54_local_IRQHandler_45(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_30_u54_local_IRQHandler_46(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_31_u54_local_IRQHandler_47(void)
+{
+}
+#endif /* ifndef SIFIVE_HIFIVE_UNLEASHED */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_l2_cache.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_l2_cache.c
new file mode 100644
index 00000000..d51efed0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_l2_cache.c
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_l2_cache.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief The code in this file is executed before any code/data sections are
+ * copied. This code must not rely sdata/data section content. Hence, global
+ * variables should not be used unless they are constants.
+ *
+ */
+/*==============================================================================
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "mss_l2_cache.h"
+
+/*==============================================================================
+ * Local defines
+ */
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+static const uint64_t g_init_marker = INIT_MARKER;
+#endif
+
+/*==============================================================================
+ * Local functions.
+ */
+static void check_config_l2_scratchpad(void);
+
+
+/*==============================================================================
+ * This code should only be executed from E51 to be functional.
+ * Configure the L2 cache memory:
+ * - Set the number of cache ways used as cache based on the MSS Configurator
+ * settings.
+ * - Configure some of the enabled ways as scratchpad based on linker
+ * configuration and space allocated by configurator.
+ */
+__attribute__((weak)) void config_l2_cache(void)
+{
+ ASSERT(LIBERO_SETTING_WAY_ENABLE < 16U);
+
+ /*
+ * Set the number of ways that will be shared between cache and scratchpad.
+ */
+ CACHE_CTRL->WAY_ENABLE = LIBERO_SETTING_WAY_ENABLE;
+
+ /*
+ * shutdown L2 as directed
+ */
+ SYSREG->L2_SHUTDOWN_CR = LIBERO_SETTING_L2_SHUTDOWN_CR;
+
+ /* The scratchpad has already been set-up, first check enough space before copying */
+ check_config_l2_scratchpad();
+
+ /* If you are not using scratchpad, no need to include the following code */
+
+ ASSERT(LIBERO_SETTING_WAY_ENABLE >= LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS);
+
+
+
+ /*
+ * Compute the mask used to specify ways that will be used by the
+ * scratchpad.
+ */
+
+ uint32_t scratchpad_ways_mask = 0U;
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+ uint32_t inc;
+ uint32_t seed_ways_mask = 0x1U << LIBERO_SETTING_WAY_ENABLE;
+ for(inc = 0; inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++inc)
+ {
+ scratchpad_ways_mask |= (seed_ways_mask >> inc) ;
+ }
+#else
+ (void)scratchpad_ways_mask;
+#endif
+
+ /*
+ * Make sure ways are masked if being used as scratchpad
+ */
+ ASSERT((LIBERO_SETTING_WAY_MASK_DMA & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_E51_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_E51_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_1_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_2_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_3_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_4_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_1_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_2_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_3_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_4_ICACHE & scratchpad_ways_mask) == 0UL);
+
+ /*
+ * Setup all masters, apart from one we are using to setup scratch
+ */
+ CACHE_CTRL->WAY_MASK_DMA = LIBERO_SETTING_WAY_MASK_DMA;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_0;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_1;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_2;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_3;
+ CACHE_CTRL->WAY_MASK_E51_ICACHE = LIBERO_SETTING_WAY_MASK_E51_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_1_DCACHE = LIBERO_SETTING_WAY_MASK_U54_1_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_1_ICACHE = LIBERO_SETTING_WAY_MASK_U54_1_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_2_DCACHE = LIBERO_SETTING_WAY_MASK_U54_2_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_2_ICACHE = LIBERO_SETTING_WAY_MASK_U54_2_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_3_DCACHE = LIBERO_SETTING_WAY_MASK_U54_3_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_3_ICACHE = LIBERO_SETTING_WAY_MASK_U54_3_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_4_DCACHE = LIBERO_SETTING_WAY_MASK_U54_4_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_4_ICACHE = LIBERO_SETTING_WAY_MASK_U54_4_ICACHE;
+
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+ /*
+ * Assign ways to Zero Device
+ */
+ uint64_t * p_scratchpad = (uint64_t *)ZERO_DEVICE_BOTTOM;
+ uint32_t ways_inc;
+ uint64_t current_way = 0x1U << (((LIBERO_SETTING_WAY_ENABLE + 1U) - LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS) );
+ for(ways_inc = 0; ways_inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++ways_inc)
+ {
+ /*
+ * Populate the scratchpad memory one way at a time.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way;
+ mb();
+ /*
+ * Write to the first 64-bit location of each cache block.
+ */
+ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc)
+ {
+ *p_scratchpad = g_init_marker + inc;
+ p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH;
+ }
+ current_way = current_way << 1U;
+ mb();
+ }
+#endif /* (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0) */
+ /*
+ * Prevent E51 from evicting from scratchpad ways.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = LIBERO_SETTING_WAY_MASK_E51_DCACHE;
+ mb();
+
+}
+
+
+/*==============================================================================
+ * Configure the L2 scratchpad based on linker symbols:
+ * __l2_scratchpad_vma_start
+ * __l2_scratchpad_vma_end
+ *
+ * These linker symbols specify the start address and length of the scratchpad.
+ * The scratchpad must be located within the Zero Device memory range.
+ */
+static void check_config_l2_scratchpad(void)
+{
+ extern char __l2_scratchpad_vma_start;
+ extern char __l2_scratchpad_vma_end;
+
+ uint8_t n_scratchpad_ways;
+ const uint64_t end = (const uint64_t)&__l2_scratchpad_vma_end;
+ const uint64_t start = (const uint64_t)&__l2_scratchpad_vma_start;
+ uint64_t modulo;
+
+ ASSERT(start >= (uint64_t)ZERO_DEVICE_BOTTOM);
+ ASSERT(end < (uint64_t)ZERO_DEVICE_TOP);
+ ASSERT(end >= start);
+
+ /*
+ * Figure out how many cache ways will be required from linker script
+ * symbols.
+ */
+ n_scratchpad_ways = (uint8_t)((end - start) / WAY_BYTE_LENGTH);
+ modulo = (end - start) % WAY_BYTE_LENGTH;
+ if(modulo > 0)
+ {
+ ++n_scratchpad_ways;
+ }
+
+ ASSERT(LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS >= n_scratchpad_ways);
+}
+
+#if 0 // todo - remove, no longer used
+
+
+/*==============================================================================
+ * Reserve a number of cache ways to be used as scratchpad memory.
+ *
+ * @param nways
+ * Number of ways to be used as scratchpad. One way is 128Kbytes.
+ *
+ * @param scratchpad_start
+ * Start address within the Zero Device memory range in which the scratchpad
+ * will be located.
+ */
+static void reserve_scratchpad_ways(uint8_t nways, uint64_t * scratchpad_start)
+{
+ uint8_t way_enable;
+ uint64_t available_ways = 1;
+ uint64_t scratchpad_ways = 0;
+ uint64_t non_scratchpad_ways;
+ uint32_t inc;
+
+ ASSERT(scratchpad_start >= (uint64_t *)ZERO_DEVICE_BOTTOM);
+ ASSERT(scratchpad_start < (uint64_t *)ZERO_DEVICE_TOP);
+
+ /*
+ * Ensure at least one way remains available as cache.
+ */
+ way_enable = CACHE_CTRL->WAY_ENABLE;
+ ASSERT(nways <= way_enable);
+ if(nways <= way_enable)
+ {
+ /*
+ * Compute the mask used to specify ways that will be used by the
+ * scratchpad.
+ */
+
+ for(inc = 0; inc < way_enable; ++inc)
+ {
+ available_ways = (available_ways << 1) | (uint64_t)0x01;
+ if(inc < nways)
+ {
+ scratchpad_ways = (scratchpad_ways << 1) | (uint64_t)0x01;
+ }
+ }
+
+ /*
+ * Prevent other masters from evicting cache lines from scratchpad ways.
+ * Only allow E51 to evict from scratchpad ways.
+ */
+ non_scratchpad_ways = available_ways & ~scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_DMA = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_E51_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_1_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_1_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_2_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_2_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_3_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_3_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_4_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_4_ICACHE = non_scratchpad_ways;
+
+ /*
+ * Assign ways to Zero Device
+ */
+ uint64_t * p_scratchpad = scratchpad_start;
+ int ways_inc;
+ uint64_t current_way = 1;
+ for(ways_inc = 0; ways_inc < nways; ++ways_inc)
+ {
+ /*
+ * Populate the scratchpad memory one way at a time.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way;
+ /*
+ * Write to the first 64-bit location of each cache block.
+ */
+ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc)
+ {
+ *p_scratchpad = g_init_marker + inc;
+ p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH;
+ }
+ current_way = current_way << 1U;
+ mb();
+ }
+
+ /*
+ * Prevent E51 from evicting from scratchpad ways.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = non_scratchpad_ways;
+ }
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_l2_cache.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_l2_cache.h
new file mode 100644
index 00000000..16d618d6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_l2_cache.h
@@ -0,0 +1,532 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_l2_cache.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MACROs defines and prototypes associated with L2 Cache
+ *
+ */
+#ifndef MSS_L2_CACHE_H
+#define MSS_L2_CACHE_H
+
+#include
+#include "encoding.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following defines will be present in configurator generated xml Q1 2021
+ * In the interim, you can manually edit if required.
+ */
+#if !defined (LIBERO_SETTING_WAY_ENABLE)
+/*Way indexes less than or equal to this register value may be used by the
+cache. E.g. set to 0x7, will allocate 8 cache ways, 0-7 to cache, and leave
+8-15 as LIM. Note 1: Way 0 is always allocated as cache. Note 2: each way is
+128KB. */
+#define LIBERO_SETTING_WAY_ENABLE 0x00000007UL
+ /* WAY_ENABLE [0:8] RW value= 0x7 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_DMA)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_DMA 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_0)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_1)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_2)
+/*Way mask registerAXI slave port 2. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_3)
+/*Way mask register AXI slave port 3. Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_DCACHE)
+/*Way mask register E51 data cache (hart0). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_ICACHE)
+/*Way mask registerE52 instruction cache (hart0). Set field to zero to disable
+way from this master. The available cache ways are 0 to number set in
+WAY_ENABLE register. If using scratch pad memory, the ways you want reserved
+for scrathpad are not available for selection, you must set to 0. e.g. If three
+ways reserved for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set
+to zero for all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_DCACHE)
+/*Way mask register data cache (hart1). Set field to zero to disable way from
+this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_ICACHE)
+/*Way mask register instruction cache (hart1). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_DCACHE)
+/*Way mask register data cache (hart2). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_ICACHE)
+/*Way mask register instruction cache (hart2). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_DCACHE)
+/*Way mask register data cache (hart3). Set field to 1 to disable way from this
+master.Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_ICACHE)
+/*Way mask register instruction cache(hart3). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_DCACHE)
+/*Way mask register data cache (hart4). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_ICACHE)
+/*Way mask register instruction cache (hart4). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS)
+/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
+2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
+for scratchpad start at way 0, and work up. */
+#define LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS 0x00000000UL
+ /* NUM_OF_WAYS [0:8] RW value= 0x0 */
+#endif
+
+
+#if !defined (LIBERO_SETTING_L2_SHUTDOWN_CR)
+/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
+2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
+for scratchpad start at way 0, and work up. */
+#define LIBERO_SETTING_L2_SHUTDOWN_CR 0x00000000UL
+ /* NUM_OF_WAYS [0:8] RW value= 0x0 */
+#endif
+
+
+
+/*==============================================================================
+ * Define describing cache characteristics.
+ */
+#define MAX_WAY_ENABLE 15
+#define NB_SETS 512
+#define NB_BANKS 4
+#define CACHE_BLOCK_BYTE_LENGTH 64
+#define UINT64_BYTE_LENGTH 8
+#define WAY_BYTE_LENGTH (CACHE_BLOCK_BYTE_LENGTH * NB_SETS * NB_BANKS)
+
+#define ZERO_DEVICE_BOTTOM 0x0A000000ULL
+#define ZERO_DEVICE_TOP 0x0C000000ULL
+
+#define CACHE_CTRL_BASE 0x02010000ULL
+
+#define INIT_MARKER 0xC0FFEEBEC0010000ULL
+
+#define SHUTDOWN_CACHE_CC24_00_07_MASK 0x01
+#define SHUTDOWN_CACHE_CC24_08_15_MASK 0x02
+#define SHUTDOWN_CACHE_CC24_16_23_MASK 0x04
+#define SHUTDOWN_CACHE_CC24_24_31_MASK 0x08
+
+
+/*==============================================================================
+ * Cache controller registers definitions
+ */
+#define RO volatile const
+#define RW volatile
+#define WO volatile
+
+typedef struct {
+ RO uint8_t BANKS;
+ RO uint8_t WAYS;
+ RO uint8_t SETS;
+ RO uint8_t BYTES;
+} CACHE_CONFIG_typedef;
+
+typedef struct {
+ CACHE_CONFIG_typedef CONFIG;
+ RO uint32_t RESERVED;
+ RW uint8_t WAY_ENABLE;
+ RO uint8_t RESERVED0[55];
+
+ RW uint32_t ECC_INJECT_ERROR;
+ RO uint32_t RESERVED1[47];
+
+ RO uint64_t ECC_DIR_FIX_ADDR;
+ RO uint32_t ECC_DIR_FIX_COUNT;
+ RO uint32_t RESERVED2[13];
+
+ RO uint64_t ECC_DATA_FIX_ADDR;
+ RO uint32_t ECC_DATA_FIX_COUNT;
+ RO uint32_t RESERVED3[5];
+
+ RO uint64_t ECC_DATA_FAIL_ADDR;
+ RO uint32_t ECC_DATA_FAIL_COUNT;
+ RO uint32_t RESERVED4[37];
+
+ WO uint64_t FLUSH64;
+ RO uint64_t RESERVED5[7];
+
+ WO uint32_t FLUSH32;
+ RO uint32_t RESERVED6[367];
+
+ RW uint64_t WAY_MASK_DMA;
+
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_0;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_1;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_2;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_3;
+
+ RW uint64_t WAY_MASK_E51_DCACHE;
+ RW uint64_t WAY_MASK_E51_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_1_DCACHE;
+ RW uint64_t WAY_MASK_U54_1_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_2_DCACHE;
+ RW uint64_t WAY_MASK_U54_2_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_3_DCACHE;
+ RW uint64_t WAY_MASK_U54_3_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_4_DCACHE;
+ RW uint64_t WAY_MASK_U54_4_ICACHE;
+} CACHE_CTRL_typedef;
+
+#define CACHE_CTRL ((volatile CACHE_CTRL_typedef *) CACHE_CTRL_BASE)
+
+void config_l2_cache(void);
+uint8_t check_num_scratch_ways(uint64_t *start, uint64_t *end);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_L2_CACHE_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mpu.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mpu.c
new file mode 100644
index 00000000..1e5b55e7
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mpu.c
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_mpu.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS MPU driver for configuring access regions for the
+ * external masters.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+static uint64_t pmp_get_napot_base_and_range(uint64_t reg, uint64_t *range);
+
+uint8_t num_pmp_lut[10U] = {16U,16U,8U,4U,8U,8U,4U,4U,8U,2U};
+
+/**
+ * \brief MPU configuration from Libero for FIC0
+ *
+ */
+const uint64_t mpu_fic0_values[] = {
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP7,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP8,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP9,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP10,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP11,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP12,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP13,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP14,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP15
+};
+
+/**
+ * \brief MPU configuration from Libero for FIC1
+ *
+ */
+const uint64_t mpu_fic1_values[] = {
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP7,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP8,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP9,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP10,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP11,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP12,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP13,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP14,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP15
+};
+
+/**
+ * \brief MPU configuration from Libero for FIC2
+ *
+ */
+const uint64_t mpu_fic2_values[] = {
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for ATHENA
+ *
+ */
+const uint64_t mpu_crypto_values[] = {
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP0,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP1,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP2,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for GEM0
+ *
+ */
+const uint64_t mpu_gem0_values[] = {
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP0,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP1,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP2,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP3,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP4,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP5,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP6,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for GEM1
+ *
+ */
+const uint64_t mpu_gem1_values[] = {
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP0,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP1,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP2,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP3,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP4,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP5,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP6,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for MMC
+ *
+ */
+const uint64_t mpu_mmc_values[] = {
+ LIBERO_SETTING_MMC_MPU_CFG_PMP0,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP1,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP2,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for SCB
+ *
+ */
+const uint64_t mpu_scb_values[] = {
+ LIBERO_SETTING_SCB_MPU_CFG_PMP0,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP1,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP2,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP3,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP4,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP5,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP6,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for USB
+ *
+ */
+const uint64_t mpu_usb_values[] = {
+ LIBERO_SETTING_USB_MPU_CFG_PMP0,
+ LIBERO_SETTING_USB_MPU_CFG_PMP1,
+ LIBERO_SETTING_USB_MPU_CFG_PMP2,
+ LIBERO_SETTING_USB_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for TRACE
+ *
+ */
+const uint64_t mpu_trace_values[] = {
+ LIBERO_SETTING_TRACE_MPU_CFG_PMP0,
+ LIBERO_SETTING_TRACE_MPU_CFG_PMP1,
+};
+
+
+/***************************************************************************//**
+ * MSS_MPU_auto_configure()
+ * Set MPU's up with configuration from Libero
+ *
+ *
+ * @return
+ */
+uint8_t mpu_configure(void)
+{
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC0)->PMPCFG)),
+ &(mpu_fic0_values),
+ sizeof(mpu_fic0_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC1)->PMPCFG)),
+ &(mpu_fic1_values),
+ sizeof(mpu_fic1_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC2)->PMPCFG)),
+ &(mpu_fic2_values),
+ sizeof(mpu_fic2_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_CRYPTO)->PMPCFG)),
+ &(mpu_crypto_values),
+ sizeof(mpu_crypto_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_GEM0)->PMPCFG)),
+ &(mpu_gem0_values),
+ sizeof(mpu_gem0_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_GEM1)->PMPCFG)),
+ &(mpu_gem1_values),
+ sizeof(mpu_gem1_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_USB)->PMPCFG)),
+ &(mpu_usb_values),
+ sizeof(mpu_usb_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_MMC)->PMPCFG)),
+ &(mpu_mmc_values),
+ sizeof(mpu_mmc_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_SCB)->PMPCFG)),
+ &(mpu_scb_values),
+ sizeof(mpu_scb_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_TRACE)->PMPCFG)),
+ &(mpu_trace_values),
+ sizeof(mpu_trace_values));
+
+ return(0);
+}
+
+
+
+
+
+/***************************************************************************//**
+*/
+uint8_t MSS_MPU_configure(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t base,
+ uint64_t size,
+ uint8_t permission,
+ mss_mpu_addrm_t matching_mode,
+ uint8_t lock_en)
+{
+ uint64_t temp = size, cnt=0ULL;
+ uint64_t range;
+
+ /*size must be minimum 4k
+ Size must be power of 2
+ different masters have different number of regions*/
+ if((size >= 4096ULL) && (0U == (size & (size - 1U))) && (pmp_region < num_pmp_lut[master_port]))
+ {
+ while((0 == (temp & 0x01U)))
+ {
+ cnt++;
+ temp >>= 1U;
+ }
+
+ range = (1ULL << (cnt-1U))-1U;
+
+ MSS_MPU(master_port)->PMPCFG[pmp_region].raw = (base | range) >> 2U;
+
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode = (uint8_t)(permission |
+ (uint8_t)(matching_mode << 3U) |
+ (lock_en << 0x7U));
+
+ return ((uint8_t)0);
+ }
+ else
+ {
+ return ((uint8_t)1);
+ }
+}
+
+uint8_t MSS_MPU_get_config(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t* base,
+ uint64_t* size,
+ uint8_t* permission,
+ mss_mpu_addrm_t* matching_mode,
+ uint8_t* lock_en)
+{
+ uint64_t reg;
+
+ /*All AXI external masters dont have same number of PMP regions*/
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ reg = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.pmp;
+ *base = pmp_get_napot_base_and_range(reg, size);
+
+ reg = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode;
+ *lock_en = ( reg >> 0x7U) & 0x1U;
+ *matching_mode = (mss_mpu_addrm_t)( (reg >> 3ULL) & 0x3U);
+ *permission = reg & 0x7U;
+
+ return ((uint8_t)0);
+ }
+ else
+ {
+ return ((uint8_t)1);
+ }
+}
+
+static uint64_t pmp_get_napot_base_and_range(uint64_t reg, uint64_t *range)
+{
+ /* construct a mask of all bits bar the top bit */
+ uint64_t mask = 0U;
+ uint64_t base = reg;
+ uint64_t numbits = (sizeof(uint64_t) * 8U) + 2U;
+ mask = (mask - 1U) >> 1U;
+
+ while (mask)
+ {
+ if ((reg & mask) == mask)
+ {
+ /* this is the mask to use */
+ base = reg & ~mask;
+ break;
+ }
+ mask >>= 1U;
+ numbits--;
+ }
+
+ *range = (1LU << numbits);
+ return (base << 2U);
+}
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mpu.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mpu.h
new file mode 100644
index 00000000..6b4e1abb
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mpu.h
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_mpu.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS MPU driver APIs for configuring access regions for
+ * the external masters.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_MPU_H
+#define MSS_MPU_H
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+/***************************************************************************//**
+
+ */
+#define MPU_MODE_READ_ACCESS (1U << 0U)
+#define MPU_MODE_WRITE_ACCESS (1U << 1U)
+#define MPU_MODE_EXEC_ACCESS (1U << 2U)
+
+typedef enum {
+ MSS_MPU_FIC0 = 0x00,
+ MSS_MPU_FIC1,
+ MSS_MPU_FIC2,
+ MSS_MPU_CRYPTO,
+ MSS_MPU_GEM0,
+ MSS_MPU_GEM1,
+ MSS_MPU_USB,
+ MSS_MPU_MMC,
+ MSS_MPU_SCB,
+ MSS_MPU_TRACE,
+ MSS_MPU_SEG0,
+ MSS_MPU_SEG1,
+} mss_mpu_mport_t;
+
+typedef enum {
+ MSS_MPU_AM_OFF = 0x00U,
+ MSS_MPU_AM_NAPOT = 0x03U,
+} mss_mpu_addrm_t;
+
+typedef enum {
+ MSS_MPU_PMP_REGION0 = 0x00,
+ MSS_MPU_PMP_REGION1,
+ MSS_MPU_PMP_REGION2,
+ MSS_MPU_PMP_REGION3,
+ MSS_MPU_PMP_REGION4,
+ MSS_MPU_PMP_REGION5,
+ MSS_MPU_PMP_REGION6,
+ MSS_MPU_PMP_REGION7,
+ MSS_MPU_PMP_REGION8,
+ MSS_MPU_PMP_REGION9,
+ MSS_MPU_PMP_REGION10,
+ MSS_MPU_PMP_REGION11,
+ MSS_MPU_PMP_REGION12,
+ MSS_MPU_PMP_REGION13,
+ MSS_MPU_PMP_REGION14,
+ MSS_MPU_PMP_REGION15,
+} mss_mpu_pmp_region_t;
+
+extern uint8_t num_pmp_lut[10];
+
+#ifndef __I
+#define __I const volatile
+#endif
+#ifndef __IO
+#define __IO volatile
+#endif
+#ifndef __O
+#define __O volatile
+#endif
+
+
+typedef struct {
+ union {
+ struct
+ {
+ __IO uint64_t pmp : 38;
+ __IO uint64_t rsrvd : 18;
+ __IO uint64_t mode : 8;
+ } MPUCFG_TypeDef;
+ uint64_t raw;
+ };
+} MPU_CFG;
+
+typedef struct
+{
+ __IO uint64_t addr : 38;
+ __IO uint64_t rw : 1;
+ __IO uint64_t id : 4;
+ __IO uint64_t failed : 1;
+ __IO uint64_t padding : (64-44);
+} MPU_FailStatus_TypeDef;
+
+typedef struct
+{
+ MPU_CFG PMPCFG[16U];
+ __IO MPU_FailStatus_TypeDef STATUS;
+} MPU_TypeDef;
+
+
+
+#define MSS_MPU(master) ( (MPU_TypeDef*) (0x20005000UL + ((master) << 8U)))
+
+
+uint8_t mpu_configure(void);
+
+
+uint8_t MSS_MPU_configure(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t base,
+ uint64_t size,
+ uint8_t permission,
+ mss_mpu_addrm_t matching_mode,
+ uint8_t lock_en);
+
+uint8_t MSS_MPU_get_config(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t* base,
+ uint64_t* size,
+ uint8_t* permission,
+ mss_mpu_addrm_t* matching_mode,
+ uint8_t* lock_en);
+
+static inline uint8_t MSS_MPU_lock_region(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= (0x1U << 7U);
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+/*permission value could be bitwise or of:
+ * MPU_MODE_READ_ACCESS
+ * MPU_MODE_WRITE_ACCESS
+ * MPU_MODE_EXEC_ACCESS
+ *
+ * */
+static inline uint8_t MSS_MPU_set_permission(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint8_t permission)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= permission;
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+static inline uint8_t MSS_MPU_get_permission(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint8_t* permission)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ *permission = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode & 0x7U;
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+/*read the Fail status register when there is a MPU access failure.
+ See the return type MPU_FailStatus_TypeDef for the details of the STATUS bitfield.
+ The status failed bit(offset 42) needs to be reset using the corresponding bit
+ in SYSREG->mpu_violation_sr
+ */
+static inline MPU_FailStatus_TypeDef MSS_MPU_get_failstatus(mss_mpu_mport_t master_port)
+{
+ return (MSS_MPU(master_port)->STATUS);
+}
+
+#endif /* ! SIFIVE_HIFIVE_UNLEASHED */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_MPU_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mtrap.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mtrap.c
new file mode 100644
index 00000000..2226d7bf
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mtrap.c
@@ -0,0 +1,783 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ *
+ * @file mss_mtrap.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief trap functions
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+void handle_local_interrupt(uint8_t interrupt_no);
+void handle_m_soft_interrupt(void);
+void handle_m_timer_interrupt(void);
+void illegal_insn_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void misaligned_store_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void misaligned_load_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void pmp_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void trap_from_machine_mode(uintptr_t * regs, uintptr_t dummy, uintptr_t mepc);
+void bad_trap(uintptr_t* regs, uintptr_t dummy, uintptr_t mepc);
+
+
+void bad_trap(uintptr_t* regs, uintptr_t dummy, uintptr_t mepc)
+{
+ (void)regs;
+ (void)dummy;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void misaligned_store_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void misaligned_load_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void illegal_insn_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void pmp_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for external interrupts.
+ */
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+uint8_t (*ext_irq_handler_table[PLIC_NUM_SOURCES])(void) =
+{
+ Invalid_IRQHandler,
+ l2_metadata_corr_IRQHandler,
+ l2_metadata_uncorr_IRQHandler,
+ l2_data_corr_IRQHandler,
+ l2_data_uncorr_IRQHandler,
+ dma_ch0_DONE_IRQHandler,
+ dma_ch0_ERR_IRQHandler,
+ dma_ch1_DONE_IRQHandler,
+ dma_ch1_ERR_IRQHandler,
+ dma_ch2_DONE_IRQHandler,
+ dma_ch2_ERR_IRQHandler,
+ dma_ch3_DONE_IRQHandler,
+ dma_ch3_ERR_IRQHandler,
+ gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler,
+ gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler,
+ gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler,
+ gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler,
+ gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler,
+ gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler,
+ gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler,
+ gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler,
+ gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler,
+ gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler,
+ gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler,
+ gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler,
+ gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler,
+
+ gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler,
+ gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler,
+ gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler,
+ gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler,
+ gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler,
+ gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler,
+ gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler,
+ gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler,
+ gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler,
+ gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler,
+ gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler,
+ gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler,
+ gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler,
+ gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler,
+ gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler,
+
+ gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler,
+ gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler,
+ gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler,
+ gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler,
+
+ gpio1_bit18_plic_32_IRQHandler,
+ gpio1_bit19_plic_33_IRQHandler,
+ gpio1_bit20_plic_34_IRQHandler,
+ gpio1_bit21_plic_35_IRQHandler,
+ gpio1_bit22_plic_36_IRQHandler,
+ gpio1_bit23_plic_37_IRQHandler,
+
+ gpio0_non_direct_plic_IRQHandler,
+ gpio1_non_direct_plic_IRQHandler,
+ gpio2_non_direct_plic_IRQHandler,
+
+ spi0_plic_IRQHandler,
+ spi1_plic_IRQHandler,
+ external_can0_plic_IRQHandler,
+ can1_IRQHandler,
+ External_i2c0_main_plic_IRQHandler,
+ External_i2c0_alert_plic_IRQHandler,
+ i2c0_sus_plic_IRQHandler,
+ i2c1_main_plic_IRQHandler,
+ i2c1_alert_plic_IRQHandler,
+ i2c1_sus_plic_IRQHandler,
+ mac0_int_plic_IRQHandler,
+ mac0_queue1_plic_IRQHandler,
+ mac0_queue2_plic_IRQHandler,
+ mac0_queue3_plic_IRQHandler,
+ mac0_emac_plic_IRQHandler,
+ mac0_mmsl_plic_IRQHandler,
+ mac1_int_plic_IRQHandler,
+ mac1_queue1_plic_IRQHandler,
+ mac1_queue2_plic_IRQHandler,
+ mac1_queue3_plic_IRQHandler,
+ mac1_emac_plic_IRQHandler,
+ mac1_mmsl_plic_IRQHandler,
+ ddrc_train_plic_IRQHandler,
+ scb_interrupt_plic_IRQHandler,
+ ecc_error_plic_IRQHandler,
+ ecc_correct_plic_IRQHandler,
+ rtc_wakeup_plic_IRQHandler,
+ rtc_match_plic_IRQHandler,
+ timer1_plic_IRQHandler,
+ timer2_plic_IRQHandler,
+ envm_plic_IRQHandler,
+ qspi_plic_IRQHandler,
+ usb_dma_plic_IRQHandler,
+ usb_mc_plic_IRQHandler,
+ mmc_main_plic_IRQHandler,
+ mmc_wakeup_plic_IRQHandler,
+ mmuart0_plic_77_IRQHandler,
+ mmuart1_plic_IRQHandler,
+ mmuart2_plic_IRQHandler,
+ mmuart3_plic_IRQHandler,
+ mmuart4_plic_IRQHandler,
+
+ g5c_devrst_plic_IRQHandler,
+ g5c_message_plic_IRQHandler,
+ usoc_vc_interrupt_plic_IRQHandler,
+ usoc_smb_interrupt_plic_IRQHandler,
+ e51_0_Maintence_plic_IRQHandler,
+
+ wdog0_mvrp_plic_IRQHandler,
+ wdog1_mvrp_plic_IRQHandler, /*100 contains multiple interrupts- */
+ wdog2_mvrp_plic_IRQHandler,
+ wdog3_mvrp_plic_IRQHandler,
+ wdog4_mvrp_plic_IRQHandler,
+ wdog0_tout_plic_IRQHandler,
+ wdog1_tout_plic_IRQHandler,
+ wdog2_tout_plic_IRQHandler,
+ wdog3_tout_plic_IRQHandler,
+ wdog4_tout_plic_IRQHandler,
+
+ g5c_mss_spi_plic_IRQHandler,
+ volt_temp_alarm_plic_IRQHandler,
+ athena_complete_plic_IRQHandler,
+ athena_alarm_plic_IRQHandler,
+ athena_bus_error_plic_IRQHandler,
+ usoc_axic_us_plic_IRQHandler,
+ usoc_axic_ds_plic_IRQHandler,
+
+ reserved_104_plic_IRQHandler,
+
+ fabric_f2h_0_plic_IRQHandler,
+ fabric_f2h_1_plic_IRQHandler,
+ fabric_f2h_2_plic_IRQHandler,
+ fabric_f2h_3_plic_IRQHandler,
+ fabric_f2h_4_plic_IRQHandler,
+ fabric_f2h_5_plic_IRQHandler,
+ fabric_f2h_6_plic_IRQHandler,
+ fabric_f2h_7_plic_IRQHandler,
+ fabric_f2h_8_plic_IRQHandler,
+ fabric_f2h_9_plic_IRQHandler,
+
+ fabric_f2h_10_plic_IRQHandler,
+ fabric_f2h_11_plic_IRQHandler,
+ fabric_f2h_12_plic_IRQHandler,
+ fabric_f2h_13_plic_IRQHandler,
+ fabric_f2h_14_plic_IRQHandler,
+ fabric_f2h_15_plic_IRQHandler,
+ fabric_f2h_16_plic_IRQHandler,
+ fabric_f2h_17_plic_IRQHandler,
+ fabric_f2h_18_plic_IRQHandler,
+ fabric_f2h_19_plic_IRQHandler,
+
+ fabric_f2h_20_plic_IRQHandler,
+ fabric_f2h_21_plic_IRQHandler,
+ fabric_f2h_22_plic_IRQHandler,
+ fabric_f2h_23_plic_IRQHandler,
+ fabric_f2h_24_plic_IRQHandler,
+ fabric_f2h_25_plic_IRQHandler,
+ fabric_f2h_26_plic_IRQHandler,
+ fabric_f2h_27_plic_IRQHandler,
+ fabric_f2h_28_plic_IRQHandler,
+ fabric_f2h_29_plic_IRQHandler,
+
+ fabric_f2h_30_plic_IRQHandler,
+ fabric_f2h_31_plic_IRQHandler,
+
+ fabric_f2h_32_plic_IRQHandler,
+ fabric_f2h_33_plic_IRQHandler,
+ fabric_f2h_34_plic_IRQHandler,
+ fabric_f2h_35_plic_IRQHandler,
+ fabric_f2h_36_plic_IRQHandler,
+ fabric_f2h_37_plic_IRQHandler,
+ fabric_f2h_38_plic_IRQHandler,
+ fabric_f2h_39_plic_IRQHandler,
+ fabric_f2h_40_plic_IRQHandler,
+ fabric_f2h_41_plic_IRQHandler,
+
+ fabric_f2h_42_plic_IRQHandler,
+ fabric_f2h_43_plic_IRQHandler,
+ fabric_f2h_44_plic_IRQHandler,
+ fabric_f2h_45_plic_IRQHandler,
+ fabric_f2h_46_plic_IRQHandler,
+ fabric_f2h_47_plic_IRQHandler,
+ fabric_f2h_48_plic_IRQHandler,
+ fabric_f2h_49_plic_IRQHandler,
+ fabric_f2h_50_plic_IRQHandler,
+ fabric_f2h_51_plic_IRQHandler,
+
+ fabric_f2h_52_plic_IRQHandler,
+ fabric_f2h_53_plic_IRQHandler,
+ fabric_f2h_54_plic_IRQHandler,
+ fabric_f2h_55_plic_IRQHandler,
+ fabric_f2h_56_plic_IRQHandler,
+ fabric_f2h_57_plic_IRQHandler,
+ fabric_f2h_58_plic_IRQHandler,
+ fabric_f2h_59_plic_IRQHandler,
+ fabric_f2h_60_plic_IRQHandler,
+ fabric_f2h_61_plic_IRQHandler,
+
+ fabric_f2h_62_plic_IRQHandler,
+ fabric_f2h_63_plic_IRQHandler,
+
+ bus_error_unit_hart_0_plic_IRQHandler,
+ bus_error_unit_hart_1_plic_IRQHandler,
+ bus_error_unit_hart_2_plic_IRQHandler,
+ bus_error_unit_hart_3_plic_IRQHandler,
+ bus_error_unit_hart_4_plic_IRQHandler
+};
+
+#define E51_LOCAL_NUM_SOURCES 48U
+
+
+void (*local_irq_handler_e51_table[E51_LOCAL_NUM_SOURCES])(void) =
+{
+ maintenance_e51_local_IRQHandler_0, /* reference multiple interrupts */
+ usoc_smb_interrupt_e51_local_IRQHandler_1,
+ usoc_vc_interrupt_e51_local_IRQHandler_2,
+ g5c_message_e51_local_IRQHandler_3,
+ g5c_devrst_e51_local_IRQHandler_4,
+ wdog4_tout_e51_local_IRQHandler_5,
+ wdog3_tout_e51_local_IRQHandler_6,
+ wdog2_tout_e51_local_IRQHandler_7,
+ wdog1_tout_e51_local_IRQHandler_8,
+ wdog0_tout_e51_local_IRQHandler_9,
+ wdog0_mvrp_e51_local_IRQHandler_10,
+ mmuart0_e51_local_IRQHandler_11,
+ envm_e51_local_IRQHandler_12,
+ ecc_correct_e51_local_IRQHandler_13,
+ ecc_error_e51_local_IRQHandler_14,
+ scb_interrupt_e51_local_IRQHandler_15,
+ fabric_f2h_32_e51_local_IRQHandler_16,
+ fabric_f2h_33_e51_local_IRQHandler_17,
+ fabric_f2h_34_e51_local_IRQHandler_18,
+ fabric_f2h_35_e51_local_IRQHandler_19,
+ fabric_f2h_36_e51_local_IRQHandler_20,
+ fabric_f2h_37_e51_local_IRQHandler_21,
+ fabric_f2h_38_e51_local_IRQHandler_22,
+ fabric_f2h_39_e51_local_IRQHandler_23,
+ fabric_f2h_40_e51_local_IRQHandler_24,
+ fabric_f2h_41_e51_local_IRQHandler_25,
+
+ fabric_f2h_42_e51_local_IRQHandler_26,
+ fabric_f2h_43_e51_local_IRQHandler_27,
+ fabric_f2h_44_e51_local_IRQHandler_28,
+ fabric_f2h_45_e51_local_IRQHandler_29,
+ fabric_f2h_46_e51_local_IRQHandler_30,
+ fabric_f2h_47_e51_local_IRQHandler_31,
+ fabric_f2h_48_e51_local_IRQHandler_32,
+ fabric_f2h_49_e51_local_IRQHandler_33,
+ fabric_f2h_50_e51_local_IRQHandler_34,
+ fabric_f2h_51_e51_local_IRQHandler_35,
+
+ fabric_f2h_52_e51_local_IRQHandler_36,
+ fabric_f2h_53_e51_local_IRQHandler_37,
+ fabric_f2h_54_e51_local_IRQHandler_38,
+ fabric_f2h_55_e51_local_IRQHandler_39,
+ fabric_f2h_56_e51_local_IRQHandler_40,
+ fabric_f2h_57_e51_local_IRQHandler_41,
+ fabric_f2h_58_e51_local_IRQHandler_42,
+ fabric_f2h_59_e51_local_IRQHandler_43,
+ fabric_f2h_60_e51_local_IRQHandler_44,
+ fabric_f2h_61_e51_local_IRQHandler_45,
+
+ fabric_f2h_62_e51_local_IRQHandler_46,
+ fabric_f2h_63_e51_local_IRQHandler_47
+};
+
+
+typedef void (*local_int_p_t)(void);
+
+/* U54 1 */
+local_int_p_t local_irq_handler_u54_1_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_1_local_IRQHandler_3,
+ mac_emac_u54_1_local_IRQHandler_4,
+ mac_queue3_u54_1_local_IRQHandler_5,
+ mac_queue2_u54_1_local_IRQHandler_6,
+ mac_queue1_u54_1_local_IRQHandler_7,
+ mac_int_u54_1_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h1_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h1_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 2 */
+local_int_p_t local_irq_handler_u54_2_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_2_local_IRQHandler_3,
+ mac_emac_u54_2_local_IRQHandler_4,
+ mac_queue3_u54_2_local_IRQHandler_5,
+ mac_queue2_u54_2_local_IRQHandler_6,
+ mac_queue1_u54_2_local_IRQHandler_7,
+ mac_int_u54_2_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h2_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h2_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 3 */
+local_int_p_t local_irq_handler_u54_3_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_3_local_IRQHandler_3,
+ mac_emac_u54_3_local_IRQHandler_4,
+ mac_queue3_u54_3_local_IRQHandler_5,
+ mac_queue2_u54_3_local_IRQHandler_6,
+ mac_queue1_u54_3_local_IRQHandler_7,
+ mac_int_u54_3_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h3_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h3_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 4 */
+local_int_p_t local_irq_handler_u54_4_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_4_local_IRQHandler_3,
+ mac_emac_u54_4_local_IRQHandler_4,
+ mac_queue3_u54_4_local_IRQHandler_5,
+ mac_queue2_u54_4_local_IRQHandler_6,
+ mac_queue1_u54_4_local_IRQHandler_7,
+ mac_int_u54_4_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h4_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h4_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+local_int_p_t *local_int_mux[5] =
+{
+ local_irq_handler_e51_table,
+ local_irq_handler_u54_1_table,
+ local_irq_handler_u54_2_table,
+ local_irq_handler_u54_3_table,
+ local_irq_handler_u54_4_table
+};
+
+#else
+uint8_t (*ext_irq_handler_table[PLIC_NUM_SOURCES])(void) =
+{
+ Invalid_IRQHandler,
+ External_1_IRQHandler,
+ External_2_IRQHandler,
+ External_3_IRQHandler,
+ USART0_plic_4_IRQHandler,
+ External_5_IRQHandler,
+ External_6_IRQHandler,
+ External_7_IRQHandler,
+ External_8_IRQHandler,
+ External_9_IRQHandler,
+ External_10_IRQHandler,
+ External_11_IRQHandler,
+ External_12_IRQHandler,
+ External_13_IRQHandler,
+ External_14_IRQHandler,
+ External_15_IRQHandler,
+ External_16_IRQHandler,
+ External_17_IRQHandler,
+ External_18_IRQHandler,
+ External_19_IRQHandler,
+ External_20_IRQHandler,
+ External_21_IRQHandler,
+ External_22_IRQHandler,
+ dma_ch0_DONE_IRQHandler,
+ dma_ch0_ERR_IRQHandler,
+ dma_ch1_DONE_IRQHandler,
+ dma_ch1_ERR_IRQHandler,
+ dma_ch2_DONE_IRQHandler,
+ dma_ch2_ERR_IRQHandler,
+ dma_ch3_DONE_IRQHandler,
+ dma_ch3_ERR_IRQHandler,
+ External_31_IRQHandler,
+ External_32_IRQHandler,
+ External_33_IRQHandler,
+ External_34_IRQHandler,
+ External_35_IRQHandler,
+ External_36_IRQHandler,
+ External_37_IRQHandler,
+ External_38_IRQHandler,
+ External_39_IRQHandler,
+ External_40_IRQHandler,
+ External_41_IRQHandler,
+ External_42_IRQHandler,
+ External_43_IRQHandler,
+ External_44_IRQHandler,
+ External_45_IRQHandler,
+ External_46_IRQHandler,
+ External_47_IRQHandler,
+ External_48_IRQHandler,
+ External_49_IRQHandler,
+ External_50_IRQHandler,
+ External_51_IRQHandler,
+ External_52_IRQHandler,
+ MAC0_plic_53_IRQHandler
+
+};
+#endif
+/*------------------------------------------------------------------------------
+ *
+ */
+void handle_m_ext_interrupt(void)
+{
+
+ volatile uint32_t int_num = PLIC_ClaimIRQ();
+
+ if (INVALID_IRQn == int_num)
+ {
+ return;
+ }
+
+ uint8_t disable = EXT_IRQ_KEEP_ENABLED;
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ disable = ext_irq_handler_table[int_num /* + OFFSET_TO_MSS_GLOBAL_INTS Think this was required in early bitfile */]();
+#else
+ disable = ext_irq_handler_table[int_num]();
+#endif
+
+ PLIC_CompleteIRQ(int_num);
+
+ if(EXT_IRQ_DISABLE == disable)
+ {
+ PLIC_DisableIRQ((PLIC_IRQn_Type)int_num);
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void handle_local_interrupt(uint8_t interrupt_no)
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED /* no local interrupts on unleashed */
+ uint64_t mhart_id = read_csr(mhartid);
+ uint8_t local_interrupt_no = (uint8_t)(interrupt_no - 16U);
+ local_int_p_t *local_int_table = local_int_mux[mhart_id];
+
+ (*local_int_table[local_interrupt_no])();
+
+#endif
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void trap_from_machine_mode(uintptr_t * regs, uintptr_t dummy, uintptr_t mepc)
+{
+ volatile uintptr_t mcause = read_csr(mcause);
+
+ if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) > 15U)&& ((mcause & MCAUSE_CAUSE) < 64U))
+ {
+ handle_local_interrupt((uint8_t)(mcause & MCAUSE_CAUSE));
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT))
+ {
+ handle_m_ext_interrupt();
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_SOFT))
+ {
+ handle_m_soft_interrupt();
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER))
+ {
+ handle_m_timer_interrupt();
+ }
+ else
+ {
+ uint32_t i = 0U;
+ while(1)
+ {
+ /* wait for watchdog */
+ i++; /* added some code as SC debugger hangs if in loop doing nothing */
+ if(i == 0x1000U)
+ {
+ i = mcause; /* so mcause is not optimised out */
+ }
+ }
+ switch(mcause)
+ {
+
+ case CAUSE_LOAD_PAGE_FAULT:
+ break;
+ case CAUSE_STORE_PAGE_FAULT:
+ break;
+ case CAUSE_FETCH_ACCESS:
+ break;
+ case CAUSE_LOAD_ACCESS:
+ break;
+ case CAUSE_STORE_ACCESS:
+ break;
+ default:
+ bad_trap(regs, dummy, mepc);
+ break;
+ }
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mtrap.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mtrap.h
new file mode 100644
index 00000000..3d68eb12
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_mtrap.h
@@ -0,0 +1,92 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+#ifndef RISCV_MTRAP_H
+#define RISCV_MTRAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ASSEMBLER__
+#define read_const_csr(reg) ({ unsigned long __tmp; \
+ asm ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+#endif
+
+#define IPI_SOFT 0x01
+#define IPI_FENCE_I 0x02
+#define IPI_SFENCE_VMA 0x04
+
+#define MACHINE_STACK_SIZE (RISCV_PGSIZE) /* this is 4k for HLS and 4k for the stack*/
+#define MENTRY_HLS_OFFSET (INTEGER_CONTEXT_SIZE + SOFT_FLOAT_CONTEXT_SIZE)
+#define MENTRY_FRAME_SIZE (MENTRY_HLS_OFFSET + HLS_SIZE)
+#define MENTRY_IPI_OFFSET (MENTRY_HLS_OFFSET)
+#define MENTRY_IPI_PENDING_OFFSET (MENTRY_HLS_OFFSET + REGBYTES)
+
+#ifdef __riscv_flen
+# define SOFT_FLOAT_CONTEXT_SIZE (0)
+#else
+# define SOFT_FLOAT_CONTEXT_SIZE (8 * 32)
+#endif
+
+#define HLS_SIZE (64)
+#define INTEGER_CONTEXT_SIZE (32 * REGBYTES)
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ volatile uint32_t * ipi;
+ volatile int mipi_pending;
+ volatile int padding;
+ volatile uint64_t * timecmp;
+ volatile uint32_t * plic_m_thresh;
+ volatile uintptr_t * plic_m_ie;
+ volatile uint32_t * plic_s_thresh;
+ volatile uintptr_t * plic_s_ie;
+} hls_t;
+
+/* This code relies on the stack being allocated on a 4K boundary */
+/* also can not be bigger than 4k */
+#define MACHINE_STACK_TOP() ({ \
+ register uintptr_t sp asm ("sp"); \
+ (void *)((sp + RISCV_PGSIZE) & -RISCV_PGSIZE); })
+
+// hart-local storage
+#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
+#define OTHER_HLS(id) ((hls_t*)((void *)HLS() + RISCV_PGSIZE * ((id) - read_const_csr(mhartid))))
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*RISCV_MTRAP_H*/
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_peripherals.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_peripherals.c
new file mode 100644
index 00000000..307cd0ee
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_peripherals.c
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_peripherals.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS functions related to peripherals.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+const uint32_t LIBERO_SETTING_CONTEXT_EN[][2U] = {
+ {LIBERO_SETTING_CONTEXT_A_EN,
+ LIBERO_SETTING_CONTEXT_B_EN},
+ {LIBERO_SETTING_CONTEXT_A_EN_FIC,
+ LIBERO_SETTING_CONTEXT_B_EN_FIC},
+};
+
+/* offsets used in PERIPHERAL_SETUP array */
+#define PERIPHERAL_INDEX_OFFSET 0U /* used for sanity check */
+#define CONTEXT_EN_INDEX_OFFSET 1U
+#define CONTEXT_MASK_INDEX_OFFSET 2U
+#define CONTEXT_SUBCLK_INDEX_OFFSET 3U
+
+const uint32_t PERIPHERAL_SETUP[][4U] = {
+ {MSS_PERIPH_MMUART0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART0,SUBBLK_CLOCK_CR_MMUART0_MASK},
+ {MSS_PERIPH_MMUART1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART1,SUBBLK_CLOCK_CR_MMUART1_MASK},
+ {MSS_PERIPH_MMUART2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART2,SUBBLK_CLOCK_CR_MMUART2_MASK},
+ {MSS_PERIPH_MMUART3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART3,SUBBLK_CLOCK_CR_MMUART3_MASK},
+ {MSS_PERIPH_MMUART4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART4,SUBBLK_CLOCK_CR_MMUART4_MASK},
+ {MSS_PERIPH_WDOG0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG0,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG1,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG2,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG3,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG4,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_SPI0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI0,SUBBLK_CLOCK_CR_SPI0_MASK},
+ {MSS_PERIPH_SPI1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI1,SUBBLK_CLOCK_CR_SPI1_MASK},
+ {MSS_PERIPH_I2C0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C0,SUBBLK_CLOCK_CR_I2C0_MASK},
+ {MSS_PERIPH_I2C1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C1,SUBBLK_CLOCK_CR_I2C1_MASK},
+ {MSS_PERIPH_CAN0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN0,SUBBLK_CLOCK_CR_CAN0_MASK},
+ {MSS_PERIPH_CAN1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN1,SUBBLK_CLOCK_CR_CAN1_MASK},
+ {MSS_PERIPH_MAC0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC0,SUBBLK_CLOCK_CR_MAC0_MASK},
+ {MSS_PERIPH_MAC1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC1,SUBBLK_CLOCK_CR_MAC1_MASK},
+ {MSS_PERIPH_TIMER,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_TIMER,SUBBLK_CLOCK_CR_TIMER_MASK},
+ {MSS_PERIPH_GPIO0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO0,SUBBLK_CLOCK_CR_GPIO0_MASK},
+ {MSS_PERIPH_GPIO1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO1,SUBBLK_CLOCK_CR_GPIO1_MASK},
+ {MSS_PERIPH_GPIO2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO2,SUBBLK_CLOCK_CR_GPIO2_MASK},
+ {MSS_PERIPH_RTC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_RTC,SUBBLK_CLOCK_CR_RTC_MASK},
+ {MSS_PERIPH_H2FINT,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_H2FINT, SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_CRYPTO,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CRYPTO,SUBBLK_CLOCK_CR_ATHENA_MASK},
+ {MSS_PERIPH_USB,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_USB,SUBBLK_CLOCK_CR_USB_MASK},
+ {MSS_PERIPH_QSPIXIP,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_QSPIXIP,SUBBLK_CLOCK_CR_QSPI_MASK},
+ {MSS_PERIPH_ATHENA,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_ATHENA,SUBBLK_CLOCK_CR_ATHENA_MASK},
+ {MSS_PERIPH_TRACE,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_MAILBOX_SC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_EMMC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_CFM,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CFM,SUBBLK_CLOCK_CR_CFM_MASK},
+ {MSS_PERIPH_FIC0,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC0,SUBBLK_CLOCK_CR_FIC0_MASK},
+ {MSS_PERIPH_FIC1,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC1,SUBBLK_CLOCK_CR_FIC1_MASK},
+ {MSS_PERIPH_FIC2,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC2,SUBBLK_CLOCK_CR_FIC2_MASK},
+ {MSS_PERIPH_FIC3,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC3,SUBBLK_CLOCK_CR_FIC3_MASK}
+};
+
+/**
+ * If contexts set-up, verify allowed access to peripheral
+ * @param option - Two option, , FIC enables set separately. CONTEXT_EN_INDEX_FIC or CONTEXT_EN_INDEX
+ * @param periph_context_mask See CONTEXT_EN_MASK_ defines for options
+ * @param hart The hart ID of origin of request.
+ * @return
+ */
+static inline uint8_t verify_context_enable(uint8_t option, uint32_t periph_context_mask , uint32_t hart)
+{
+ uint8_t result = 1U;
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ if (hart != (uint8_t) 0U)
+ {
+ if (LIBERO_SETTING_CONTEXT_A_HART_EN & hart )
+ {
+ if (LIBERO_SETTING_CONTEXT_EN[option][0U] & periph_context_mask)
+ {
+ result = 0U;
+ }
+ }
+
+ if (LIBERO_SETTING_CONTEXT_B_HART_EN & hart )
+ {
+ if (LIBERO_SETTING_CONTEXT_EN[option][1U] & periph_context_mask)
+ {
+ result = 0U;
+ }
+ }
+ }
+ else
+ {
+ hart = 0U;
+ }
+#else
+ (void)hart;
+ (void)periph_context_mask;
+ (void)option;
+ result = 0U;
+#endif
+ return result;
+}
+
+/**
+ * Turn on/off mss peripheral as required
+ * @param peripheral_mask
+ * @param req_state
+ */
+static inline void peripheral_on_off(uint32_t peripheral_mask , PERIPH_RESET_STATE req_state)
+{
+ if (req_state == PERIPHERAL_OFF)
+ {
+ /* Turn off clock */
+ SYSREG->SUBBLK_CLOCK_CR &= (uint32_t)~(peripheral_mask);
+ /* Hold in reset */
+ SYSREG->SOFT_RESET_CR |= (uint32_t)(peripheral_mask);
+ }
+ else
+ {
+ /* Turn on clock */
+ SYSREG->SUBBLK_CLOCK_CR |= (peripheral_mask);
+ /* Remove soft reset */
+ SYSREG->SOFT_RESET_CR &= (uint32_t)~(peripheral_mask);
+ }
+}
+
+
+/***************************************************************************//**
+ * See mss_peripherals.h for details of how to use this function.
+ */
+__attribute__((weak)) uint8_t mss_config_clk_rst(mss_peripherals peripheral, uint8_t hart, PERIPH_RESET_STATE req_state)
+{
+ uint8_t result = 1U;
+
+ ASSERT(PERIPHERAL_SETUP[peripheral][PERIPHERAL_INDEX_OFFSET] == peripheral);
+
+ result = verify_context_enable(PERIPHERAL_SETUP[peripheral][CONTEXT_EN_INDEX_OFFSET], PERIPHERAL_SETUP[peripheral][CONTEXT_MASK_INDEX_OFFSET] , hart);
+
+ if (result == 0U)
+ {
+ peripheral_on_off(PERIPHERAL_SETUP[peripheral][CONTEXT_SUBCLK_INDEX_OFFSET] , req_state);
+ }
+ return result;
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_peripherals.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_peripherals.h
new file mode 100644
index 00000000..0f6f217c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_peripherals.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_peripherals.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS fumnctions related to MSS peripherals.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_PERIPHERALS_H
+#define MSS_PERIPHERALS_H
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_CONTEXT_A_EN)
+#define LIBERO_SETTING_CONTEXT_A_EN 0x00000000UL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_EN)
+#define LIBERO_SETTING_CONTEXT_B_EN 0x00000000UL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_A_EN_FIC)
+#define LIBERO_SETTING_CONTEXT_A_EN_FIC 0x0000000FUL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_EN_FIC)
+#define LIBERO_SETTING_CONTEXT_B_EN_FIC 0x0000000FUL
+#endif
+
+/***************************************************************************//**
+
+ */
+typedef enum PERIPH_RESET_STATE_
+{
+
+ PERIPHERAL_ON = 0x00, /*!< 0 RST and clk ON */
+ PERIPHERAL_OFF = 0x01, /*!< 1 RST and clk OFF */
+} PERIPH_RESET_STATE;
+
+#define CONTEXT_EN_INDEX 0x00U
+#define CONTEXT_EN_INDEX_FIC 0x01U
+#define SUBBLK_CLOCK_NA_MASK 0x00U
+
+typedef enum mss_peripherals_ {
+ MSS_PERIPH_MMUART0 = 0U,
+ MSS_PERIPH_MMUART1 = 1U,
+ MSS_PERIPH_MMUART2 = 2U,
+ MSS_PERIPH_MMUART3 = 3U,
+ MSS_PERIPH_MMUART4 = 4U,
+ MSS_PERIPH_WDOG0 = 5U,
+ MSS_PERIPH_WDOG1 = 6U,
+ MSS_PERIPH_WDOG2 = 7U,
+ MSS_PERIPH_WDOG3 = 8U,
+ MSS_PERIPH_WDOG4 = 9U,
+ MSS_PERIPH_SPI0 = 10U,
+ MSS_PERIPH_SPI1 = 11U,
+ MSS_PERIPH_I2C0 = 12U,
+ MSS_PERIPH_I2C1 = 13U,
+ MSS_PERIPH_CAN0 = 14U,
+ MSS_PERIPH_CAN1 = 15U,
+ MSS_PERIPH_MAC0 = 16U,
+ MSS_PERIPH_MAC1 = 17U,
+ MSS_PERIPH_TIMER = 18U,
+ MSS_PERIPH_GPIO0 = 19U,
+ MSS_PERIPH_GPIO1 = 20U,
+ MSS_PERIPH_GPIO2 = 21U,
+ MSS_PERIPH_RTC = 22U,
+ MSS_PERIPH_H2FINT = 23U,
+ MSS_PERIPH_CRYPTO = 24U,
+ MSS_PERIPH_USB = 25U,
+ MSS_PERIPH_QSPIXIP = 26U,
+ MSS_PERIPH_ATHENA = 27U,
+ MSS_PERIPH_TRACE = 28U,
+ MSS_PERIPH_MAILBOX_SC = 29U,
+ MSS_PERIPH_EMMC = 30U,
+ MSS_PERIPH_CFM = 31U,
+ MSS_PERIPH_FIC0 = 32U,
+ MSS_PERIPH_FIC1 = 33U,
+ MSS_PERIPH_FIC2 = 34U,
+ MSS_PERIPH_FIC3 = 35U
+} mss_peripherals;
+
+
+/***************************************************************************//**
+ This function is used to turn on or off a peripheral. If contexts have been
+ configured, these will be checked to see if peripheral should be controlled
+ from a particular context.
+
+ @param peripheral
+ See enum mss_peripherals for list of peripherals
+
+ @param hart
+ Origin hart of this request
+
+ @req_state
+ Turn peripheral on or off:
+ - PERIPHERAL_ON
+ - PERIPHERAL_OFF
+ Example:
+ @code
+ uint8_t err_status;
+ err_status = mss_config_clk_rst(MSS_PERIPH_MMUART0, (uint8_t) origin_hart_ID, PERIPHERAL_ON);
+
+ if(0U != err_status)
+ {
+ print_uart0("\n\r Context not allowed to access UART0 from hart:%d\n\nr", origin_hart_ID);
+ }
+ @endcode
+ */
+uint8_t mss_config_clk_rst(mss_peripherals peripheral, uint8_t hart, PERIPH_RESET_STATE req_state);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_PERIPHERALS_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_plic.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_plic.c
new file mode 100644
index 00000000..15297e97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_plic.c
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_plic.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PLIC and PRCI access data structures and functions.
+ *
+ * PLIC related data which cannot be placed in mss_plic.h
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const unsigned long plic_hart_lookup[5U] = {0U, 1U, 3U, 5U, 7U};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_plic.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_plic.h
new file mode 100644
index 00000000..16c16029
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_plic.h
@@ -0,0 +1,1026 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_plic.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PLIC and PRCI access data structures and functions.
+ *
+ * Definitions and functions associated with PLIC interrupts.
+ *
+ */
+#ifndef MSS_PLIC_H
+#define MSS_PLIC_H
+
+#include
+#ifndef CONFIG_OPENSBI
+#include "encoding.h"
+#endif
+
+#include "mss_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *Return value from External IRQ handler. This will be used to disable the
+ *Return External interrupt.
+ */
+#define EXT_IRQ_KEEP_ENABLED 0U
+#define EXT_IRQ_DISABLE 1U
+
+/*------------------------------------------------------------------------------
+ *
+ */
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+uint8_t Invalid_IRQHandler(void);
+uint8_t l2_metadata_corr_IRQHandler(void);
+uint8_t l2_metadata_uncorr_IRQHandler(void);
+uint8_t l2_data_corr_IRQHandler(void);
+uint8_t l2_data_uncorr_IRQHandler(void);
+uint8_t dma_ch0_DONE_IRQHandler(void);
+uint8_t dma_ch0_ERR_IRQHandler(void);
+uint8_t dma_ch1_DONE_IRQHandler(void);
+uint8_t dma_ch1_ERR_IRQHandler(void);
+uint8_t dma_ch2_DONE_IRQHandler(void);
+uint8_t dma_ch2_ERR_IRQHandler(void);
+uint8_t dma_ch3_DONE_IRQHandler(void);
+uint8_t dma_ch3_ERR_IRQHandler(void);
+uint8_t gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler(void);
+uint8_t gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler(void);
+uint8_t gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler(void);
+uint8_t gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler(void);
+uint8_t gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler(void);
+uint8_t gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler(void);
+uint8_t gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler(void);
+uint8_t gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler(void);
+uint8_t gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler(void);
+uint8_t gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler(void);
+uint8_t gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler(void);
+uint8_t gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler(void);
+uint8_t gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler(void);
+
+uint8_t gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler(void);
+uint8_t gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler(void);
+uint8_t gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler(void);
+uint8_t gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler(void);
+uint8_t gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler(void);
+uint8_t gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler(void);
+uint8_t gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler(void);
+uint8_t gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler(void);
+uint8_t gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler(void);
+uint8_t gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler(void);
+uint8_t gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler(void);
+uint8_t gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler(void);
+uint8_t gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler(void);
+uint8_t gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler(void);
+uint8_t gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler(void);
+
+uint8_t gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler(void);
+uint8_t gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler(void);
+uint8_t gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler(void);
+uint8_t gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler(void);
+
+uint8_t gpio1_bit18_plic_32_IRQHandler(void);
+uint8_t gpio1_bit19_plic_33_IRQHandler(void);
+uint8_t gpio1_bit20_plic_34_IRQHandler(void);
+uint8_t gpio1_bit21_plic_35_IRQHandler(void);
+uint8_t gpio1_bit22_plic_36_IRQHandler(void);
+uint8_t gpio1_bit23_plic_37_IRQHandler(void);
+
+uint8_t gpio0_non_direct_plic_IRQHandler(void);
+uint8_t gpio1_non_direct_plic_IRQHandler(void);
+uint8_t gpio2_non_direct_plic_IRQHandler(void);
+
+uint8_t spi0_plic_IRQHandler(void);
+uint8_t spi1_plic_IRQHandler(void);
+uint8_t external_can0_plic_IRQHandler(void);
+uint8_t can1_IRQHandler(void);
+uint8_t External_i2c0_main_plic_IRQHandler(void);
+uint8_t External_i2c0_alert_plic_IRQHandler(void);
+uint8_t i2c0_sus_plic_IRQHandler(void);
+uint8_t i2c1_main_plic_IRQHandler(void);
+uint8_t i2c1_alert_plic_IRQHandler(void);
+uint8_t i2c1_sus_plic_IRQHandler(void);
+uint8_t mac0_int_plic_IRQHandler(void);
+uint8_t mac0_queue1_plic_IRQHandler(void);
+uint8_t mac0_queue2_plic_IRQHandler(void);
+uint8_t mac0_queue3_plic_IRQHandler(void);
+uint8_t mac0_emac_plic_IRQHandler(void);
+uint8_t mac0_mmsl_plic_IRQHandler(void);
+uint8_t mac1_int_plic_IRQHandler(void);
+uint8_t mac1_queue1_plic_IRQHandler(void);
+uint8_t mac1_queue2_plic_IRQHandler(void);
+uint8_t mac1_queue3_plic_IRQHandler(void);
+uint8_t mac1_emac_plic_IRQHandler(void);
+uint8_t mac1_mmsl_plic_IRQHandler(void);
+uint8_t ddrc_train_plic_IRQHandler(void);
+uint8_t scb_interrupt_plic_IRQHandler(void);
+uint8_t ecc_error_plic_IRQHandler(void);
+uint8_t ecc_correct_plic_IRQHandler(void);
+uint8_t rtc_wakeup_plic_IRQHandler(void);
+uint8_t rtc_match_plic_IRQHandler(void);
+uint8_t timer1_plic_IRQHandler(void);
+uint8_t timer2_plic_IRQHandler(void);
+uint8_t envm_plic_IRQHandler(void);
+uint8_t qspi_plic_IRQHandler(void);
+uint8_t usb_dma_plic_IRQHandler(void);
+uint8_t usb_mc_plic_IRQHandler(void);
+uint8_t mmc_main_plic_IRQHandler(void);
+uint8_t mmc_wakeup_plic_IRQHandler(void);
+uint8_t mmuart0_plic_77_IRQHandler(void);
+uint8_t mmuart1_plic_IRQHandler(void);
+uint8_t mmuart2_plic_IRQHandler(void);
+uint8_t mmuart3_plic_IRQHandler(void);
+uint8_t mmuart4_plic_IRQHandler(void);
+uint8_t g5c_devrst_plic_IRQHandler(void);
+uint8_t g5c_message_plic_IRQHandler(void);
+uint8_t usoc_vc_interrupt_plic_IRQHandler(void);
+uint8_t usoc_smb_interrupt_plic_IRQHandler(void);
+uint8_t e51_0_Maintence_plic_IRQHandler(void);
+
+uint8_t wdog0_mvrp_plic_IRQHandler(void);
+uint8_t wdog1_mvrp_plic_IRQHandler(void);
+uint8_t wdog2_mvrp_plic_IRQHandler(void);
+uint8_t wdog3_mvrp_plic_IRQHandler(void);
+uint8_t wdog4_mvrp_plic_IRQHandler(void);
+uint8_t wdog0_tout_plic_IRQHandler(void);
+uint8_t wdog1_tout_plic_IRQHandler(void);
+uint8_t wdog2_tout_plic_IRQHandler(void);
+uint8_t wdog3_tout_plic_IRQHandler(void);
+uint8_t wdog4_tout_plic_IRQHandler(void);
+uint8_t g5c_mss_spi_plic_IRQHandler(void);
+uint8_t volt_temp_alarm_plic_IRQHandler(void);
+
+uint8_t athena_complete_plic_IRQHandler(void);
+uint8_t athena_alarm_plic_IRQHandler(void);
+uint8_t athena_bus_error_plic_IRQHandler(void);
+uint8_t usoc_axic_us_plic_IRQHandler(void);
+uint8_t usoc_axic_ds_plic_IRQHandler(void);
+
+uint8_t reserved_104_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_0_plic_IRQHandler(void);
+uint8_t fabric_f2h_1_plic_IRQHandler(void);
+uint8_t fabric_f2h_2_plic_IRQHandler(void);
+uint8_t fabric_f2h_3_plic_IRQHandler(void);
+uint8_t fabric_f2h_4_plic_IRQHandler(void);
+uint8_t fabric_f2h_5_plic_IRQHandler(void);
+uint8_t fabric_f2h_6_plic_IRQHandler(void);
+uint8_t fabric_f2h_7_plic_IRQHandler(void);
+uint8_t fabric_f2h_8_plic_IRQHandler(void);
+uint8_t fabric_f2h_9_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_10_plic_IRQHandler(void);
+uint8_t fabric_f2h_11_plic_IRQHandler(void);
+uint8_t fabric_f2h_12_plic_IRQHandler(void);
+uint8_t fabric_f2h_13_plic_IRQHandler(void);
+uint8_t fabric_f2h_14_plic_IRQHandler(void);
+uint8_t fabric_f2h_15_plic_IRQHandler(void);
+uint8_t fabric_f2h_16_plic_IRQHandler(void);
+uint8_t fabric_f2h_17_plic_IRQHandler(void);
+uint8_t fabric_f2h_18_plic_IRQHandler(void);
+uint8_t fabric_f2h_19_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_20_plic_IRQHandler(void);
+uint8_t fabric_f2h_21_plic_IRQHandler(void);
+uint8_t fabric_f2h_22_plic_IRQHandler(void);
+uint8_t fabric_f2h_23_plic_IRQHandler(void);
+uint8_t fabric_f2h_24_plic_IRQHandler(void);
+uint8_t fabric_f2h_25_plic_IRQHandler(void);
+uint8_t fabric_f2h_26_plic_IRQHandler(void);
+uint8_t fabric_f2h_27_plic_IRQHandler(void);
+uint8_t fabric_f2h_28_plic_IRQHandler(void);
+uint8_t fabric_f2h_29_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_30_plic_IRQHandler(void);
+uint8_t fabric_f2h_31_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_32_plic_IRQHandler(void);
+uint8_t fabric_f2h_33_plic_IRQHandler(void);
+uint8_t fabric_f2h_34_plic_IRQHandler(void);
+uint8_t fabric_f2h_35_plic_IRQHandler(void);
+uint8_t fabric_f2h_36_plic_IRQHandler(void);
+uint8_t fabric_f2h_37_plic_IRQHandler(void);
+uint8_t fabric_f2h_38_plic_IRQHandler(void);
+uint8_t fabric_f2h_39_plic_IRQHandler(void);
+uint8_t fabric_f2h_40_plic_IRQHandler(void);
+uint8_t fabric_f2h_41_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_42_plic_IRQHandler(void);
+uint8_t fabric_f2h_43_plic_IRQHandler(void);
+uint8_t fabric_f2h_44_plic_IRQHandler(void);
+uint8_t fabric_f2h_45_plic_IRQHandler(void);
+uint8_t fabric_f2h_46_plic_IRQHandler(void);
+uint8_t fabric_f2h_47_plic_IRQHandler(void);
+uint8_t fabric_f2h_48_plic_IRQHandler(void);
+uint8_t fabric_f2h_49_plic_IRQHandler(void);
+uint8_t fabric_f2h_50_plic_IRQHandler(void);
+uint8_t fabric_f2h_51_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_52_plic_IRQHandler(void);
+uint8_t fabric_f2h_53_plic_IRQHandler(void);
+uint8_t fabric_f2h_54_plic_IRQHandler(void);
+uint8_t fabric_f2h_55_plic_IRQHandler(void);
+uint8_t fabric_f2h_56_plic_IRQHandler(void);
+uint8_t fabric_f2h_57_plic_IRQHandler(void);
+uint8_t fabric_f2h_58_plic_IRQHandler(void);
+uint8_t fabric_f2h_59_plic_IRQHandler(void);
+uint8_t fabric_f2h_60_plic_IRQHandler(void);
+uint8_t fabric_f2h_61_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_62_plic_IRQHandler(void);
+uint8_t fabric_f2h_63_plic_IRQHandler(void);
+
+uint8_t bus_error_unit_hart_0_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_1_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_2_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_3_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_4_plic_IRQHandler(void);
+
+
+#else
+uint8_t Invalid_IRQHandler(void);
+uint8_t External_1_IRQHandler(void);
+uint8_t External_2_IRQHandler(void);
+uint8_t External_3_IRQHandler(void);
+uint8_t USART0_plic_4_IRQHandler(void);
+uint8_t External_5_IRQHandler(void);
+uint8_t External_6_IRQHandler(void);
+uint8_t External_7_IRQHandler(void);
+uint8_t External_8_IRQHandler(void);
+uint8_t External_9_IRQHandler(void);
+uint8_t External_10_IRQHandler(void);
+uint8_t External_11_IRQHandler(void);
+uint8_t External_12_IRQHandler(void);
+uint8_t External_13_IRQHandler(void);
+uint8_t External_14_IRQHandler(void);
+uint8_t External_15_IRQHandler(void);
+uint8_t External_16_IRQHandler(void);
+uint8_t External_17_IRQHandler(void);
+uint8_t External_18_IRQHandler(void);
+uint8_t External_19_IRQHandler(void);
+uint8_t External_20_IRQHandler(void);
+uint8_t External_21_IRQHandler(void);
+uint8_t External_22_IRQHandler(void);
+uint8_t dma_ch0_DONE_IRQHandler(void);
+uint8_t dma_ch0_ERR_IRQHandler(void);
+uint8_t dma_ch1_DONE_IRQHandler(void);
+uint8_t dma_ch1_ERR_IRQHandler(void);
+uint8_t dma_ch2_DONE_IRQHandler(void);
+uint8_t dma_ch2_ERR_IRQHandler(void);
+uint8_t dma_ch3_DONE_IRQHandler(void);
+uint8_t dma_ch3_ERR_IRQHandler(void);
+uint8_t External_31_IRQHandler(void);
+uint8_t External_32_IRQHandler(void);
+uint8_t External_33_IRQHandler(void);
+uint8_t External_34_IRQHandler(void);
+uint8_t External_35_IRQHandler(void);
+uint8_t External_36_IRQHandler(void);
+uint8_t External_37_IRQHandler(void);
+uint8_t External_38_IRQHandler(void);
+uint8_t External_39_IRQHandler(void);
+uint8_t External_40_IRQHandler(void);
+uint8_t External_41_IRQHandler(void);
+uint8_t External_42_IRQHandler(void);
+uint8_t External_43_IRQHandler(void);
+uint8_t External_44_IRQHandler(void);
+uint8_t External_45_IRQHandler(void);
+uint8_t External_46_IRQHandler(void);
+uint8_t External_47_IRQHandler(void);
+uint8_t External_48_IRQHandler(void);
+uint8_t External_49_IRQHandler(void);
+uint8_t External_50_IRQHandler(void);
+uint8_t External_51_IRQHandler(void);
+uint8_t External_52_IRQHandler(void);
+uint8_t MAC0_plic_53_IRQHandler(void);
+
+#endif
+
+/***************************************************************************//**
+ * PLIC source Interrupt numbers:
+ */
+/* See section on PLIC Interrupt Sources in User Guide */
+#define OFFSET_TO_MSS_GLOBAL_INTS 13U
+typedef enum
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ INVALID_IRQn = 0,
+ L2_METADATA_CORR_IRQn = 1,
+ L2_METADAT_UNCORR_IRQn = 2,
+ L2_DATA_CORR_IRQn = 3,
+ L2_DATA_UNCORR_IRQn = 4,
+ DMA_CH0_DONE_IRQn = 5,
+ DMA_CH0_ERR_IRQn = 6,
+ DMA_CH1_DONE_IRQn = 7,
+ DMA_CH1_ERR_IRQn = 8,
+ DMA_CH2_DONE_IRQn = 9,
+ DMA_CH2_ERR_IRQn = 10,
+ DMA_CH3_DONE_IRQn = 11,
+ DMA_CH3_ERR_IRQn = 12,
+ /* see GPIO Interrupt Multiplexing in the User Guide */
+ GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0 = 0 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1 = 1 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2 = 2 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3 = 3 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4 = 4 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5 = 5 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6 = 6 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7 = 7 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8 = 8 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9 = 9 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10 = 10 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11 = 11 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12 = 12 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO0_BIT13_or_GPIO2_BIT13_PLIC_13 = 13 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14 = 14 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15 = 15 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16 = 16 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17 = 17 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18 = 18 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19 = 19 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT6_or_GPIO2_BIT20_PLIC_20 = 20 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT7_or_GPIO2_BIT21_PLIC_21 = 21 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT8_or_GPIO2_BIT22_PLIC_22 = 22 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT9_or_GPIO2_BIT23_PLIC_23 = 23 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT10_or_GPIO2_BIT24_PLIC_24 = 24 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT11_or_GPIO2_BIT25_PLIC_25 = 25 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT12_or_GPIO2_BIT26_PLIC_26 = 26 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT13_or_GPIO2_BIT27_PLIC_27 = 27 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO1_BIT14_or_GPIO2_BIT28_PLIC_28 = 28 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT15_or_GPIO2_BIT29_PLIC_29 = 29 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT16_or_GPIO2_BIT30_PLIC_30 = 30 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT17_or_GPIO2_BIT31_PLIC_31 = 31 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO1_BIT18_PLIC_32 = 32 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT19_PLIC_33 = 33 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT20_PLIC_34 = 34 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT21_PLIC_35 = 35 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT22_PLIC_36 = 36 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT23_PLIC_37 = 37 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO0_NON_DIRECT_PLIC = 38 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_NON_DIRECT_PLIC = 39 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO2_NON_DIRECT_PLIC = 40 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ SPI0_PLIC = 41 + OFFSET_TO_MSS_GLOBAL_INTS,
+ SPI1_PLIC = 42 + OFFSET_TO_MSS_GLOBAL_INTS,
+ CAN0_PLIC = 43 + OFFSET_TO_MSS_GLOBAL_INTS,
+ CAN1_PLIC = 44 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_MAIN_PLIC = 45 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_ALERT_PLIC = 46 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_SUS_PLIC = 47 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_MAIN_PLIC = 48 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_ALERT_PLIC = 49 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_SUS_PLIC = 50 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_INT_PLIC = 51 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE1_PLIC = 52 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE2_PLIC = 53 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE3_PLIC = 54 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_EMAC_PLIC = 55 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_MMSL_PLIC = 56 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_INT_PLIC = 57 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE1_PLIC = 58 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE2_PLIC = 59 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE3_PLIC = 60 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_EMAC_PLIC = 61 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_MMSL_PLIC = 62 + OFFSET_TO_MSS_GLOBAL_INTS,
+ DDRC_TRAIN_PLIC = 63 + OFFSET_TO_MSS_GLOBAL_INTS,
+ SCB_INTERRUPT_PLIC = 64 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ECC_ERROR_PLIC = 65 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ECC_CORRECT_PLIC = 66 + OFFSET_TO_MSS_GLOBAL_INTS,
+ RTC_WAKEUP_PLIC = 67 + OFFSET_TO_MSS_GLOBAL_INTS,
+ RTC_MATCH_PLIC = 68 + OFFSET_TO_MSS_GLOBAL_INTS,
+ TIMER1_PLIC = 69 + OFFSET_TO_MSS_GLOBAL_INTS,
+ TIMER2_PLIC = 70 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ENVM_PLIC = 71 + OFFSET_TO_MSS_GLOBAL_INTS,
+ QSPI_PLIC = 72 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USB_DMA_PLIC = 73 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USB_MC_PLIC = 74 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMC_main_PLIC = 75 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMC_wakeup_PLIC = 76 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART0_PLIC_77 = 77 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART1_PLIC = 78 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART2_PLIC = 79 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART3_PLIC = 80 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART4_PLIC = 81 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ G5C_DEVRST_PLIC = 82 + OFFSET_TO_MSS_GLOBAL_INTS,
+ g5c_MESSAGE_PLIC = 83 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_VC_INTERRUPT_PLIC = 84 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_SMB_INTERRUPT_PLIC = 85 + OFFSET_TO_MSS_GLOBAL_INTS,
+ /* contains multiple interrupts- */
+ E51_0_MAINTENACE_PLIC = 86 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ WDOG0_MRVP_PLIC = 87 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG1_MRVP_PLIC = 88 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG2_MRVP_PLIC = 89 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG3_MRVP_PLIC = 90 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG4_MRVP_PLIC = 91 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG0_TOUT_PLIC = 92 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG1_TOUT_PLIC = 93 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG2_TOUT_PLIC = 94 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG3_TOUT_PLIC = 95 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG4_TOUT_PLIC = 96 + OFFSET_TO_MSS_GLOBAL_INTS,
+ G5C_MSS_SPI_PLIC = 97 + OFFSET_TO_MSS_GLOBAL_INTS,
+ VOLT_TEMP_ALARM_PLIC = 98 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_COMPLETE_PLIC = 99 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_ALARM_PLIC = 100 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_BUS_ERROR_PLIC = 101 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_AXIC_US_PLIC = 102 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_AXIC_DS_PLIC = 103 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_0_PLIC = 105 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_1_PLIC = 106 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_2_PLIC = 107 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_3_PLIC = 108 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_4_PLIC = 109 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_5_PLIC = 110 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_6_PLIC = 111 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_7_PLIC = 112 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_8_PLIC = 113 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_9_PLIC = 114 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_10_PLIC = 115 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_11_PLIC = 116 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_12_PLIC = 117 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_13_PLIC = 118 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_14_PLIC = 119 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_15_PLIC = 120 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_16_PLIC = 121 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_17_PLIC = 122 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_18_PLIC = 123 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_19_PLIC = 124 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_20_PLIC = 125 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_21_PLIC = 126 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_22_PLIC = 127 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_23_PLIC = 128 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_24_PLIC = 129 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_25_PLIC = 130 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_26_PLIC = 131 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_27_PLIC = 132 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_28_PLIC = 133 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_29_PLIC = 134 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_30_PLIC = 135 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_31_PLIC = 136 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_32_PLIC = 137 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_33_PLIC = 138 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_34_PLIC = 139 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_35_PLIC = 140 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_36_PLIC = 141 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_37_PLIC = 142 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_38_PLIC = 143 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_39_PLIC = 144 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_40_PLIC = 145 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_41_PLIC = 146 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_42_PLIC = 147 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_43_PLIC = 148 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_44_PLIC = 149 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_45_PLIC = 150 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_46_PLIC = 151 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_47_PLIC = 152 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_48_PLIC = 153 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_49_PLIC = 154 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_50_PLIC = 155 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_51_PLIC = 156 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_52_PLIC = 157 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_53_PLIC = 158 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_54_PLIC = 159 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_55_PLIC = 160 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_56_PLIC = 161 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_57_PLIC = 162 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_58_PLIC = 163 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_59_PLIC = 164 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_60_PLIC = 165 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_61_PLIC = 166 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_62_PLIC = 167 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_63_PLIC = 168 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ BUS_ERROR_UNIT_HART_0 = 182,
+ BUS_ERROR_UNIT_HART_1 = 183,
+ BUS_ERROR_UNIT_HART_2 = 184,
+ BUS_ERROR_UNIT_HART_3 = 185,
+ BUS_ERROR_UNIT_HART_4 = 186
+
+#else
+ INVALID_IRQn = 0,
+ L2Cache_0_PLIC_1 = 1,
+ L2Cache_1_PLIC_2 = 2,
+ L2Cache_2__PLIC_3 = 3,
+ USART0_PLIC_4 = 4,
+ USART1_PLIC_5 = 5,
+ QSPI_12_PLIC_6 = 6,
+
+ gpio_PLIC_7 = 7,
+ gpio_PLIC_8 = 8,
+ gpio_PLIC_9 = 9,
+ gpio_10 = 10,
+ gpio_11 = 11,
+ gpio_12 = 12,
+ gpio_PLIC_13 = 13,
+ gpio_PLIC_14 = 14,
+ gpio_PLIC_15 = 15,
+ gpio_PLIC_16 = 16,
+ gpio_PLIC_17 = 17,
+ gpio_PLIC_18 = 18,
+ gpio_PLIC_19 = 19,
+ gpio_PLIC_20 = 20,
+ gpio_PLIC_21 = 21,
+ gpio_PLIC_22 = 22,
+
+ dma_PLIC_23 = 23,
+ dma_PLIC_24 = 24,
+ dma_PLIC_25 = 25,
+ dma_PLIC_26 = 26,
+ dma_PLIC_27 = 27,
+ dma_PLIC_28 = 28,
+ dma_PLIC_29 = 29,
+ dma_PLIC_30 = 30,
+
+ ddr_subsytem_PLIC_31 = 31,
+
+ chiplink_msi_PLIC_32 = 32,
+ chiplink_msi_PLIC_33 = 33,
+ chiplink_msi_PLIC_34 = 34,
+ chiplink_msi_PLIC_35 = 35,
+ chiplink_msi_PLIC_36 = 36,
+ chiplink_msi_PLIC_37 = 37,
+ chiplink_msi_PLIC_38 = 38,
+ chiplink_msi_PLIC_39 = 39,
+ chiplink_msi_PLIC_40 = 40,
+ chiplink_msi_PLIC_41 = 41,
+
+ pwm0_PLIC_42 = 42,
+ pwm0_PLIC_43 = 43,
+ pwm0_PLIC_44 = 44,
+ pwm0_PLIC_45 = 45,
+
+ pwm1_PLIC_46 = 46,
+ pwm1_PLIC_47 = 47,
+ pwm1_PLIC_48 = 48,
+ pwm1_PLIC_49 = 49,
+
+ i2c_PLIC_50 = 50,
+ QSPI0_PLIC_51 = 51,
+ QSPI1_PLIC_52 = 52,
+ ethernet_PLIC_53 = 53
+
+#endif
+
+} PLIC_IRQn_Type;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define MAX_PLIC_INT BUS_ERROR_UNIT_HART_4
+#else
+#define MAX_PLIC_INT ethernet_PLIC_53
+#endif
+
+/***************************************************************************//**
+ * E51-0 is Maintenance Interrupt, CPU needs to read status register to
+ * determine exact cause:
+ * This structure added here for clarity, need to replay with status register
+ * defines for determining interrupt cause
+ */
+typedef enum
+{
+ mpu_fail_plic =0,
+ lp_state_enter_plic =1,
+ lp_state_exit_plic =2,
+ ff_start_plic =3,
+ ff_end_plic =4,
+ fpga_on_plic =5,
+ fpga_off_plic =6,
+ scb_error_plic =7,
+ scb_fault_plic =8,
+ mesh_fail_plic =9
+} PLIC_IRQ86_Type;
+
+typedef struct
+{
+ volatile uint32_t PRIORITY_THRESHOLD;
+ volatile uint32_t CLAIM_COMPLETE;
+ volatile uint32_t reserved[(0x1000/4)-2];
+} IRQ_Target_Type;
+
+typedef struct
+{
+ volatile uint32_t ENABLES[32U];
+} Target_Enables_Type;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define PLIC_SET_UP_REGISTERS 6U
+#else
+#define PLIC_SET_UP_REGISTERS 2U
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define PLIC_NUM_SOURCES 187U
+#else
+#define PLIC_NUM_SOURCES 54U /* 53 actual, source 0 is not used */
+#endif
+
+#define PLIC_NUM_PRIORITIES 7U
+#define NUM_CLAIM_REGS 9U
+
+
+/* The FU540-C000 has 53 interrupt sources. */
+ typedef struct
+{
+ volatile uint32_t RESERVED0;
+ /*-------------------- Source Priority --------------------*/
+ volatile uint32_t SOURCE_PRIORITY[PLIC_NUM_SOURCES];
+ volatile uint32_t RESERVED1[(0x1000 / 4) - (PLIC_NUM_SOURCES + 1)];
+ /*-------------------- Pending array --------------------*/
+ volatile const uint32_t PENDING_ARRAY[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED2[(0x1000/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart0 Mode Enables--------------------*/
+ volatile uint32_t HART0_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED3[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart1 Mode Enables--------------------*/
+ volatile uint32_t HART1_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED4a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART1_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED4[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart2 Mode Enables--------------------*/
+ volatile uint32_t HART2_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED5a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART2_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED5[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart3 Mode Enables--------------------*/
+ volatile uint32_t HART3_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED6a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART3_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED6[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart4 Mode Enables--------------------*/
+ volatile uint32_t HART4_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED7a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART4_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED7[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ volatile uint32_t RESERVED8[(0x0C200000 - 0x0C002480)/4];
+
+ /*--- Target Priority threshold and claim/complete---------*/
+ IRQ_Target_Type TARGET[NUM_CLAIM_REGS]; /* See PLIC Register Map or
+ TARGET_OFFSET defines below
+ for offset details */
+
+} PLIC_Type;
+
+#define TARGET_OFFSET_HART0_M 0U
+#define TARGET_OFFSET_HART1_M 1U
+#define TARGET_OFFSET_HART1_S 2U
+#define TARGET_OFFSET_HART2_M 3U
+#define TARGET_OFFSET_HART2_S 4U
+#define TARGET_OFFSET_HART3_M 5U
+#define TARGET_OFFSET_HART3_S 6U
+#define TARGET_OFFSET_HART4_M 7U
+#define TARGET_OFFSET_HART4_S 8U
+
+extern const unsigned long plic_hart_lookup[5U];
+
+/***************************************************************************//**
+ * PLIC: Platform Level Interrupt Controller
+ */
+#define PLIC_BASE_ADDR 0x0C000000UL
+
+#define PLIC ((PLIC_Type * const)PLIC_BASE_ADDR)
+
+/*-------------------------------------------------------------------------*//**
+ * The function PLIC_init() initializes the PLIC controller and enables the
+ * global external interrupt bit.
+ */
+
+/*-----------------Hart Mode Enables--------------------*/
+
+static inline void PLIC_init(void)
+{
+ uint32_t inc;
+ uint64_t hart_id = read_csr(mhartid);
+
+ /* Disable all interrupts for the current hart. */
+ switch(hart_id)
+ {
+ case 0:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART0_MMODE_ENA[inc] = 0U;
+ }
+
+ /* Set the threshold to zero.
+ * PLIC provides context based threshold register for the settings of a
+ * interrupt priority threshold of each context. The threshold register
+ * is a WARL field. The PLIC will mask all PLIC interrupts of a priority
+ * less than or equal to threshold. For example, a threshold value of zero
+ * permits all interrupts with non-zero priority.*/
+
+ PLIC->TARGET[TARGET_OFFSET_HART0_M].PRIORITY_THRESHOLD = 0U;
+ break;
+ case 1:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART1_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART1_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART1_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 2:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART2_MMODE_ENA[inc] = 0U;
+ PLIC->HART2_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART2_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART2_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 3:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART3_MMODE_ENA[inc] = 0U;
+ PLIC->HART3_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART3_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART3_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 4:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART4_MMODE_ENA[inc] = 0U;
+ PLIC->HART4_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART4_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART4_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ default:
+ break;
+ }
+
+ /* Enable machine external interrupts. */
+ set_csr(mie, MIP_MEIP);
+}
+
+
+
+/***************************************************************************//**
+ * The function PLIC_EnableIRQ() enables the external interrupt for the
+ * interrupt number indicated by the parameter IRQn.
+ */
+static inline void PLIC_EnableIRQ(PLIC_IRQn_Type IRQn)
+{
+ uint32_t current;
+ uint64_t hart_id = read_csr(mhartid);
+
+ switch(hart_id)
+ {
+ case 0:
+ current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 1:
+ current = PLIC->HART1_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART1_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 2:
+ current = PLIC->HART2_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART2_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 3:
+ current = PLIC->HART3_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART3_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 4:
+ current = PLIC->HART4_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART4_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ default:
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_DisableIRQ() disables the external interrupt for the
+ * interrupt number indicated by the parameter IRQn.
+
+ * NOTE:
+ * This function can be used to disable the external interrupt from outside
+ * external interrupt handler function.
+ * This function MUST NOT be used from within the External Interrupt
+ * handler.
+ * If you wish to disable the external interrupt while the interrupt handler
+ * for that external interrupt is executing then you must use the return
+ * value EXT_IRQ_DISABLE to return from the extern interrupt handler.
+ */
+static inline void PLIC_DisableIRQ(PLIC_IRQn_Type IRQn)
+{
+ uint32_t current;
+ uint64_t hart_id = read_csr(mhartid);
+
+ switch(hart_id)
+ {
+ case 0:
+ current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 1:
+ current = PLIC->HART1_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART1_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 2:
+ current = PLIC->HART2_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART2_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 3:
+ current = PLIC->HART3_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART3_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 4:
+ current = PLIC->HART4_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART4_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ default:
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_SetPriority() sets the priority for the external interrupt
+ * for the interrupt number indicated by the parameter IRQn.
+ */
+static inline void PLIC_SetPriority(PLIC_IRQn_Type IRQn, uint32_t priority)
+{
+ if((IRQn > INVALID_IRQn) && (IRQn < PLIC_NUM_SOURCES))
+ {
+ PLIC->SOURCE_PRIORITY[IRQn-1] = priority;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_GetPriority() returns the priority for the external
+ * interrupt for the interrupt number indicated by the parameter IRQn.
+ */
+static inline uint32_t PLIC_GetPriority(PLIC_IRQn_Type IRQn)
+{
+ uint32_t ret_val = 0U;
+
+ if((IRQn > INVALID_IRQn) && (IRQn < PLIC_NUM_SOURCES))
+ {
+ ret_val = PLIC->SOURCE_PRIORITY[IRQn-1];
+ }
+
+ return(ret_val);
+}
+
+
+static inline uint32_t PLIC_pending(PLIC_IRQn_Type IRQn)
+{
+ return (PLIC->PENDING_ARRAY[IRQn/32U] & (0x01U<<(IRQn%32U)));
+}
+
+/***************************************************************************//**
+ * The function PLIC_ClaimIRQ() claims the interrupt from the PLIC controller.
+ */
+static inline uint32_t PLIC_ClaimIRQ(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ return (PLIC->TARGET[plic_hart_lookup[hart_id]].CLAIM_COMPLETE);
+}
+
+/***************************************************************************//**
+ * The function PLIC_CompleteIRQ() indicates to the PLIC controller the
+ * interrupt is processed and claim is complete.
+ */
+static inline void PLIC_CompleteIRQ(uint32_t source)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ ASSERT(source <= MAX_PLIC_INT);
+
+ PLIC->TARGET[plic_hart_lookup[hart_id]].CLAIM_COMPLETE = source;
+}
+
+/***************************************************************************//**
+ *
+ * The function PLIC_SetPriority_Threshold() sets the threshold for a particular
+ * hart. The default threshold on reset is 0.
+ * The PFSoC Core Complex supports setting of an interrupt priority threshold
+ * via the threshold register. The threshold is a WARL field, where the PFSoC
+ * Core Complex supports a maximum threshold of 7.
+ * The PFSoC Core Complex will mask all PLIC interrupts of a priority less than
+ * or equal to threshold. For example, a threshold value of zero permits all
+ * interrupts with non-zero priority, whereas a value of 7 masks all
+ * interrupts.
+ */
+static inline void PLIC_SetPriority_Threshold(uint32_t threshold)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ ASSERT(threshold <= 7);
+
+ PLIC->TARGET[plic_hart_lookup[hart_id]].PRIORITY_THRESHOLD = threshold;
+}
+
+/***************************************************************************//**
+ * PLIC_ClearPendingIRQ(void)
+ * This is only called by the startup hart and only once
+ * Clears any pending interrupts as PLIC can be in unknown state on startup
+ */
+static inline void PLIC_ClearPendingIRQ(void)
+{
+ volatile uint32_t int_num = PLIC_ClaimIRQ();
+ volatile int32_t wait_possible_int;
+
+ while ( int_num != INVALID_IRQn)
+ {
+ PLIC_CompleteIRQ(int_num);
+ wait_possible_int = 0xFU;
+ while (wait_possible_int)
+ {
+ wait_possible_int--;
+ }
+ int_num = PLIC_ClaimIRQ(); /* obtain interrupt, auto clears */
+ }
+}
+
+/***************************************************************************//**
+ * This function is only called from one hart on startup
+ */
+static inline void PLIC_init_on_reset(void)
+{
+ uint32_t inc;
+
+ /* default all priorities so effectively disabled */
+ for(inc = 0U; inc < PLIC_NUM_SOURCES; ++inc)
+ {
+ /* priority must be greater than threshold to be enabled, so setting to
+ * 7 disables */
+ PLIC->SOURCE_PRIORITY[inc] = 0U;
+ }
+
+ for(inc = 0U; inc < NUM_CLAIM_REGS; ++inc)
+ {
+ PLIC->TARGET[inc].PRIORITY_THRESHOLD = 7U;
+ }
+
+ /* and clear all the enables */
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART0_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_SMODE_ENA[inc] = 0U;
+ PLIC->HART2_MMODE_ENA[inc] = 0U;
+ PLIC->HART2_SMODE_ENA[inc] = 0U;
+ PLIC->HART3_MMODE_ENA[inc] = 0U;
+ PLIC->HART3_SMODE_ENA[inc] = 0U;
+ PLIC->HART4_MMODE_ENA[inc] = 0U;
+ PLIC->HART4_SMODE_ENA[inc] = 0U;
+ }
+
+ /* clear any pending interrupts- in case already there */
+ PLIC_ClearPendingIRQ();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_PLIC_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_pmp.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_pmp.c
new file mode 100644
index 00000000..2e21f5bb
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_pmp.c
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_pmp.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PMP configuration using MSS configurator values.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+/**
+ * \brief PMP configuration from Libero
+ *
+ */
+const uint64_t pmp_values[][18] = {
+ /* hart 0 */
+ {LIBERO_SETTING_HART0_CSR_PMPCFG0,
+ LIBERO_SETTING_HART0_CSR_PMPCFG2,
+ LIBERO_SETTING_HART0_CSR_PMPADDR0,
+ LIBERO_SETTING_HART0_CSR_PMPADDR1,
+ LIBERO_SETTING_HART0_CSR_PMPADDR2,
+ LIBERO_SETTING_HART0_CSR_PMPADDR3,
+ LIBERO_SETTING_HART0_CSR_PMPADDR4,
+ LIBERO_SETTING_HART0_CSR_PMPADDR5,
+ LIBERO_SETTING_HART0_CSR_PMPADDR6,
+ LIBERO_SETTING_HART0_CSR_PMPADDR7,
+ LIBERO_SETTING_HART0_CSR_PMPADDR8,
+ LIBERO_SETTING_HART0_CSR_PMPADDR9,
+ LIBERO_SETTING_HART0_CSR_PMPADDR10,
+ LIBERO_SETTING_HART0_CSR_PMPADDR11,
+ LIBERO_SETTING_HART0_CSR_PMPADDR12,
+ LIBERO_SETTING_HART0_CSR_PMPADDR13,
+ LIBERO_SETTING_HART0_CSR_PMPADDR14,
+ LIBERO_SETTING_HART0_CSR_PMPADDR15},
+ /* hart 1 */
+ {LIBERO_SETTING_HART1_CSR_PMPCFG0,
+ LIBERO_SETTING_HART1_CSR_PMPCFG2,
+ LIBERO_SETTING_HART1_CSR_PMPADDR0,
+ LIBERO_SETTING_HART1_CSR_PMPADDR1,
+ LIBERO_SETTING_HART1_CSR_PMPADDR2,
+ LIBERO_SETTING_HART1_CSR_PMPADDR3,
+ LIBERO_SETTING_HART1_CSR_PMPADDR4,
+ LIBERO_SETTING_HART1_CSR_PMPADDR5,
+ LIBERO_SETTING_HART1_CSR_PMPADDR6,
+ LIBERO_SETTING_HART1_CSR_PMPADDR7,
+ LIBERO_SETTING_HART1_CSR_PMPADDR8,
+ LIBERO_SETTING_HART1_CSR_PMPADDR9,
+ LIBERO_SETTING_HART1_CSR_PMPADDR10,
+ LIBERO_SETTING_HART1_CSR_PMPADDR11,
+ LIBERO_SETTING_HART1_CSR_PMPADDR12,
+ LIBERO_SETTING_HART1_CSR_PMPADDR13,
+ LIBERO_SETTING_HART1_CSR_PMPADDR14,
+ LIBERO_SETTING_HART1_CSR_PMPADDR15},
+ /* hart 2 */
+ {LIBERO_SETTING_HART2_CSR_PMPCFG0,
+ LIBERO_SETTING_HART2_CSR_PMPCFG2,
+ LIBERO_SETTING_HART2_CSR_PMPADDR0,
+ LIBERO_SETTING_HART2_CSR_PMPADDR1,
+ LIBERO_SETTING_HART2_CSR_PMPADDR2,
+ LIBERO_SETTING_HART2_CSR_PMPADDR3,
+ LIBERO_SETTING_HART2_CSR_PMPADDR4,
+ LIBERO_SETTING_HART2_CSR_PMPADDR5,
+ LIBERO_SETTING_HART2_CSR_PMPADDR6,
+ LIBERO_SETTING_HART2_CSR_PMPADDR7,
+ LIBERO_SETTING_HART2_CSR_PMPADDR8,
+ LIBERO_SETTING_HART2_CSR_PMPADDR9,
+ LIBERO_SETTING_HART2_CSR_PMPADDR10,
+ LIBERO_SETTING_HART2_CSR_PMPADDR11,
+ LIBERO_SETTING_HART2_CSR_PMPADDR12,
+ LIBERO_SETTING_HART2_CSR_PMPADDR13,
+ LIBERO_SETTING_HART2_CSR_PMPADDR14,
+ LIBERO_SETTING_HART2_CSR_PMPADDR15},
+ /* hart 3 */
+ {LIBERO_SETTING_HART3_CSR_PMPCFG0,
+ LIBERO_SETTING_HART3_CSR_PMPCFG2,
+ LIBERO_SETTING_HART3_CSR_PMPADDR0,
+ LIBERO_SETTING_HART3_CSR_PMPADDR1,
+ LIBERO_SETTING_HART3_CSR_PMPADDR2,
+ LIBERO_SETTING_HART3_CSR_PMPADDR3,
+ LIBERO_SETTING_HART3_CSR_PMPADDR4,
+ LIBERO_SETTING_HART3_CSR_PMPADDR5,
+ LIBERO_SETTING_HART3_CSR_PMPADDR6,
+ LIBERO_SETTING_HART3_CSR_PMPADDR7,
+ LIBERO_SETTING_HART3_CSR_PMPADDR8,
+ LIBERO_SETTING_HART3_CSR_PMPADDR9,
+ LIBERO_SETTING_HART3_CSR_PMPADDR10,
+ LIBERO_SETTING_HART3_CSR_PMPADDR11,
+ LIBERO_SETTING_HART3_CSR_PMPADDR12,
+ LIBERO_SETTING_HART3_CSR_PMPADDR13,
+ LIBERO_SETTING_HART3_CSR_PMPADDR14,
+ LIBERO_SETTING_HART3_CSR_PMPADDR15},
+ /* hart 4 */
+ {LIBERO_SETTING_HART4_CSR_PMPCFG0,
+ LIBERO_SETTING_HART4_CSR_PMPCFG2,
+ LIBERO_SETTING_HART4_CSR_PMPADDR0,
+ LIBERO_SETTING_HART4_CSR_PMPADDR1,
+ LIBERO_SETTING_HART4_CSR_PMPADDR2,
+ LIBERO_SETTING_HART4_CSR_PMPADDR3,
+ LIBERO_SETTING_HART4_CSR_PMPADDR4,
+ LIBERO_SETTING_HART4_CSR_PMPADDR5,
+ LIBERO_SETTING_HART4_CSR_PMPADDR6,
+ LIBERO_SETTING_HART4_CSR_PMPADDR7,
+ LIBERO_SETTING_HART4_CSR_PMPADDR8,
+ LIBERO_SETTING_HART4_CSR_PMPADDR9,
+ LIBERO_SETTING_HART4_CSR_PMPADDR10,
+ LIBERO_SETTING_HART4_CSR_PMPADDR11,
+ LIBERO_SETTING_HART4_CSR_PMPADDR12,
+ LIBERO_SETTING_HART4_CSR_PMPADDR13,
+ LIBERO_SETTING_HART4_CSR_PMPADDR14,
+ LIBERO_SETTING_HART4_CSR_PMPADDR15},
+};
+
+/**
+ * pmp_configure()
+ * Set PMP's up with configuration from Libero
+ * @param hart_id hart Id
+ * @return
+ */
+uint8_t pmp_configure(uint8_t hart_id) /* set-up with settings from Libero */
+{
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ uint64_t pmp0cfg;
+#endif
+ /* make sure enables are off */
+ write_csr(pmpcfg0, 0);
+ write_csr(pmpcfg2, 0);
+ /* set required addressing */
+ write_csr(pmpaddr0, pmp_values[hart_id][2]);
+ write_csr(pmpaddr1, pmp_values[hart_id][3]);
+ write_csr(pmpaddr2, pmp_values[hart_id][4]);
+ write_csr(pmpaddr3, pmp_values[hart_id][5]);
+ write_csr(pmpaddr4, pmp_values[hart_id][6]);
+ write_csr(pmpaddr5, pmp_values[hart_id][7]);
+ write_csr(pmpaddr6, pmp_values[hart_id][8]);
+ write_csr(pmpaddr7, pmp_values[hart_id][9]);
+ write_csr(pmpaddr8, pmp_values[hart_id][10]);
+ write_csr(pmpaddr9, pmp_values[hart_id][11]);
+ write_csr(pmpaddr10, pmp_values[hart_id][12]);
+ write_csr(pmpaddr11, pmp_values[hart_id][13]);
+ write_csr(pmpaddr12, pmp_values[hart_id][14]);
+ write_csr(pmpaddr13, pmp_values[hart_id][15]);
+ write_csr(pmpaddr14, pmp_values[hart_id][16]);
+ write_csr(pmpaddr15, pmp_values[hart_id][17]);
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ pmp0cfg = pmp_values[hart_id][0];
+ pmp_master_configs(hart_id, &pmp0cfg);
+ write_csr(pmpcfg0, pmp0cfg);
+ write_csr(pmpcfg2, pmp_values[hart_id][1]);
+#endif
+
+ return(0);
+}
+
+/*-------------------------------------------------------------------------*//**
+ Please note the first four PMP's are set to zero by MSS Configurator v2021.1
+ These will need to be set by the HSS. The first three relate to HSS footprint
+ The PMP4 is used to open a hole for debug region.
+
+ | PMP | cfg | L | XWR | Detail |
+ |-----|-----------|-----|----------------------------------------------------|
+ | 0 | 0x18 | N | | 256KB | Closes access for s and U mode |
+ | 1 | 0x98 | Y | X R | 256KB | Opens up area for m-mode only |
+ | 2 | 0x98 | Y | XRW | 64KB | OpenSBI scratch per scratch |
+ | 3 | 0x98 | Y | XRW | 4KB | Open window for debug |
+ | .. | .. | .. | .. | .. | .. |
+ | 15 | 0x18 | Y | | - | Close everything not opened |
+
+ @param pmp0cfg return with config for first four PMP's
+
+ */
+__attribute__((weak)) void pmp_master_configs(uint8_t hart_id, uint64_t * pmp0cfg)
+{
+ if ( hart_id == 0U )
+ {
+ *pmp0cfg = LIBERO_SETTING_HART0_CSR_PMPCFG0;
+ write_csr(pmpaddr0, pmp_values[hart_id][2]);
+ write_csr(pmpaddr1, pmp_values[hart_id][3]);
+ write_csr(pmpaddr2, pmp_values[hart_id][4]);
+ write_csr(pmpaddr3, pmp_values[hart_id][5]);
+ }
+ else
+ {
+ /*
+ * Example of closed memory map, must be created based on HSS footprint
+ */
+#define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG0 0x2007FFFULL /* 256K LIM */
+#define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG1 0x200FFFFULL /* 512K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_LIM_EG0 0x2007FFFULL /* 256K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_LIM_EG1 0x200FFFFULL /* 512K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG 0x280FFFFULL /* 512K SCRATCHPAD */
+#define OPEN_CONTEXT_ACCESS_LIM_PMP2_H1 0x2011FFFULL /* 64K LIM */
+#define OPEN_CONTEXT_ACCESS_LIM_PMP2_H2 0x2015FFFULL /* 64K LIM */
+#define OPEN_DEBUG_ACCESS_PMP3 0x1FFULL
+#define HSS_CLOSED_CFG_MASK ~0xFFFFFFFFULL
+#define HSS_CLOSED_CFG 0x9F9F9D18ULL
+ /*
+ * We will open 512K LIM and scratchpad in weak pmp_master_configs()
+ * for all harts.
+ */
+#define LIM_512K_FROM_BASE 0x200FFFFULL /* 512K LIM */
+#define SCRATCH_512K_FROM_BASE 0x280FFFFULL /* 512K LIM */
+ *pmp0cfg &= HSS_CLOSED_CFG_MASK;
+ *pmp0cfg |= 0x9F009F9FULL; /* open 0,1 and 3 to allow open access */
+ write_csr(pmpaddr0, OPEN_M_ACCESS_HSS_PMP1_LIM_EG1);
+ write_csr(pmpaddr1, OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG);
+ write_csr(pmpaddr2, 0ULL);
+ write_csr(pmpaddr3, OPEN_DEBUG_ACCESS_PMP3);
+ }
+
+ /*
+ *
+ */
+#define LOCAL_PMP_SETTINGS
+#ifdef LOCAL_PMP_SETTINGS
+
+#endif
+ return;
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_pmp.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_pmp.h
new file mode 100644
index 00000000..d4319a04
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_pmp.h
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_pmp.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PMP configuration using MSS configurator values.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_PMP_H
+#define MSS_PMP_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MEM_CONFIGS_ENABLED)
+#define LIBERO_SETTING_MEM_CONFIGS_ENABLED 0ULL
+/* Enabled when bit set to 1 */
+/* PMP [0:0] RW value= 0x0 */
+/* MPU [1:0] RW value= 0x0 */
+#endif
+#define PMP_ENABLED_MASK 1UL
+#define MPU_ENABLED_MASK 2UL
+
+/*
+ * Bit offsets associated with LIBERO_SETTING_CONTEXT_A_HART_EN and
+ * LIBERO_SETTING_CONTEXT_B_HART_EN
+ */
+#define CONTEXT_EN_MASK_MMUART0 (1U<<0)
+#define CONTEXT_EN_MASK_MMUART1 (1U<<1)
+#define CONTEXT_EN_MASK_MMUART2 (1U<<2)
+#define CONTEXT_EN_MASK_MMUART3 (1U<<3)
+#define CONTEXT_EN_MASK_MMUART4 (1U<<4)
+#define CONTEXT_EN_MASK_WDOG0 (1U<<5)
+#define CONTEXT_EN_MASK_WDOG1 (1U<<6)
+#define CONTEXT_EN_MASK_WDOG2 (1U<<7)
+#define CONTEXT_EN_MASK_WDOG3 (1U<<8)
+#define CONTEXT_EN_MASK_WDOG4 (1U<<9)
+#define CONTEXT_EN_MASK_SPI0 (1U<<10)
+#define CONTEXT_EN_MASK_SPI1 (1U<<11)
+#define CONTEXT_EN_MASK_I2C0 (1U<<12)
+#define CONTEXT_EN_MASK_I2C1 (1U<<13)
+#define CONTEXT_EN_MASK_CAN0 (1U<<14)
+#define CONTEXT_EN_MASK_CAN1 (1U<<15)
+#define CONTEXT_EN_MASK_MAC0 (1U<<16)
+#define CONTEXT_EN_MASK_MAC1 (1U<<17)
+#define CONTEXT_EN_MASK_TIMER (1U<<18)
+#define CONTEXT_EN_MASK_GPIO0 (1U<<19)
+#define CONTEXT_EN_MASK_GPIO1 (1U<<20)
+#define CONTEXT_EN_MASK_GPIO2 (1U<<21)
+#define CONTEXT_EN_MASK_RTC (1U<<22)
+#define CONTEXT_EN_MASK_H2FINT (1U<<23)
+#define CONTEXT_EN_MASK_CRYPTO (1U<<24)
+#define CONTEXT_EN_MASK_USB (1U<<25)
+#define CONTEXT_EN_MASK_QSPIXIP (1U<<26)
+#define CONTEXT_EN_MASK_ATHENA (1U<<27)
+#define CONTEXT_EN_MASK_TRACE (1U<<28)
+#define CONTEXT_EN_MASK_MAILBOX_SC (1U<<29)
+#define CONTEXT_EN_MASK_MMC (1U<<30)
+#define CONTEXT_EN_MASK_CFM (1U<<31)
+
+/*
+ * Bit offsets associated with LIBERO_SETTING_CONTEXT_A_FIC_EN and
+ * LIBERO_SETTING_CONTEXT_B_FIC_EN
+ */
+#define CONTEXT_EN_MASK_FIC0 (1U<<0)
+#define CONTEXT_EN_MASK_FIC1 (1U<<1)
+#define CONTEXT_EN_MASK_FIC2 (1U<<2)
+#define CONTEXT_EN_MASK_FIC3 (1U<<3)
+
+
+uint8_t pmp_configure(uint8_t hart_id);
+void pmp_master_configs(uint8_t hart_id, uint64_t * pmp0cfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_PMP_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_seg.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_seg.h
new file mode 100644
index 00000000..32534501
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_seg.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ *
+ * @file mss_seg.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief segmentation block defines
+ *
+ * These blocks allow the DDR memory to be allocated to cached, non-cached
+ * regions and trace depending on the amount of DDR memory physically connected.
+ * Conceptually an address offset is added/subtracted from the DDR address
+ * provided by the Core Complex to point at a base address in the DDR memory.
+ *
+ * The AXI bus simply passes through the segmentation block, and the address
+ * is modified.
+ *
+ * There are two segmentation blocks, they are grouped into the same address
+ * ranges as the MPU blocks. Each one has seven 32-segmentation registers, but
+ * only two in SEG0 and five in SEG1 are actually implemented.
+ *
+ * DDRC blocker - blocks writes to DDR before it is set-up
+ * SEG0.CFG[7]
+ * Is cleared at reset. When written to '1' disables the blocker function
+ * Is allowing the L2 cache controller to access the DDRC.
+ * Is Once written to '1' the register cannot be written to 0, only an MSS reset
+ * Is will clear the register
+ *
+ */
+
+#ifndef MSS_SEG_H
+#define MSS_SEG_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ union {
+ struct {
+ volatile int32_t offset : 15;
+ volatile int32_t rsrvd : 16;
+ volatile int32_t locked : 1;
+ } CFG;
+ uint32_t raw;
+ } u[8u];
+
+ uint32_t fill[64U-8U];
+
+} seg_t;
+
+#define SEG ((seg_t*) 0x20005d00)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MSS_SEG_H*/
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_sysreg.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_sysreg.h
new file mode 100644
index 00000000..7a255e25
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_sysreg.h
@@ -0,0 +1,4069 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/**************************************************************************
+ *
+ * @file mss_sysreg.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Hardware register definitions.
+
+ *
+ */
+#ifndef MSS_SYSREG_H
+#define MSS_SYSREG_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* IO definitions (access restrictions to peripheral registers) */
+ /**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+ IO Type Qualifiers are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+
+ */
+#ifndef __I
+ #ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permis
+ sions */
+ #else
+ #define __I volatile const /*!< Defines 'read only' permis
+ sions */
+ #endif
+#endif
+#ifndef __O
+ #define __O volatile /*!< Defines 'write only' permi
+ ssions */
+#endif
+#ifndef __IO
+ #define __IO volatile /*!< Defines 'read / write' per
+ missions */
+#endif
+ /* following defines should be used for structure members */
+#ifndef __IM
+ #define __IM volatile const /*! Defines 'read only' structu
+ re member permissions */
+#endif
+#ifndef __OM
+ #define __OM volatile /*! Defines 'write only' struct
+ ure member permissions */
+#endif
+#ifndef __IOM
+ #define __IOM volatile /*! Defines 'read / write' stru
+ cture member permissions */
+#endif
+
+/* Defines all Top Register offsets*/
+/* Date of Source Revision File: 12-Jul-18*/
+/* PROTOCOL=MSS; BASE=32'h20012000*/
+/* Hardware Base Address*/
+#define BASE32_ADDR_MSS_SYSREG 0x20002000
+
+
+/*Register for software use*/
+#define TEMP0_OFFSET 0x0
+ /* Scratch register for CPUS*/
+ #define TEMP0_DATA_OFFSET 0x0
+ #define TEMP0_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Register for software use*/
+#define TEMP1_OFFSET 0x4
+ /* Scratch register for CPUS*/
+ #define TEMP1_DATA_OFFSET 0x0
+ #define TEMP1_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Master clock configuration*/
+#define CLOCK_CONFIG_CR_OFFSET 0x8
+ /* "Sets the master synchronous clock divider bits [1:0] CPU clock divi
+ der (Reset=/1 =0)bits [3:2] AXI clock divider (Reset=/
+ 1 =0)bits [5:4] AHB/APB clock divider (Reset=/2 =1)00=/1 01=/2 10=/4 11
+ =/8 (AHB/APB divider may not be set to /1)Note at reset MSS corner clock i
+ s 80MHz therefore divider is set to divide by 1"*/
+ #define CLOCK_CONFIG_CR_DIVIDER_OFFSET 0x0
+ #define CLOCK_CONFIG_CR_DIVIDER_MASK (0x3F << 0x0)
+ /* When '1' requests G5_control to enable the 1mHz (2MHz) on-chip oscil
+ lator*/
+ #define CLOCK_CONFIG_CR_ENABLE_1MHZ_OFFSET 0x8
+ #define CLOCK_CONFIG_CR_ENABLE_1MHZ_MASK (0x01 << 0x8)
+
+/*RTC clock divider*/
+#define RTC_CLOCK_CR_OFFSET 0xC
+ /* "Sets the division ratio to create the internal RTC clock from the
+ reference clock. The defaults sets the reference clock to 1MHz assuming the
+ reference clock is 100Mhz.If the reference clock is 125MHz then 125 will c
+ reate a 1MHz clockMax divider value is 4095 and value must be an integer.RT
+ C clock must be less 2X the AXI clock rate."*/
+ #define RTC_CLOCK_CR_PERIOD_OFFSET 0x0
+ #define RTC_CLOCK_CR_PERIOD_MASK (0xFFF << 0x0)
+ /* RTC Clock enable. When chaning the divider the enable should be trur
+ ned off first the divider changed and the enable turned back on.*/
+ #define RTC_CLOCK_CR_ENABLE_OFFSET 0x10
+ #define RTC_CLOCK_CR_ENABLE_MASK (0x01 << 0x10)
+
+/*Fabric Reset mask*/
+#define FABRIC_RESET_CR_OFFSET 0x10
+ /* Blocks the fabric Reset input preventing the fabric reseting the MSS
+ */
+ #define FABRIC_RESET_CR_ENABLE_OFFSET 0x0
+ #define FABRIC_RESET_CR_ENABLE_MASK (0x01 << 0x0)
+
+/**/
+#define BOOT_FAIL_CR_OFFSET 0x14
+ /* Written by firmware to indicate that the boot process failed drives
+ the fab_boot_fail signal to the fabric. Is cleared by the fabric asserting
+ fab_boot_fail_clear*/
+ #define BOOT_FAIL_CR_BOOT_OFFSET 0x0
+ #define BOOT_FAIL_CR_BOOT_MASK (0x01 << 0x0)
+
+/*Configuration lock*/
+#define CONFIG_LOCK_CR_OFFSET 0x1C
+ /* When written to '1' will cause all RWC registers to lock until a mas
+ ter reset occurs.*/
+ #define CONFIG_LOCK_CR_LOCK_OFFSET 0x0
+ #define CONFIG_LOCK_CR_LOCK_MASK (0x01 << 0x0)
+
+/*Indicates which reset caused the last reset. After a reset occurs registe
+ r should be read and then zero written to allow the next reset event to be
+ correctly captured.*/
+#define RESET_SR_OFFSET 0x20
+ /* Reset was caused by the SCB periphery reset signal*/
+ #define RESET_SR_SCB_PERIPH_RESET_OFFSET 0x0
+ #define RESET_SR_SCB_PERIPH_RESET_MASK (0x01 << 0x0)
+ /* Reset was caused by the SCB MSS reset register*/
+ #define RESET_SR_SCB_MSS_RESET_OFFSET 0x1
+ #define RESET_SR_SCB_MSS_RESET_MASK (0x01 << 0x1)
+ /* Reset was caused by the SCB CPU reset register*/
+ #define RESET_SR_SCB_CPU_RESET_OFFSET 0x2
+ #define RESET_SR_SCB_CPU_RESET_MASK (0x01 << 0x2)
+ /* Reset was caused by the Risc-V Debugger*/
+ #define RESET_SR_DEBUGER_RESET_OFFSET 0x3
+ #define RESET_SR_DEBUGER_RESET_MASK (0x01 << 0x3)
+ /* Reset was caused by the fabric*/
+ #define RESET_SR_FABRIC_RESET_OFFSET 0x4
+ #define RESET_SR_FABRIC_RESET_MASK (0x01 << 0x4)
+ /* Reset was caused by the watchdog*/
+ #define RESET_SR_WDOG_RESET_OFFSET 0x5
+ #define RESET_SR_WDOG_RESET_MASK (0x01 << 0x5)
+ /* Indicates that fabric asserted the GPIO reset inputs*/
+ #define RESET_SR_GPIO_RESET_OFFSET 0x6
+ #define RESET_SR_GPIO_RESET_MASK (0x01 << 0x6)
+ /* Indicates that SCB bus reset occurred (which causes warm reset of MS
+ S)*/
+ #define RESET_SR_SCB_BUS_RESET_OFFSET 0x7
+ #define RESET_SR_SCB_BUS_RESET_MASK (0x01 << 0x7)
+
+/*Indicates the device status in particular the state of the FPGA fabric an
+ d the MSS IO banks*/
+#define DEVICE_STATUS_OFFSET 0x24
+ /* Indicates the status of the core_up input from G5 Control.*/
+ #define DEVICE_STATUS_CORE_UP_OFFSET 0x0
+ #define DEVICE_STATUS_CORE_UP_MASK (0x01 << 0x0)
+ /* Indicates the status of the lp_state input from G5 Control.*/
+ #define DEVICE_STATUS_LP_STATE_OFFSET 0x1
+ #define DEVICE_STATUS_LP_STATE_MASK (0x01 << 0x1)
+ /* Indicates the status of the ff_in_progress input from G5 Control.*/
+ #define DEVICE_STATUS_FF_IN_PROGRESS_OFFSET 0x2
+ #define DEVICE_STATUS_FF_IN_PROGRESS_MASK (0x01 << 0x2)
+ /* Indicates the status of the flash_valid input from G5 Control.*/
+ #define DEVICE_STATUS_FLASH_VALID_OFFSET 0x3
+ #define DEVICE_STATUS_FLASH_VALID_MASK (0x01 << 0x3)
+ /* Power status of IO bank 2*/
+ #define DEVICE_STATUS_IO_BANK_B2_STATUS_OFFSET 0x8
+ #define DEVICE_STATUS_IO_BANK_B2_STATUS_MASK (0x01 << 0x8)
+ /* Power status of IO bank 4*/
+ #define DEVICE_STATUS_IO_BANK_B4_STATUS_OFFSET 0x9
+ #define DEVICE_STATUS_IO_BANK_B4_STATUS_MASK (0x01 << 0x9)
+ /* Power status of IO bank 5*/
+ #define DEVICE_STATUS_IO_BANK_B5_STATUS_OFFSET 0xA
+ #define DEVICE_STATUS_IO_BANK_B5_STATUS_MASK (0x01 << 0xA)
+ /* Power status of IO bank 6*/
+ #define DEVICE_STATUS_IO_BANK_B6_STATUS_OFFSET 0xB
+ #define DEVICE_STATUS_IO_BANK_B6_STATUS_MASK (0x01 << 0xB)
+ /* Indicates the status of the io_en input from G5 Control.*/
+ #define DEVICE_STATUS_IO_EN_OFFSET 0xC
+ #define DEVICE_STATUS_IO_EN_MASK (0x01 << 0xC)
+
+/*MSS Build Info*/
+#define MSS_BUILD_OFFSET 0x28
+ #define MSS_BUILD_REVISION_OFFSET 0x0
+ #define MSS_BUILD_REVISION_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-1 Fabric interrupt enable*/
+#define FAB_INTEN_U54_1_OFFSET 0x40
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_1_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_1_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-2 Fabric interrupt enable*/
+#define FAB_INTEN_U54_2_OFFSET 0x44
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_2_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_2_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-3 Fabric interrupt enable*/
+#define FAB_INTEN_U54_3_OFFSET 0x48
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_3_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_3_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*U54-4 Fabric interrupt enable*/
+#define FAB_INTEN_U54_4_OFFSET 0x4C
+ /* Enables the F2H_interrupts[31:0] to interrupt U54_1 directly*/
+ #define FAB_INTEN_U54_4_ENABLE_OFFSET 0x0
+ #define FAB_INTEN_U54_4_ENABLE_MASK (0xFFFFFFFF << 0x0)
+
+/*Allows the Ethernat interrupts to be directly routed to the U54 CPUS.*/
+#define FAB_INTEN_MISC_OFFSET 0x50
+ /* Enables the Ethernet MAC0 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC0_U54_1_OFFSET 0x0
+ #define FAB_INTEN_MISC_MAC0_U54_1_MASK (0x01 << 0x0)
+ /* Enables the Ethernet MAC0 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC0_U54_2_OFFSET 0x1
+ #define FAB_INTEN_MISC_MAC0_U54_2_MASK (0x01 << 0x1)
+ /* Enables the Ethernet MAC1 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC1_U54_3_OFFSET 0x2
+ #define FAB_INTEN_MISC_MAC1_U54_3_MASK (0x01 << 0x2)
+ /* Enables the Ethernet MAC1 to interrupt U54_1 directly*/
+ #define FAB_INTEN_MISC_MAC1_U54_4_OFFSET 0x3
+ #define FAB_INTEN_MISC_MAC1_U54_4_MASK (0x01 << 0x3)
+
+/*Switches GPIO interrupt from PAD to Fabric GPIO*/
+#define GPIO_INTERRUPT_FAB_CR_OFFSET 0x54
+ /* Setting these bits will disable the Pad interrupt and enable the fabric
+ GPIO interrupt for bits 31:0. When the bit is set the Pad interrupt will
+ be ORED into the GPIO0 & GPIO1 non-direct interrupts. When the bit is
+ not set the Fabric interrupt is ORED into the GPIO2 non-direct interrupt.
+ To prevent ORING then the interrupt should not be enabled in the GPIO block
+ */
+ #define GPIO_INTERRUPT_FAB_CR_SELECT_OFFSET 0x0
+ #define GPIO_INTERRUPT_FAB_CR_SELECT_MASK (0xFFFFFFFF << 0x0)
+
+/*"AMP Mode peripheral mapping register. When the register bit is '0' the p
+ eripheral is mapped into the 0x2000000 address range using AXI bus 5 from t
+ he Coreplex. When the register bit is '1' the peripheral is mapped into the
+ 0x28000000 address range using AXI bus 6 from the Coreplex."*/
+#define APBBUS_CR_OFFSET 0x80
+ /* */
+ #define APBBUS_CR_MMUART0_OFFSET 0x0
+ #define APBBUS_CR_MMUART0_MASK (0x01 << 0x0)
+ /* */
+ #define APBBUS_CR_MMUART1_OFFSET 0x1
+ #define APBBUS_CR_MMUART1_MASK (0x01 << 0x1)
+ /* */
+ #define APBBUS_CR_MMUART2_OFFSET 0x2
+ #define APBBUS_CR_MMUART2_MASK (0x01 << 0x2)
+ /* */
+ #define APBBUS_CR_MMUART3_OFFSET 0x3
+ #define APBBUS_CR_MMUART3_MASK (0x01 << 0x3)
+ /* */
+ #define APBBUS_CR_MMUART4_OFFSET 0x4
+ #define APBBUS_CR_MMUART4_MASK (0x01 << 0x4)
+ /* */
+ #define APBBUS_CR_WDOG0_OFFSET 0x5
+ #define APBBUS_CR_WDOG0_MASK (0x01 << 0x5)
+ /* */
+ #define APBBUS_CR_WDOG1_OFFSET 0x6
+ #define APBBUS_CR_WDOG1_MASK (0x01 << 0x6)
+ /* */
+ #define APBBUS_CR_WDOG2_OFFSET 0x7
+ #define APBBUS_CR_WDOG2_MASK (0x01 << 0x7)
+ /* */
+ #define APBBUS_CR_WDOG3_OFFSET 0x8
+ #define APBBUS_CR_WDOG3_MASK (0x01 << 0x8)
+ /* */
+ #define APBBUS_CR_WDOG4_OFFSET 0x9
+ #define APBBUS_CR_WDOG4_MASK (0x01 << 0x9)
+ /* */
+ #define APBBUS_CR_SPI0_OFFSET 0xA
+ #define APBBUS_CR_SPI0_MASK (0x01 << 0xA)
+ /* */
+ #define APBBUS_CR_SPI1_OFFSET 0xB
+ #define APBBUS_CR_SPI1_MASK (0x01 << 0xB)
+ /* */
+ #define APBBUS_CR_I2C0_OFFSET 0xC
+ #define APBBUS_CR_I2C0_MASK (0x01 << 0xC)
+ /* */
+ #define APBBUS_CR_I2C1_OFFSET 0xD
+ #define APBBUS_CR_I2C1_MASK (0x01 << 0xD)
+ /* */
+ #define APBBUS_CR_CAN0_OFFSET 0xE
+ #define APBBUS_CR_CAN0_MASK (0x01 << 0xE)
+ /* */
+ #define APBBUS_CR_CAN1_OFFSET 0xF
+ #define APBBUS_CR_CAN1_MASK (0x01 << 0xF)
+ /* */
+ #define APBBUS_CR_GEM0_OFFSET 0x10
+ #define APBBUS_CR_GEM0_MASK (0x01 << 0x10)
+ /* */
+ #define APBBUS_CR_GEM1_OFFSET 0x11
+ #define APBBUS_CR_GEM1_MASK (0x01 << 0x11)
+ /* */
+ #define APBBUS_CR_TIMER_OFFSET 0x12
+ #define APBBUS_CR_TIMER_MASK (0x01 << 0x12)
+ /* */
+ #define APBBUS_CR_GPIO0_OFFSET 0x13
+ #define APBBUS_CR_GPIO0_MASK (0x01 << 0x13)
+ /* */
+ #define APBBUS_CR_GPIO1_OFFSET 0x14
+ #define APBBUS_CR_GPIO1_MASK (0x01 << 0x14)
+ /* */
+ #define APBBUS_CR_GPIO2_OFFSET 0x15
+ #define APBBUS_CR_GPIO2_MASK (0x01 << 0x15)
+ /* */
+ #define APBBUS_CR_RTC_OFFSET 0x16
+ #define APBBUS_CR_RTC_MASK (0x01 << 0x16)
+ /* */
+ #define APBBUS_CR_H2FINT_OFFSET 0x17
+ #define APBBUS_CR_H2FINT_MASK (0x01 << 0x17)
+
+/*"Enables the clock to the MSS peripheral. By turning clocks off dynamic power
+ can be saved. When the clock is off the peripheral should not be accessed
+ the access may be ignored return unspecified data or result in bus response
+ error."*/
+#define SUBBLK_CLOCK_CR_OFFSET 0x84
+ /* */
+ #define SUBBLK_CLOCK_CR_ENVM_OFFSET 0x0
+ #define SUBBLK_CLOCK_CR_ENVM_MASK (0x01 << 0x0)
+ /* */
+ #define SUBBLK_CLOCK_CR_MAC0_OFFSET 0x1
+ #define SUBBLK_CLOCK_CR_MAC0_MASK (0x01 << 0x1)
+ /* */
+ #define SUBBLK_CLOCK_CR_MAC1_OFFSET 0x2
+ #define SUBBLK_CLOCK_CR_MAC1_MASK (0x01 << 0x2)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMC_OFFSET 0x3
+ #define SUBBLK_CLOCK_CR_MMC_MASK (0x01 << 0x3)
+ /* */
+ #define SUBBLK_CLOCK_CR_TIMER_OFFSET 0x4
+ #define SUBBLK_CLOCK_CR_TIMER_MASK (0x01 << 0x4)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART0_OFFSET 0x5
+ #define SUBBLK_CLOCK_CR_MMUART0_MASK (0x01 << 0x5)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART1_OFFSET 0x6
+ #define SUBBLK_CLOCK_CR_MMUART1_MASK (0x01 << 0x6)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART2_OFFSET 0x7
+ #define SUBBLK_CLOCK_CR_MMUART2_MASK (0x01 << 0x7)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART3_OFFSET 0x8
+ #define SUBBLK_CLOCK_CR_MMUART3_MASK (0x01 << 0x8)
+ /* */
+ #define SUBBLK_CLOCK_CR_MMUART4_OFFSET 0x9
+ #define SUBBLK_CLOCK_CR_MMUART4_MASK (0x01 << 0x9)
+ /* */
+ #define SUBBLK_CLOCK_CR_SPI0_OFFSET 0xA
+ #define SUBBLK_CLOCK_CR_SPI0_MASK (0x01 << 0xA)
+ /* */
+ #define SUBBLK_CLOCK_CR_SPI1_OFFSET 0xB
+ #define SUBBLK_CLOCK_CR_SPI1_MASK (0x01 << 0xB)
+ /* */
+ #define SUBBLK_CLOCK_CR_I2C0_OFFSET 0xC
+ #define SUBBLK_CLOCK_CR_I2C0_MASK (0x01 << 0xC)
+ /* */
+ #define SUBBLK_CLOCK_CR_I2C1_OFFSET 0xD
+ #define SUBBLK_CLOCK_CR_I2C1_MASK (0x01 << 0xD)
+ /* */
+ #define SUBBLK_CLOCK_CR_CAN0_OFFSET 0xE
+ #define SUBBLK_CLOCK_CR_CAN0_MASK (0x01 << 0xE)
+ /* */
+ #define SUBBLK_CLOCK_CR_CAN1_OFFSET 0xF
+ #define SUBBLK_CLOCK_CR_CAN1_MASK (0x01 << 0xF)
+ /* */
+ #define SUBBLK_CLOCK_CR_USB_OFFSET 0x10
+ #define SUBBLK_CLOCK_CR_USB_MASK (0x01 << 0x10)
+ /* */
+ #define SUBBLK_CLOCK_CR_RSVD_OFFSET 0x11
+ #define SUBBLK_CLOCK_CR_RSVD_MASK (0x01 << 0x11)
+ /* */
+ #define SUBBLK_CLOCK_CR_RTC_OFFSET 0x12
+ #define SUBBLK_CLOCK_CR_RTC_MASK (0x01 << 0x12)
+ /* */
+ #define SUBBLK_CLOCK_CR_QSPI_OFFSET 0x13
+ #define SUBBLK_CLOCK_CR_QSPI_MASK (0x01 << 0x13)
+ /* */
+ #define SUBBLK_CLOCK_CR_GPIO0_OFFSET 0x14
+ #define SUBBLK_CLOCK_CR_GPIO0_MASK (0x01 << 0x14)
+ /* */
+ #define SUBBLK_CLOCK_CR_GPIO1_OFFSET 0x15
+ #define SUBBLK_CLOCK_CR_GPIO1_MASK (0x01 << 0x15)
+ /* */
+ #define SUBBLK_CLOCK_CR_GPIO2_OFFSET 0x16
+ #define SUBBLK_CLOCK_CR_GPIO2_MASK (0x01 << 0x16)
+ /* */
+ #define SUBBLK_CLOCK_CR_DDRC_OFFSET 0x17
+ #define SUBBLK_CLOCK_CR_DDRC_MASK (0x01 << 0x17)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC0_OFFSET 0x18
+ #define SUBBLK_CLOCK_CR_FIC0_MASK (0x01 << 0x18)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC1_OFFSET 0x19
+ #define SUBBLK_CLOCK_CR_FIC1_MASK (0x01 << 0x19)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC2_OFFSET 0x1A
+ #define SUBBLK_CLOCK_CR_FIC2_MASK (0x01 << 0x1A)
+ /* */
+ #define SUBBLK_CLOCK_CR_FIC3_OFFSET 0x1B
+ #define SUBBLK_CLOCK_CR_FIC3_MASK (0x01 << 0x1B)
+ /* */
+ #define SUBBLK_CLOCK_CR_ATHENA_OFFSET 0x1C
+ #define SUBBLK_CLOCK_CR_ATHENA_MASK (0x01 << 0x1C)
+ /* */
+ #define SUBBLK_CLOCK_CR_CFM_OFFSET 0x1D
+ #define SUBBLK_CLOCK_CR_CFM_MASK (0x01 << 0x1D)
+
+/*"Holds the MSS peripherals in reset. When in reset the peripheral should
+ not be accessed the acess may be ignored return unspecified data or result
+ in bus response error."*/
+#define SOFT_RESET_CR_OFFSET 0x88
+ /* */
+ #define SOFT_RESET_CR_ENVM_OFFSET 0x0
+ #define SOFT_RESET_CR_ENVM_MASK (0x01 << 0x0)
+ /* */
+ #define SOFT_RESET_CR_MAC0_OFFSET 0x1
+ #define SOFT_RESET_CR_MAC0_MASK (0x01 << 0x1)
+ /* */
+ #define SOFT_RESET_CR_MAC1_OFFSET 0x2
+ #define SOFT_RESET_CR_MAC1_MASK (0x01 << 0x2)
+ /* */
+ #define SOFT_RESET_CR_MMC_OFFSET 0x3
+ #define SOFT_RESET_CR_MMC_MASK (0x01 << 0x3)
+ /* */
+ #define SOFT_RESET_CR_TIMER_OFFSET 0x4
+ #define SOFT_RESET_CR_TIMER_MASK (0x01 << 0x4)
+ /* */
+ #define SOFT_RESET_CR_MMUART0_OFFSET 0x5
+ #define SOFT_RESET_CR_MMUART0_MASK (0x01 << 0x5)
+ /* */
+ #define SOFT_RESET_CR_MMUART1_OFFSET 0x6
+ #define SOFT_RESET_CR_MMUART1_MASK (0x01 << 0x6)
+ /* */
+ #define SOFT_RESET_CR_MMUART2_OFFSET 0x7
+ #define SOFT_RESET_CR_MMUART2_MASK (0x01 << 0x7)
+ /* */
+ #define SOFT_RESET_CR_MMUART3_OFFSET 0x8
+ #define SOFT_RESET_CR_MMUART3_MASK (0x01 << 0x8)
+ /* */
+ #define SOFT_RESET_CR_MMUART4_OFFSET 0x9
+ #define SOFT_RESET_CR_MMUART4_MASK (0x01 << 0x9)
+ /* */
+ #define SOFT_RESET_CR_SPI0_OFFSET 0xA
+ #define SOFT_RESET_CR_SPI0_MASK (0x01 << 0xA)
+ /* */
+ #define SOFT_RESET_CR_SPI1_OFFSET 0xB
+ #define SOFT_RESET_CR_SPI1_MASK (0x01 << 0xB)
+ /* */
+ #define SOFT_RESET_CR_I2C0_OFFSET 0xC
+ #define SOFT_RESET_CR_I2C0_MASK (0x01 << 0xC)
+ /* */
+ #define SOFT_RESET_CR_I2C1_OFFSET 0xD
+ #define SOFT_RESET_CR_I2C1_MASK (0x01 << 0xD)
+ /* */
+ #define SOFT_RESET_CR_CAN0_OFFSET 0xE
+ #define SOFT_RESET_CR_CAN0_MASK (0x01 << 0xE)
+ /* */
+ #define SOFT_RESET_CR_CAN1_OFFSET 0xF
+ #define SOFT_RESET_CR_CAN1_MASK (0x01 << 0xF)
+ /* */
+ #define SOFT_RESET_CR_USB_OFFSET 0x10
+ #define SOFT_RESET_CR_USB_MASK (0x01 << 0x10)
+ /* */
+ #define SOFT_RESET_CR_FPGA_OFFSET 0x11
+ #define SOFT_RESET_CR_FPGA_MASK (0x01 << 0x11)
+ /* */
+ #define SOFT_RESET_CR_RTC_OFFSET 0x12
+ #define SOFT_RESET_CR_RTC_MASK (0x01 << 0x12)
+ /* */
+ #define SOFT_RESET_CR_QSPI_OFFSET 0x13
+ #define SOFT_RESET_CR_QSPI_MASK (0x01 << 0x13)
+ /* */
+ #define SOFT_RESET_CR_GPIO0_OFFSET 0x14
+ #define SOFT_RESET_CR_GPIO0_MASK (0x01 << 0x14)
+ /* */
+ #define SOFT_RESET_CR_GPIO1_OFFSET 0x15
+ #define SOFT_RESET_CR_GPIO1_MASK (0x01 << 0x15)
+ /* */
+ #define SOFT_RESET_CR_GPIO2_OFFSET 0x16
+ #define SOFT_RESET_CR_GPIO2_MASK (0x01 << 0x16)
+ /* */
+ #define SOFT_RESET_CR_DDRC_OFFSET 0x17
+ #define SOFT_RESET_CR_DDRC_MASK (0x01 << 0x17)
+ /* */
+ #define SOFT_RESET_CR_FIC0_OFFSET 0x18
+ #define SOFT_RESET_CR_FIC0_MASK (0x01 << 0x18)
+ /* */
+ #define SOFT_RESET_CR_FIC1_OFFSET 0x19
+ #define SOFT_RESET_CR_FIC1_MASK (0x01 << 0x19)
+ /* */
+ #define SOFT_RESET_CR_FIC2_OFFSET 0x1A
+ #define SOFT_RESET_CR_FIC2_MASK (0x01 << 0x1A)
+ /* */
+ #define SOFT_RESET_CR_FIC3_OFFSET 0x1B
+ #define SOFT_RESET_CR_FIC3_MASK (0x01 << 0x1B)
+ /* */
+ #define SOFT_RESET_CR_ATHENA_OFFSET 0x1C
+ #define SOFT_RESET_CR_ATHENA_MASK (0x01 << 0x1C)
+ /* */
+ #define SOFT_RESET_CR_CFM_OFFSET 0x1D
+ #define SOFT_RESET_CR_CFM_MASK (0x01 << 0x1D)
+ /* Reset to Corner SGMII block*/
+ #define SOFT_RESET_CR_SGMII_OFFSET 0x1E
+ #define SOFT_RESET_CR_SGMII_MASK (0x01 << 0x1E)
+
+/*Configures how many outstanding transfers the AXI-AHB bridges in front of
+ f the USB and Crypto blocks should allow. (See Synopsys AXI-AHB bridge docu
+ mentation)*/
+#define AHBAXI_CR_OFFSET 0x8C
+ /* Number of outstanding write transactions to USB block*/
+ #define AHBAXI_CR_USB_WBCNT_OFFSET 0x0
+ #define AHBAXI_CR_USB_WBCNT_MASK (0x0F << 0x0)
+ /* Number of outstanding read transactions to USB block*/
+ #define AHBAXI_CR_USB_RBCNT_OFFSET 0x4
+ #define AHBAXI_CR_USB_RBCNT_MASK (0x0F << 0x4)
+ /* Number of outstanding write transactions to Athena block*/
+ #define AHBAXI_CR_ATHENA_WBCNT_OFFSET 0x8
+ #define AHBAXI_CR_ATHENA_WBCNT_MASK (0x0F << 0x8)
+ /* Number of outstanding read transactions to Athena block*/
+ #define AHBAXI_CR_ATHENA_RBCNT_OFFSET 0xC
+ #define AHBAXI_CR_ATHENA_RBCNT_MASK (0x0F << 0xC)
+
+/*Configures the two AHB-APB bridges on S5 and S6*/
+#define AHBAPB_CR_OFFSET 0x90
+ /* Enables posted mode on the AHB-APB bridge when set the AHB write cyc
+ le will complete before the APB write cycle completes.*/
+ #define AHBAPB_CR_APB0_POSTED_OFFSET 0x0
+ #define AHBAPB_CR_APB0_POSTED_MASK (0x01 << 0x0)
+ /* Enables posted mode on the AHB-APB bridge when set the AHB write cyc
+ le will complete before the APB write cycle completes.*/
+ #define AHBAPB_CR_APB1_POSTED_OFFSET 0x1
+ #define AHBAPB_CR_APB1_POSTED_MASK (0x01 << 0x1)
+
+/*MSS Corner APB interface controls*/
+#define DFIAPB_CR_OFFSET 0x98
+ /* Turns on the APB clock to the MSS Corner is off at reset. Once corne
+ r blocks is configured the firmware may turn off the clock but periodically
+ should turn back on to allow refresh of TMR registers inside the corner bl
+ ock. */
+ #define DFIAPB_CR_CLOCKON_OFFSET 0x0
+ #define DFIAPB_CR_CLOCKON_MASK (0x01 << 0x0)
+ /* Asserts the APB reset to the MSS corner is asserted at MSS reset.*/
+ #define DFIAPB_CR_RESET_OFFSET 0x1
+ #define DFIAPB_CR_RESET_MASK (0x01 << 0x1)
+
+/*GPIO Blocks reset control*/
+#define GPIO_CR_OFFSET 0x9C
+ /* "This signal selects whether the associated byte is reset by soft re
+ set or the the MSS_GPIO_RESET_N signal from the FPGA fabric. The allowed va
+ lues are:* 0: Selects MSS_GPIO_RESET_N signal from the FPGA fabric.* 1
+ : Selects the GPIO to be reset by the GPIO block soft reset signal .Bit 0
+ controls GPIO0 [7:0] and bit 1 GPIO[15:8]The master MSS reset will also r
+ eset the GPIO register if not configured to use fabric reset."*/
+ #define GPIO_CR_GPIO0_SOFT_RESET_SELECT_OFFSET 0x0
+ #define GPIO_CR_GPIO0_SOFT_RESET_SELECT_MASK (0x03 << 0x0)
+ /* "Sets the reset value off the GPIO0 per byteBit 0 controls GPIO0 [7:
+ 0] and bit 1 GPIO[15:8]"*/
+ #define GPIO_CR_GPIO0_DEFAULT_OFFSET 0x4
+ #define GPIO_CR_GPIO0_DEFAULT_MASK (0x03 << 0x4)
+ /* "This signal selects whether the associated byte is reset by soft re
+ set or the the MSS_GPIO_RESET_N signal from the FPGA fabric. The allowed va
+ lues are:* 0: Selects MSS_GPIO_RESET_N signal from the FPGA fabric.* 1
+ : Selects the GPIO to be reset by the GPIO block soft reset signal .Bit 0
+ controls GPIO0 [7:0] bit 1 GPIO[15:8] and bit 2 GPIO[23:16]The master MSS
+ reset will also reset the GPIO register if not configured to use fabric res
+ et."*/
+ #define GPIO_CR_GPIO1_SOFT_RESET_SELECT_OFFSET 0x8
+ #define GPIO_CR_GPIO1_SOFT_RESET_SELECT_MASK (0x07 << 0x8)
+ /* "Sets the reset value off the GPIO0 per byteBit 0 controls GPIO0 [7:
+ 0] bit 1 GPIO[15:8] and bit 2 GPIO[23:16]"*/
+ #define GPIO_CR_GPIO1_DEFAULT_OFFSET 0xC
+ #define GPIO_CR_GPIO1_DEFAULT_MASK (0x07 << 0xC)
+ /* "This signal selects whether the associated byte is reset by soft re
+ set or the the MSS_GPIO_RESET_N signal from the FPGA fabric. The allowed va
+ lues are:* 0: Selects MSS_GPIO_RESET_N signal from the FPGA fabric.* 1
+ : Selects the GPIO to be reset by the GPIO block soft reset signal .Bit 0
+ controls GPIO0 [7:0] bit 1 GPIO[15:8] and bit 1 GPIO[23:16] and bit 3 GPIO
+ [31:24]The master MSS reset will also reset the GPIO register if not config
+ ured to use fabric reset."*/
+ #define GPIO_CR_GPIO2_SOFT_RESET_SELECT_OFFSET 0x10
+ #define GPIO_CR_GPIO2_SOFT_RESET_SELECT_MASK (0x0F << 0x10)
+ /* "Sets the reset value off the GPIO0 per byteBit 0 controls GPIO0 [7:
+ 0] bit 1 GPIO[15:8] and bit 1 GPIO[23:16] and bit 3 GPIO[31:24]"*/
+ #define GPIO_CR_GPIO2_DEFAULT_OFFSET 0x14
+ #define GPIO_CR_GPIO2_DEFAULT_MASK (0x0F << 0x14)
+
+/*MAC0 configuration register*/
+#define MAC0_CR_OFFSET 0xA4
+ /* Current speed mode on the MAC*/
+ #define MAC0_CR_SPEED_MODE_OFFSET 0x0
+ #define MAC0_CR_SPEED_MODE_MASK (0x0F << 0x0)
+
+/*MAC1 configuration register*/
+#define MAC1_CR_OFFSET 0xA8
+ /* Current speed mode on the MAC*/
+ #define MAC1_CR_SPEED_MODE_OFFSET 0x0
+ #define MAC1_CR_SPEED_MODE_MASK (0x0F << 0x0)
+
+/*USB Configuration register*/
+#define USB_CR_OFFSET 0xAC
+ /* "Configures USB for Single-Data Rate(SDR) mode or Double-Data Rate(D
+ DR) mode. 0 - SDR Mode is selected1 - DDR Mode is selected (Not supported i
+ n G5 or G5)"*/
+ #define USB_CR_DDR_SELECT_OFFSET 0x0
+ #define USB_CR_DDR_SELECT_MASK (0x01 << 0x0)
+ /* When '1' will stops the clock to the USB core when the core asserts
+ its POWERDOWN output. For G4 compatibility this bit defaults to 0.*/
+ #define USB_CR_POWERDOWN_ENABLE_OFFSET 0x1
+ #define USB_CR_POWERDOWN_ENABLE_MASK (0x01 << 0x1)
+ /* Indicates that the USB CLK may be stopped to save power. Derived fro
+ m combination of signals from CLK & XCLK flip-flops AVALID VBUSVALID and LI
+ NESTATE. When asserted the USB clock into the core is stopped.*/
+ #define USB_CR_POWERDOWN_OFFSET 0x2
+ #define USB_CR_POWERDOWN_MASK (0x01 << 0x2)
+ /* Set when entry is made into CarKit mode and cleared on exit from Car
+ Kit mode.*/
+ #define USB_CR_LPI_CARKIT_EN_OFFSET 0x3
+ #define USB_CR_LPI_CARKIT_EN_MASK (0x01 << 0x3)
+
+/*Crypto Mesh control and status register*/
+#define MESH_CR_OFFSET 0xB0
+ /* Writing a 1 will start the Mesh System*/
+ #define MESH_CR_START_OFFSET 0x0
+ #define MESH_CR_START_MASK (0x01 << 0x0)
+ /* "Sets the amount of time that the mesh is held active for actual hol
+ d time includes up to 256 us of random variation.Minimum Time = 1 + 256 * v
+ alue usMaximum Time = 1 + 256 * (1+value) usValue must be greater than
+ 0"*/
+ #define MESH_CR_HOLD_OFFSET 0x1
+ #define MESH_CR_HOLD_MASK (0xFFF << 0x1)
+ /* When set will inject an error in the mesh*/
+ #define MESH_CR_INJECT_ERROR_OFFSET 0x10
+ #define MESH_CR_INJECT_ERROR_MASK (0x01 << 0x10)
+ /* Indicates that Mesh detected an error. Cleared by writing a '1'*/
+ #define MESH_CR_MESH_ERROR_OFFSET 0x18
+ #define MESH_CR_MESH_ERROR_MASK (0x01 << 0x18)
+ /* Indicates that the Mesh is functioning correctly. Will be set approx
+ imately 520 clock cycles after mesh started and stay set as long as the me
+ sh is not detecting any errors.*/
+ #define MESH_CR_OKAY_OFFSET 0x19
+ #define MESH_CR_OKAY_MASK (0x01 << 0x19)
+
+/*Crypto mesh seed and update rate*/
+#define MESH_SEED_CR_OFFSET 0xB4
+ /* Sets the mesh seed value any value may be used zero should be avoide
+ d*/
+ #define MESH_SEED_CR_SEED_OFFSET 0x0
+ #define MESH_SEED_CR_SEED_MASK (0x7FFFFF << 0x0)
+ /* Sets the rate that the mesh value is changed. Rate = AHBCLK/(clkrate
+ +1). Rate must be less than 1MHz setting slower will reduce power consumpti
+ on.*/
+ #define MESH_SEED_CR_CLKRATE_OFFSET 0x18
+ #define MESH_SEED_CR_CLKRATE_MASK (0xFF << 0x18)
+
+/*ENVM AHB Controller setup*/
+#define ENVM_CR_OFFSET 0xB8
+ /* "Sets the number of AHB cycles used to generate the PNVM clockClock
+ period = (Value+1) * (1000/AHBFREQMHZ) Value must be 1 to 63 (0
+ defaults to 15)e.g.11 will generate a 40ns period 25MHz clock if the AHB
+ clock is 250MHz15 will generate a 40ns period 25MHz clock if the AHB cloc
+ k is 400MHz"*/
+ #define ENVM_CR_CLOCK_PERIOD_OFFSET 0x0
+ #define ENVM_CR_CLOCK_PERIOD_MASK (0x3F << 0x0)
+ /* Indicates the eNVM is running at the configured divider rate. */
+ #define ENVM_CR_CLOCK_OKAY_OFFSET 0x6
+ #define ENVM_CR_CLOCK_OKAY_MASK (0x01 << 0x6)
+ /* When '1' the PNVM clock will be always generated and not stopped bet
+ ween access cycles. Setting this will increase access latency but mean that
+ the PNVM clock operates at a stable rate.*/
+ #define ENVM_CR_CLOCK_CONTINUOUS_OFFSET 0x8
+ #define ENVM_CR_CLOCK_CONTINUOUS_MASK (0x01 << 0x8)
+ /* When set suppresses clock edge between C-Bus access cycles so that t
+ hey appear as consecutive access cycles.*/
+ #define ENVM_CR_CLOCK_SUPPRESS_OFFSET 0x9
+ #define ENVM_CR_CLOCK_SUPPRESS_MASK (0x01 << 0x9)
+ /* "Enables ""read-ahead"" on the ENVM controller. The controller will
+ automatically read the next PNVM location as soon as possible ahead of the
+ AHB request. This will improve read performance when incrementing though
+ memory as the NVM reads and AHB cycles are pipelined. When set non incrementing
+ accesses will take longer as the controller may be in the process of reading
+ the next address and the PNVM cycle needs to complete prior to starting
+ the required read"*/
+ #define ENVM_CR_READAHEAD_OFFSET 0x10
+ #define ENVM_CR_READAHEAD_MASK (0x01 << 0x10)
+ /* When '1' the controller will initiate separate ENVM reads for all reads.
+ No buffering or speculative operations will be carried out. When performing
+ word reads incrementing through PNVM each location will be read twice
+ (intended for test use)*/
+ #define ENVM_CR_SLOWREAD_OFFSET 0x11
+ #define ENVM_CR_SLOWREAD_MASK (0x01 << 0x11)
+ /* Enable the ENVM interrupt*/
+ #define ENVM_CR_INTERRUPT_ENABLE_OFFSET 0x12
+ #define ENVM_CR_INTERRUPT_ENABLE_MASK (0x01 << 0x12)
+ /* "Sets the duration of the timer used to detect a non response of slow
+ response from the PNVM on C and R bus accesses.Timer Duration = Value *
+ (1000/AHBFREQMHZ) 0x00: Timer disabled. If the timer expires the AHB cycle
+ is terminates using the HRESP protocol"*/
+ #define ENVM_CR_TIMER_OFFSET 0x18
+ #define ENVM_CR_TIMER_MASK (0xFF << 0x18)
+
+/*Reserved*/
+#define RESERVED_BC_OFFSET 0xBC
+ /* Reserved register address*/
+ #define RESERVED_BC_RESERVED_OFFSET 0x0
+ #define RESERVED_BC_RESERVED_MASK (0x01 << 0x0)
+
+/*QOS Athena USB & MMC Configuration*/
+#define QOS_PERIPHERAL_CR_OFFSET 0xC0
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_ATHENA_READ_OFFSET 0x0
+ #define QOS_PERIPHERAL_CR_ATHENA_READ_MASK (0x0F << 0x0)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_ATHENA_WRITE_OFFSET 0x4
+ #define QOS_PERIPHERAL_CR_ATHENA_WRITE_MASK (0x0F << 0x4)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_USB_READ_OFFSET 0x8
+ #define QOS_PERIPHERAL_CR_USB_READ_MASK (0x0F << 0x8)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_USB_WRITE_OFFSET 0xC
+ #define QOS_PERIPHERAL_CR_USB_WRITE_MASK (0x0F << 0xC)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_MMC_READ_OFFSET 0x10
+ #define QOS_PERIPHERAL_CR_MMC_READ_MASK (0x0F << 0x10)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_MMC_WRITE_OFFSET 0x14
+ #define QOS_PERIPHERAL_CR_MMC_WRITE_MASK (0x0F << 0x14)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_TRACE_READ_OFFSET 0x18
+ #define QOS_PERIPHERAL_CR_TRACE_READ_MASK (0x0F << 0x18)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_PERIPHERAL_CR_TRACE_WRITE_OFFSET 0x1C
+ #define QOS_PERIPHERAL_CR_TRACE_WRITE_MASK (0x0F << 0x1C)
+
+/*QOS Configuration Coreplex*/
+#define QOS_CPLEXIO_CR_OFFSET 0xC4
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE0_READ_OFFSET 0x0
+ #define QOS_CPLEXIO_CR_DEVICE0_READ_MASK (0x0F << 0x0)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE0_WRITE_OFFSET 0x4
+ #define QOS_CPLEXIO_CR_DEVICE0_WRITE_MASK (0x0F << 0x4)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE1_READ_OFFSET 0x8
+ #define QOS_CPLEXIO_CR_DEVICE1_READ_MASK (0x0F << 0x8)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_DEVICE1_WRITE_OFFSET 0xC
+ #define QOS_CPLEXIO_CR_DEVICE1_WRITE_MASK (0x0F << 0xC)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC0_READ_OFFSET 0x10
+ #define QOS_CPLEXIO_CR_FABRIC0_READ_MASK (0x0F << 0x10)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC0_WRITE_OFFSET 0x14
+ #define QOS_CPLEXIO_CR_FABRIC0_WRITE_MASK (0x0F << 0x14)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC1_READ_OFFSET 0x18
+ #define QOS_CPLEXIO_CR_FABRIC1_READ_MASK (0x0F << 0x18)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXIO_CR_FABRIC1_WRITE_OFFSET 0x1C
+ #define QOS_CPLEXIO_CR_FABRIC1_WRITE_MASK (0x0F << 0x1C)
+
+/*QOS configuration DDRC*/
+#define QOS_CPLEXDDR_CR_OFFSET 0xC8
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_CACHE_READ_OFFSET 0x0
+ #define QOS_CPLEXDDR_CR_CACHE_READ_MASK (0x0F << 0x0)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_CACHE_WRITE_OFFSET 0x4
+ #define QOS_CPLEXDDR_CR_CACHE_WRITE_MASK (0x0F << 0x4)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_NCACHE_READ_OFFSET 0x8
+ #define QOS_CPLEXDDR_CR_NCACHE_READ_MASK (0x0F << 0x8)
+ /* Sets the QOS value from the specified device into the switch*/
+ #define QOS_CPLEXDDR_CR_NCACHE_WRITE_OFFSET 0xC
+ #define QOS_CPLEXDDR_CR_NCACHE_WRITE_MASK (0x0F << 0xC)
+
+/*Indicates that a master caused a MPU violation. Interrupts via maintenanc
+ e interrupt.*/
+#define MPU_VIOLATION_SR_OFFSET 0xF0
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_FIC0_OFFSET 0x0
+ #define MPU_VIOLATION_SR_FIC0_MASK (0x01 << 0x0)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_FIC1_OFFSET 0x1
+ #define MPU_VIOLATION_SR_FIC1_MASK (0x01 << 0x1)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_FIC2_OFFSET 0x2
+ #define MPU_VIOLATION_SR_FIC2_MASK (0x01 << 0x2)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_ATHENA_OFFSET 0x3
+ #define MPU_VIOLATION_SR_ATHENA_MASK (0x01 << 0x3)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_GEM0_OFFSET 0x4
+ #define MPU_VIOLATION_SR_GEM0_MASK (0x01 << 0x4)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_GEM1_OFFSET 0x5
+ #define MPU_VIOLATION_SR_GEM1_MASK (0x01 << 0x5)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_USB_OFFSET 0x6
+ #define MPU_VIOLATION_SR_USB_MASK (0x01 << 0x6)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_MMC_OFFSET 0x7
+ #define MPU_VIOLATION_SR_MMC_MASK (0x01 << 0x7)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_SCB_OFFSET 0x8
+ #define MPU_VIOLATION_SR_SCB_MASK (0x01 << 0x8)
+ /* Bit is set on violation. Cleared by writing '1'*/
+ #define MPU_VIOLATION_SR_TRACE_OFFSET 0x9
+ #define MPU_VIOLATION_SR_TRACE_MASK (0x01 << 0x9)
+
+/*Enables interrupts on MPU violations*/
+#define MPU_VIOLATION_INTEN_CR_OFFSET 0xF4
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_FIC0_OFFSET 0x0
+ #define MPU_VIOLATION_INTEN_CR_FIC0_MASK (0x01 << 0x0)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_FIC1_OFFSET 0x1
+ #define MPU_VIOLATION_INTEN_CR_FIC1_MASK (0x01 << 0x1)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_FIC2_OFFSET 0x2
+ #define MPU_VIOLATION_INTEN_CR_FIC2_MASK (0x01 << 0x2)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_ATHENA_OFFSET 0x3
+ #define MPU_VIOLATION_INTEN_CR_ATHENA_MASK (0x01 << 0x3)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_GEM0_OFFSET 0x4
+ #define MPU_VIOLATION_INTEN_CR_GEM0_MASK (0x01 << 0x4)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_GEM1_OFFSET 0x5
+ #define MPU_VIOLATION_INTEN_CR_GEM1_MASK (0x01 << 0x5)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_USB_OFFSET 0x6
+ #define MPU_VIOLATION_INTEN_CR_USB_MASK (0x01 << 0x6)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_MMC_OFFSET 0x7
+ #define MPU_VIOLATION_INTEN_CR_MMC_MASK (0x01 << 0x7)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_SCB_OFFSET 0x8
+ #define MPU_VIOLATION_INTEN_CR_SCB_MASK (0x01 << 0x8)
+ /* Enables the interrupt*/
+ #define MPU_VIOLATION_INTEN_CR_TRACE_OFFSET 0x9
+ #define MPU_VIOLATION_INTEN_CR_TRACE_MASK (0x01 << 0x9)
+
+/*AXI switch decode fail*/
+#define SW_FAIL_ADDR0_CR_OFFSET 0xF8
+ /* The address (bits 31:0) that failed. Reading this address as 64-bits
+ will return the 38-bit address in a single read combined with additional i
+ nformation in the next register*/
+ #define SW_FAIL_ADDR0_CR_ADDR_OFFSET 0x0
+ #define SW_FAIL_ADDR0_CR_ADDR_MASK (0xFFFFFFFF << 0x0)
+
+/*AXI switch decode fail*/
+#define SW_FAIL_ADDR1_CR_OFFSET 0xFC
+ /* Upper 6 bits off address [37:32]*/
+ #define SW_FAIL_ADDR1_CR_ADDR_OFFSET 0x0
+ #define SW_FAIL_ADDR1_CR_ADDR_MASK (0x3F << 0x0)
+ /* AXI ID off failure*/
+ #define SW_FAIL_ADDR1_CR_ID_OFFSET 0x8
+ #define SW_FAIL_ADDR1_CR_ID_MASK (0xFF << 0x8)
+ /* AXI write=1 or read=0*/
+ #define SW_FAIL_ADDR1_CR_WRITE_OFFSET 0x10
+ #define SW_FAIL_ADDR1_CR_WRITE_MASK (0x01 << 0x10)
+ /* */
+ #define SW_FAIL_ADDR1_CR_FAILED_OFFSET 0x11
+ #define SW_FAIL_ADDR1_CR_FAILED_MASK (0x01 << 0x11)
+
+/*Set when an ECC event happens*/
+#define EDAC_SR_OFFSET 0x100
+ /* */
+ #define EDAC_SR_MMC_1E_OFFSET 0x0
+ #define EDAC_SR_MMC_1E_MASK (0x01 << 0x0)
+ /* */
+ #define EDAC_SR_MMC_2E_OFFSET 0x1
+ #define EDAC_SR_MMC_2E_MASK (0x01 << 0x1)
+ /* */
+ #define EDAC_SR_DDRC_1E_OFFSET 0x2
+ #define EDAC_SR_DDRC_1E_MASK (0x01 << 0x2)
+ /* */
+ #define EDAC_SR_DDRC_2E_OFFSET 0x3
+ #define EDAC_SR_DDRC_2E_MASK (0x01 << 0x3)
+ /* */
+ #define EDAC_SR_MAC0_1E_OFFSET 0x4
+ #define EDAC_SR_MAC0_1E_MASK (0x01 << 0x4)
+ /* */
+ #define EDAC_SR_MAC0_2E_OFFSET 0x5
+ #define EDAC_SR_MAC0_2E_MASK (0x01 << 0x5)
+ /* */
+ #define EDAC_SR_MAC1_1E_OFFSET 0x6
+ #define EDAC_SR_MAC1_1E_MASK (0x01 << 0x6)
+ /* */
+ #define EDAC_SR_MAC1_2E_OFFSET 0x7
+ #define EDAC_SR_MAC1_2E_MASK (0x01 << 0x7)
+ /* */
+ #define EDAC_SR_USB_1E_OFFSET 0x8
+ #define EDAC_SR_USB_1E_MASK (0x01 << 0x8)
+ /* */
+ #define EDAC_SR_USB_2E_OFFSET 0x9
+ #define EDAC_SR_USB_2E_MASK (0x01 << 0x9)
+ /* */
+ #define EDAC_SR_CAN0_1E_OFFSET 0xA
+ #define EDAC_SR_CAN0_1E_MASK (0x01 << 0xA)
+ /* */
+ #define EDAC_SR_CAN0_2E_OFFSET 0xB
+ #define EDAC_SR_CAN0_2E_MASK (0x01 << 0xB)
+ /* */
+ #define EDAC_SR_CAN1_1E_OFFSET 0xC
+ #define EDAC_SR_CAN1_1E_MASK (0x01 << 0xC)
+ /* */
+ #define EDAC_SR_CAN1_2E_OFFSET 0xD
+ #define EDAC_SR_CAN1_2E_MASK (0x01 << 0xD)
+
+/*Enables ECC interrupt on event*/
+#define EDAC_INTEN_CR_OFFSET 0x104
+ /* */
+ #define EDAC_INTEN_CR_MMC_1E_OFFSET 0x0
+ #define EDAC_INTEN_CR_MMC_1E_MASK (0x01 << 0x0)
+ /* */
+ #define EDAC_INTEN_CR_MMC_2E_OFFSET 0x1
+ #define EDAC_INTEN_CR_MMC_2E_MASK (0x01 << 0x1)
+ /* */
+ #define EDAC_INTEN_CR_DDRC_1E_OFFSET 0x2
+ #define EDAC_INTEN_CR_DDRC_1E_MASK (0x01 << 0x2)
+ /* */
+ #define EDAC_INTEN_CR_DDRC_2E_OFFSET 0x3
+ #define EDAC_INTEN_CR_DDRC_2E_MASK (0x01 << 0x3)
+ /* */
+ #define EDAC_INTEN_CR_MAC0_1E_OFFSET 0x4
+ #define EDAC_INTEN_CR_MAC0_1E_MASK (0x01 << 0x4)
+ /* */
+ #define EDAC_INTEN_CR_MAC0_2E_OFFSET 0x5
+ #define EDAC_INTEN_CR_MAC0_2E_MASK (0x01 << 0x5)
+ /* */
+ #define EDAC_INTEN_CR_MAC1_1E_OFFSET 0x6
+ #define EDAC_INTEN_CR_MAC1_1E_MASK (0x01 << 0x6)
+ /* */
+ #define EDAC_INTEN_CR_MAC1_2E_OFFSET 0x7
+ #define EDAC_INTEN_CR_MAC1_2E_MASK (0x01 << 0x7)
+ /* */
+ #define EDAC_INTEN_CR_USB_1E_OFFSET 0x8
+ #define EDAC_INTEN_CR_USB_1E_MASK (0x01 << 0x8)
+ /* */
+ #define EDAC_INTEN_CR_USB_2E_OFFSET 0x9
+ #define EDAC_INTEN_CR_USB_2E_MASK (0x01 << 0x9)
+ /* */
+ #define EDAC_INTEN_CR_CAN0_1E_OFFSET 0xA
+ #define EDAC_INTEN_CR_CAN0_1E_MASK (0x01 << 0xA)
+ /* */
+ #define EDAC_INTEN_CR_CAN0_2E_OFFSET 0xB
+ #define EDAC_INTEN_CR_CAN0_2E_MASK (0x01 << 0xB)
+ /* */
+ #define EDAC_INTEN_CR_CAN1_1E_OFFSET 0xC
+ #define EDAC_INTEN_CR_CAN1_1E_MASK (0x01 << 0xC)
+ /* */
+ #define EDAC_INTEN_CR_CAN1_2E_OFFSET 0xD
+ #define EDAC_INTEN_CR_CAN1_2E_MASK (0x01 << 0xD)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_MMC_OFFSET 0x108
+ /* */
+ #define EDAC_CNT_MMC_COUNT_OFFSET 0x0
+ #define EDAC_CNT_MMC_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_DDRC_OFFSET 0x10C
+ /* */
+ #define EDAC_CNT_DDRC_COUNT_OFFSET 0x0
+ #define EDAC_CNT_DDRC_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_MAC0_OFFSET 0x110
+ /* */
+ #define EDAC_CNT_MAC0_COUNT_OFFSET 0x0
+ #define EDAC_CNT_MAC0_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_MAC1_OFFSET 0x114
+ /* */
+ #define EDAC_CNT_MAC1_COUNT_OFFSET 0x0
+ #define EDAC_CNT_MAC1_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_USB_OFFSET 0x118
+ /* */
+ #define EDAC_CNT_USB_COUNT_OFFSET 0x0
+ #define EDAC_CNT_USB_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_CAN0_OFFSET 0x11C
+ /* */
+ #define EDAC_CNT_CAN0_COUNT_OFFSET 0x0
+ #define EDAC_CNT_CAN0_COUNT_MASK (0x3FF << 0x0)
+
+/*Count off single bit errors*/
+#define EDAC_CNT_CAN1_OFFSET 0x120
+ /* */
+ #define EDAC_CNT_CAN1_COUNT_OFFSET 0x0
+ #define EDAC_CNT_CAN1_COUNT_MASK (0x3FF << 0x0)
+
+/*"Will Corrupt write data to rams 1E corrupts bit 0 2E bits 1 and 2.Inject
+ s Errors into all RAMS in the block as long as the bits are set. Setting 1E
+ and 2E will inject a 3-bit error"*/
+#define EDAC_INJECT_CR_OFFSET 0x124
+ /* */
+ #define EDAC_INJECT_CR_MMC_1E_OFFSET 0x0
+ #define EDAC_INJECT_CR_MMC_1E_MASK (0x01 << 0x0)
+ /* */
+ #define EDAC_INJECT_CR_MMC_2E_OFFSET 0x1
+ #define EDAC_INJECT_CR_MMC_2E_MASK (0x01 << 0x1)
+ /* */
+ #define EDAC_INJECT_CR_DDRC_1E_OFFSET 0x2
+ #define EDAC_INJECT_CR_DDRC_1E_MASK (0x01 << 0x2)
+ /* */
+ #define EDAC_INJECT_CR_DDRC_2E_OFFSET 0x3
+ #define EDAC_INJECT_CR_DDRC_2E_MASK (0x01 << 0x3)
+ /* */
+ #define EDAC_INJECT_CR_MAC0_1E_OFFSET 0x4
+ #define EDAC_INJECT_CR_MAC0_1E_MASK (0x01 << 0x4)
+ /* */
+ #define EDAC_INJECT_CR_MAC0_2E_OFFSET 0x5
+ #define EDAC_INJECT_CR_MAC0_2E_MASK (0x01 << 0x5)
+ /* */
+ #define EDAC_INJECT_CR_MAC1_1E_OFFSET 0x6
+ #define EDAC_INJECT_CR_MAC1_1E_MASK (0x01 << 0x6)
+ /* */
+ #define EDAC_INJECT_CR_MAC1_2E_OFFSET 0x7
+ #define EDAC_INJECT_CR_MAC1_2E_MASK (0x01 << 0x7)
+ /* */
+ #define EDAC_INJECT_CR_USB_1E_OFFSET 0x8
+ #define EDAC_INJECT_CR_USB_1E_MASK (0x01 << 0x8)
+ /* */
+ #define EDAC_INJECT_CR_USB_2E_OFFSET 0x9
+ #define EDAC_INJECT_CR_USB_2E_MASK (0x01 << 0x9)
+ /* */
+ #define EDAC_INJECT_CR_CAN0_1E_OFFSET 0xA
+ #define EDAC_INJECT_CR_CAN0_1E_MASK (0x01 << 0xA)
+ /* */
+ #define EDAC_INJECT_CR_CAN0_2E_OFFSET 0xB
+ #define EDAC_INJECT_CR_CAN0_2E_MASK (0x01 << 0xB)
+ /* */
+ #define EDAC_INJECT_CR_CAN1_1E_OFFSET 0xC
+ #define EDAC_INJECT_CR_CAN1_1E_MASK (0x01 << 0xC)
+ /* */
+ #define EDAC_INJECT_CR_CAN1_2E_OFFSET 0xD
+ #define EDAC_INJECT_CR_CAN1_2E_MASK (0x01 << 0xD)
+
+/*Maintenance Interrupt Enable.*/
+#define MAINTENANCE_INTEN_CR_OFFSET 0x140
+ /* Enables interrupt on a PLL event PLL_STATUS_INTEN_CR should also be
+ set*/
+ #define MAINTENANCE_INTEN_CR_PLL_OFFSET 0x0
+ #define MAINTENANCE_INTEN_CR_PLL_MASK (0x01 << 0x0)
+ /* Enables interrupt on a MPU access violation */
+ #define MAINTENANCE_INTEN_CR_MPU_OFFSET 0x1
+ #define MAINTENANCE_INTEN_CR_MPU_MASK (0x01 << 0x1)
+ /* Enables interrupt on a AXI switch decode error*/
+ #define MAINTENANCE_INTEN_CR_DECODE_OFFSET 0x2
+ #define MAINTENANCE_INTEN_CR_DECODE_MASK (0x01 << 0x2)
+ /* Enables interrupt as lp_state goes high*/
+ #define MAINTENANCE_INTEN_CR_LP_STATE_ENTER_OFFSET 0x3
+ #define MAINTENANCE_INTEN_CR_LP_STATE_ENTER_MASK (0x01 << 0x3)
+ /* Enables interrupt as lp_state goes low*/
+ #define MAINTENANCE_INTEN_CR_LP_STATE_EXIT_OFFSET 0x4
+ #define MAINTENANCE_INTEN_CR_LP_STATE_EXIT_MASK (0x01 << 0x4)
+ /* Enables interrupt as flash_freeze goes high*/
+ #define MAINTENANCE_INTEN_CR_FF_START_OFFSET 0x5
+ #define MAINTENANCE_INTEN_CR_FF_START_MASK (0x01 << 0x5)
+ /* Enables interrupt as flash_freeze goes low*/
+ #define MAINTENANCE_INTEN_CR_FF_END_OFFSET 0x6
+ #define MAINTENANCE_INTEN_CR_FF_END_MASK (0x01 << 0x6)
+ /* Enables interrupt when FPGA turned on*/
+ #define MAINTENANCE_INTEN_CR_FPGA_ON_OFFSET 0x7
+ #define MAINTENANCE_INTEN_CR_FPGA_ON_MASK (0x01 << 0x7)
+ /* Enables interrupt when FPGA turned off*/
+ #define MAINTENANCE_INTEN_CR_FPGA_OFF_OFFSET 0x8
+ #define MAINTENANCE_INTEN_CR_FPGA_OFF_MASK (0x01 << 0x8)
+ /* Enables interrupt on SCB error*/
+ #define MAINTENANCE_INTEN_CR_SCB_ERROR_OFFSET 0x9
+ #define MAINTENANCE_INTEN_CR_SCB_ERROR_MASK (0x01 << 0x9)
+ /* Enables interrupt on SCB failure*/
+ #define MAINTENANCE_INTEN_CR_SCB_FAULT_OFFSET 0xA
+ #define MAINTENANCE_INTEN_CR_SCB_FAULT_MASK (0x01 << 0xA)
+ /* Enables interrupt on Mesh violation detection */
+ #define MAINTENANCE_INTEN_CR_MESH_ERROR_OFFSET 0xB
+ #define MAINTENANCE_INTEN_CR_MESH_ERROR_MASK (0x01 << 0xB)
+ /* Enables interrupt on bank2 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_ON_OFFSET 0xC
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_ON_MASK (0x01 << 0xC)
+ /* Enables interrupt on bank4 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_ON_OFFSET 0xD
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_ON_MASK (0x01 << 0xD)
+ /* Enables interrupt on bank5 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_ON_OFFSET 0xE
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_ON_MASK (0x01 << 0xE)
+ /* Enables interrupt on bank6 powered on*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_ON_OFFSET 0xF
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_ON_MASK (0x01 << 0xF)
+ /* Enables interrupt on bank2 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_OFF_OFFSET 0x10
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B2_OFF_MASK (0x01 << 0x10)
+ /* Enables interrupt on bank4 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_OFF_OFFSET 0x11
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B4_OFF_MASK (0x01 << 0x11)
+ /* Enables interrupt on bank5 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_OFF_OFFSET 0x12
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B5_OFF_MASK (0x01 << 0x12)
+ /* Enables interrupt on bank6 powered off*/
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_OFF_OFFSET 0x13
+ #define MAINTENANCE_INTEN_CR_IO_BANK_B6_OFF_MASK (0x01 << 0x13)
+ /* Enables interrupt on a DLL event DLL_STATUS_INTEN_CR should also be
+ set*/
+ #define MAINTENANCE_INTEN_CR_DLL_OFFSET 0x14
+ #define MAINTENANCE_INTEN_CR_DLL_MASK (0x01 << 0x14)
+
+/*PLL Status interrupt enables*/
+#define PLL_STATUS_INTEN_CR_OFFSET 0x144
+ /* Enables interrupt on CPU PLL locking*/
+ #define PLL_STATUS_INTEN_CR_CPU_LOCK_OFFSET 0x0
+ #define PLL_STATUS_INTEN_CR_CPU_LOCK_MASK (0x01 << 0x0)
+ /* Enables interrupt on DFT PLL locking*/
+ #define PLL_STATUS_INTEN_CR_DFI_LOCK_OFFSET 0x1
+ #define PLL_STATUS_INTEN_CR_DFI_LOCK_MASK (0x01 << 0x1)
+ /* Enables interrupt on SGMII PLL locking*/
+ #define PLL_STATUS_INTEN_CR_SGMII_LOCK_OFFSET 0x2
+ #define PLL_STATUS_INTEN_CR_SGMII_LOCK_MASK (0x01 << 0x2)
+ /* Enables interrupt on CPU PLL unlocking*/
+ #define PLL_STATUS_INTEN_CR_CPU_UNLOCK_OFFSET 0x4
+ #define PLL_STATUS_INTEN_CR_CPU_UNLOCK_MASK (0x01 << 0x4)
+ /* Enables interrupt on DFT PLL unlocking*/
+ #define PLL_STATUS_INTEN_CR_DFI_UNLOCK_OFFSET 0x5
+ #define PLL_STATUS_INTEN_CR_DFI_UNLOCK_MASK (0x01 << 0x5)
+ /* Enables interrupt on SGMII PLL unlocking*/
+ #define PLL_STATUS_INTEN_CR_SGMII_UNLOCK_OFFSET 0x6
+ #define PLL_STATUS_INTEN_CR_SGMII_UNLOCK_MASK (0x01 << 0x6)
+
+/*Maintenance interrupt indicates fault and status events.*/
+#define MAINTENANCE_INT_SR_OFFSET 0x148
+ /* Indicates that one off the PLLs whent into the lock or unlock state.
+ Cleared via PLL status register*/
+ #define MAINTENANCE_INT_SR_PLL_OFFSET 0x0
+ #define MAINTENANCE_INT_SR_PLL_MASK (0x01 << 0x0)
+ /* Indicates that one off the MPUS signaled a MPU violation. Cleared vi
+ a MPU Violation Register*/
+ #define MAINTENANCE_INT_SR_MPU_OFFSET 0x1
+ #define MAINTENANCE_INT_SR_MPU_MASK (0x01 << 0x1)
+ /* Indicates that the AXI switch detected an illegal address. Cleared w
+ hen SREG.SW_FAIL.ADDR1_CR_FAILED is cleared.*/
+ #define MAINTENANCE_INT_SR_DECODE_OFFSET 0x2
+ #define MAINTENANCE_INT_SR_DECODE_MASK (0x01 << 0x2)
+ /* Indicates the device has entered the lower power state cleared by wr
+ iting '1'*/
+ #define MAINTENANCE_INT_SR_LP_STATE_ENTER_OFFSET 0x3
+ #define MAINTENANCE_INT_SR_LP_STATE_ENTER_MASK (0x01 << 0x3)
+ /* Indicates the device has exited the lower power state cleared by wri
+ ting '1'*/
+ #define MAINTENANCE_INT_SR_LP_STATE_EXIT_OFFSET 0x4
+ #define MAINTENANCE_INT_SR_LP_STATE_EXIT_MASK (0x01 << 0x4)
+ /* Indicates the device has entered the flash freezer state cleared by
+ writing '1'*/
+ #define MAINTENANCE_INT_SR_FF_START_OFFSET 0x5
+ #define MAINTENANCE_INT_SR_FF_START_MASK (0x01 << 0x5)
+ /* Indicates the device has exited the flash freezer state cleared by w
+ riting '1'*/
+ #define MAINTENANCE_INT_SR_FF_END_OFFSET 0x6
+ #define MAINTENANCE_INT_SR_FF_END_MASK (0x01 << 0x6)
+ /* Indicates that the FPGA array has been turned on cleared by writing
+ a '1'*/
+ #define MAINTENANCE_INT_SR_FPGA_ON_OFFSET 0x7
+ #define MAINTENANCE_INT_SR_FPGA_ON_MASK (0x01 << 0x7)
+ /* Indicates that the FPGA array has been turned off cleared by writing
+ a '1'*/
+ #define MAINTENANCE_INT_SR_FPGA_OFF_OFFSET 0x8
+ #define MAINTENANCE_INT_SR_FPGA_OFF_MASK (0x01 << 0x8)
+ /* Indicates that the SCB slave reported an error cleared via SCB contr
+ oller*/
+ #define MAINTENANCE_INT_SR_SCB_ERROR_OFFSET 0x9
+ #define MAINTENANCE_INT_SR_SCB_ERROR_MASK (0x01 << 0x9)
+ /* Indicates that the SCB bus fault occurred cleared via SCB controller
+ */
+ #define MAINTENANCE_INT_SR_SCB_FAULT_OFFSET 0xA
+ #define MAINTENANCE_INT_SR_SCB_FAULT_MASK (0x01 << 0xA)
+ /* Indicates that the mesh over the Crypto triggered cleared via Mesh s
+ ystem error*/
+ #define MAINTENANCE_INT_SR_MESH_ERROR_OFFSET 0xB
+ #define MAINTENANCE_INT_SR_MESH_ERROR_MASK (0x01 << 0xB)
+ /* Indicates that IO bank 2 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_ON_OFFSET 0xC
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_ON_MASK (0x01 << 0xC)
+ /* Indicates that IO bank 4 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_ON_OFFSET 0xD
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_ON_MASK (0x01 << 0xD)
+ /* Indicates that IO bank 5 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_ON_OFFSET 0xE
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_ON_MASK (0x01 << 0xE)
+ /* Indicates that IO bank 6 has turned on cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_ON_OFFSET 0xF
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_ON_MASK (0x01 << 0xF)
+ /* Indicates that IO bank 2 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_OFF_OFFSET 0x10
+ #define MAINTENANCE_INT_SR_IO_BANK_B2_OFF_MASK (0x01 << 0x10)
+ /* Indicates that IO bank 4 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_OFF_OFFSET 0x11
+ #define MAINTENANCE_INT_SR_IO_BANK_B4_OFF_MASK (0x01 << 0x11)
+ /* Indicates that IO bank 5 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_OFF_OFFSET 0x12
+ #define MAINTENANCE_INT_SR_IO_BANK_B5_OFF_MASK (0x01 << 0x12)
+ /* Indicates that one off the DLLs when into the lock or unlock state.
+ Cleared via DLL status register*/
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_OFF_OFFSET 0x13
+ #define MAINTENANCE_INT_SR_IO_BANK_B6_OFF_MASK (0x01 << 0x13)
+ /* Indicates that IO bank 6 has turned off cleared by writing a '1'*/
+ #define MAINTENANCE_INT_SR_DLL_OFFSET 0x14
+ #define MAINTENANCE_INT_SR_DLL_MASK (0x01 << 0x14)
+
+/*PLL interrupt register*/
+#define PLL_STATUS_SR_OFFSET 0x14C
+ /* Indicates that the CPU PLL has locked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_CPU_LOCK_OFFSET 0x0
+ #define PLL_STATUS_SR_CPU_LOCK_MASK (0x01 << 0x0)
+ /* Indicates that the DFI PLL has locked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_DFI_LOCK_OFFSET 0x1
+ #define PLL_STATUS_SR_DFI_LOCK_MASK (0x01 << 0x1)
+ /* Indicates that the SGMII PLL has locked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_SGMII_LOCK_OFFSET 0x2
+ #define PLL_STATUS_SR_SGMII_LOCK_MASK (0x01 << 0x2)
+ /* Indicates that the CPU PLL has unlocked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_CPU_UNLOCK_OFFSET 0x4
+ #define PLL_STATUS_SR_CPU_UNLOCK_MASK (0x01 << 0x4)
+ /* Indicates that the DFI PLL has unlocked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_DFI_UNLOCK_OFFSET 0x5
+ #define PLL_STATUS_SR_DFI_UNLOCK_MASK (0x01 << 0x5)
+ /* Indicates that the SGMII PLL has unlocked cleared by writing a '1'*/
+ #define PLL_STATUS_SR_SGMII_UNLOCK_OFFSET 0x6
+ #define PLL_STATUS_SR_SGMII_UNLOCK_MASK (0x01 << 0x6)
+ /* Current state off CPU PLL locked signal*/
+ #define PLL_STATUS_SR_CPU_LOCK_NOW_OFFSET 0x8
+ #define PLL_STATUS_SR_CPU_LOCK_NOW_MASK (0x01 << 0x8)
+ /* Current state off DFI PLL locked signal*/
+ #define PLL_STATUS_SR_DFI_LOCK_NOW_OFFSET 0x9
+ #define PLL_STATUS_SR_DFI_LOCK_NOW_MASK (0x01 << 0x9)
+ /* Current state off SGMII PLL locked signal*/
+ #define PLL_STATUS_SR_SGMII_LOCK_NOW_OFFSET 0xA
+ #define PLL_STATUS_SR_SGMII_LOCK_NOW_MASK (0x01 << 0xA)
+
+/*Enable to CFM Timer */
+#define CFM_TIMER_CR_OFFSET 0x150
+ /* When set and the CFM channel is in timer mode and CFM channel is set
+ to 2 (Group C) this register allows the timet to count. Allows software to
+ start and stop the timers.*/
+ #define CFM_TIMER_CR_ENABLE_OFFSET 0x0
+ #define CFM_TIMER_CR_ENABLE_MASK (0x1F << 0x0)
+
+/*Miscellaneous Register*/
+#define MISC_SR_OFFSET 0x154
+ /* Indicates that Interrupt from the G5C MSS SCB SPI controller is acti
+ ve*/
+ #define MISC_SR_CONT_SPI_INTERRUPT_OFFSET 0x0
+ #define MISC_SR_CONT_SPI_INTERRUPT_MASK (0x01 << 0x0)
+ /* Indicates that the user voltage or temperature detectors are signali
+ ng an alarm condition.*/
+ #define MISC_SR_VOLT_TEMP_ALARM_OFFSET 0x1
+ #define MISC_SR_VOLT_TEMP_ALARM_MASK (0x01 << 0x1)
+
+/*DLL Interrupt enables*/
+#define DLL_STATUS_CR_OFFSET 0x158
+ /* Enables the DLL0 lock interrupt*/
+ #define DLL_STATUS_CR_FIC0_LOCK_OFFSET 0x0
+ #define DLL_STATUS_CR_FIC0_LOCK_MASK (0x01 << 0x0)
+ /* Enables the DLL1 lock interrupt*/
+ #define DLL_STATUS_CR_FIC1_LOCK_OFFSET 0x1
+ #define DLL_STATUS_CR_FIC1_LOCK_MASK (0x01 << 0x1)
+ /* Enables the DLL2 lock interrupt*/
+ #define DLL_STATUS_CR_FIC2_LOCK_OFFSET 0x2
+ #define DLL_STATUS_CR_FIC2_LOCK_MASK (0x01 << 0x2)
+ /* Enables the DLL3 lock interrupt*/
+ #define DLL_STATUS_CR_FIC3_LOCK_OFFSET 0x4
+ #define DLL_STATUS_CR_FIC3_LOCK_MASK (0x01 << 0x4)
+ /* Enables the DLL4 (Crypto) lock interrupt*/
+ #define DLL_STATUS_CR_FIC4_LOCK_OFFSET 0x5
+ #define DLL_STATUS_CR_FIC4_LOCK_MASK (0x01 << 0x5)
+ /* Enables the DLL0 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC0_UNLOCK_OFFSET 0x8
+ #define DLL_STATUS_CR_FIC0_UNLOCK_MASK (0x01 << 0x8)
+ /* Enables the DLL1 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC1_UNLOCK_OFFSET 0x9
+ #define DLL_STATUS_CR_FIC1_UNLOCK_MASK (0x01 << 0x9)
+ /* Enables the DLL2 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC2_UNLOCK_OFFSET 0xA
+ #define DLL_STATUS_CR_FIC2_UNLOCK_MASK (0x01 << 0xA)
+ /* Enables the DLL3 unlock interrupt*/
+ #define DLL_STATUS_CR_FIC3_UNLOCK_OFFSET 0xB
+ #define DLL_STATUS_CR_FIC3_UNLOCK_MASK (0x01 << 0xB)
+ /* Enables the DLL4 (crypto) unlock interrupt*/
+ #define DLL_STATUS_CR_FIC4_UNLOCK_OFFSET 0xC
+ #define DLL_STATUS_CR_FIC4_UNLOCK_MASK (0x01 << 0xC)
+
+/*DLL interrupt register*/
+#define DLL_STATUS_SR_OFFSET 0x15C
+ /* Indicates that the FIC0 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC0_LOCK_OFFSET 0x0
+ #define DLL_STATUS_SR_FIC0_LOCK_MASK (0x01 << 0x0)
+ /* Indicates that the FIC1 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC1_LOCK_OFFSET 0x1
+ #define DLL_STATUS_SR_FIC1_LOCK_MASK (0x01 << 0x1)
+ /* Indicates that the FIC2 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC2_LOCK_OFFSET 0x2
+ #define DLL_STATUS_SR_FIC2_LOCK_MASK (0x01 << 0x2)
+ /* Indicates that the FIC3 DLL has locked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC3_LOCK_OFFSET 0x4
+ #define DLL_STATUS_SR_FIC3_LOCK_MASK (0x01 << 0x4)
+ /* Indicates that the FIC4 (Crypto) DLL has locked cleared by writing a
+ '1'*/
+ #define DLL_STATUS_SR_FIC4_LOCK_OFFSET 0x5
+ #define DLL_STATUS_SR_FIC4_LOCK_MASK (0x01 << 0x5)
+ /* Indicates that the FIC0 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC0_UNLOCK_OFFSET 0x8
+ #define DLL_STATUS_SR_FIC0_UNLOCK_MASK (0x01 << 0x8)
+ /* Indicates that the FIC1 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC1_UNLOCK_OFFSET 0x9
+ #define DLL_STATUS_SR_FIC1_UNLOCK_MASK (0x01 << 0x9)
+ /* Indicates that the FIC2 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC2_UNLOCK_OFFSET 0xA
+ #define DLL_STATUS_SR_FIC2_UNLOCK_MASK (0x01 << 0xA)
+ /* Indicates that the FIC3 DLL has unlocked cleared by writing a '1'*/
+ #define DLL_STATUS_SR_FIC3_UNLOCK_OFFSET 0xB
+ #define DLL_STATUS_SR_FIC3_UNLOCK_MASK (0x01 << 0xB)
+ /* Indicates that the FIC4 (Crypto) DLL has unlocked cleared by writing
+ a '1'*/
+ #define DLL_STATUS_SR_FIC4_UNLOCK_OFFSET 0xC
+ #define DLL_STATUS_SR_FIC4_UNLOCK_MASK (0x01 << 0xC)
+ /* Current state off FIC0 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC0_LOCK_NOW_OFFSET 0x10
+ #define DLL_STATUS_SR_FIC0_LOCK_NOW_MASK (0x01 << 0x10)
+ /* Current state off FIC1 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC1_LOCK_NOW_OFFSET 0x11
+ #define DLL_STATUS_SR_FIC1_LOCK_NOW_MASK (0x01 << 0x11)
+ /* Current state off FIC2 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC2_LOCK_NOW_OFFSET 0x12
+ #define DLL_STATUS_SR_FIC2_LOCK_NOW_MASK (0x01 << 0x12)
+ /* Current state off FIC3 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC3_LOCK_NOW_OFFSET 0x13
+ #define DLL_STATUS_SR_FIC3_LOCK_NOW_MASK (0x01 << 0x13)
+ /* Current state off FIC4 DLL locked signal*/
+ #define DLL_STATUS_SR_FIC4_LOCK_NOW_OFFSET 0x14
+ #define DLL_STATUS_SR_FIC4_LOCK_NOW_MASK (0x01 << 0x14)
+
+/*Puts all the RAMS in that block into low leakage mode. RAM contents and Q
+ value preserved.*/
+#define RAM_LIGHTSLEEP_CR_OFFSET 0x168
+ /* */
+ #define RAM_LIGHTSLEEP_CR_CAN0_OFFSET 0x0
+ #define RAM_LIGHTSLEEP_CR_CAN0_MASK (0x01 << 0x0)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_CAN1_OFFSET 0x1
+ #define RAM_LIGHTSLEEP_CR_CAN1_MASK (0x01 << 0x1)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_USB_OFFSET 0x2
+ #define RAM_LIGHTSLEEP_CR_USB_MASK (0x01 << 0x2)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_GEM0_OFFSET 0x3
+ #define RAM_LIGHTSLEEP_CR_GEM0_MASK (0x01 << 0x3)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_GEM1_OFFSET 0x4
+ #define RAM_LIGHTSLEEP_CR_GEM1_MASK (0x01 << 0x4)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_MMC_OFFSET 0x5
+ #define RAM_LIGHTSLEEP_CR_MMC_MASK (0x01 << 0x5)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_ATHENA_OFFSET 0x6
+ #define RAM_LIGHTSLEEP_CR_ATHENA_MASK (0x01 << 0x6)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_DDRC_OFFSET 0x7
+ #define RAM_LIGHTSLEEP_CR_DDRC_MASK (0x01 << 0x7)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_E51_OFFSET 0x8
+ #define RAM_LIGHTSLEEP_CR_E51_MASK (0x01 << 0x8)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_1_OFFSET 0x9
+ #define RAM_LIGHTSLEEP_CR_U54_1_MASK (0x01 << 0x9)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_2_OFFSET 0xA
+ #define RAM_LIGHTSLEEP_CR_U54_2_MASK (0x01 << 0xA)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_3_OFFSET 0xB
+ #define RAM_LIGHTSLEEP_CR_U54_3_MASK (0x01 << 0xB)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_U54_4_OFFSET 0xC
+ #define RAM_LIGHTSLEEP_CR_U54_4_MASK (0x01 << 0xC)
+ /* */
+ #define RAM_LIGHTSLEEP_CR_L2_OFFSET 0xD
+ #define RAM_LIGHTSLEEP_CR_L2_MASK (0x01 << 0xD)
+
+/*Puts all the RAMS in that block into deep sleep mode. RAM contents preser
+ ved. Powers down the periphery circuits.*/
+#define RAM_DEEPSLEEP_CR_OFFSET 0x16C
+ /* */
+ #define RAM_DEEPSLEEP_CR_CAN0_OFFSET 0x0
+ #define RAM_DEEPSLEEP_CR_CAN0_MASK (0x01 << 0x0)
+ /* */
+ #define RAM_DEEPSLEEP_CR_CAN1_OFFSET 0x1
+ #define RAM_DEEPSLEEP_CR_CAN1_MASK (0x01 << 0x1)
+ /* */
+ #define RAM_DEEPSLEEP_CR_USB_OFFSET 0x2
+ #define RAM_DEEPSLEEP_CR_USB_MASK (0x01 << 0x2)
+ /* */
+ #define RAM_DEEPSLEEP_CR_GEM0_OFFSET 0x3
+ #define RAM_DEEPSLEEP_CR_GEM0_MASK (0x01 << 0x3)
+ /* */
+ #define RAM_DEEPSLEEP_CR_GEM1_OFFSET 0x4
+ #define RAM_DEEPSLEEP_CR_GEM1_MASK (0x01 << 0x4)
+ /* */
+ #define RAM_DEEPSLEEP_CR_MMC_OFFSET 0x5
+ #define RAM_DEEPSLEEP_CR_MMC_MASK (0x01 << 0x5)
+ /* */
+ #define RAM_DEEPSLEEP_CR_ATHENA_OFFSET 0x6
+ #define RAM_DEEPSLEEP_CR_ATHENA_MASK (0x01 << 0x6)
+ /* */
+ #define RAM_DEEPSLEEP_CR_DDRC_OFFSET 0x7
+ #define RAM_DEEPSLEEP_CR_DDRC_MASK (0x01 << 0x7)
+ /* */
+ #define RAM_DEEPSLEEP_CR_E51_OFFSET 0x8
+ #define RAM_DEEPSLEEP_CR_E51_MASK (0x01 << 0x8)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_1_OFFSET 0x9
+ #define RAM_DEEPSLEEP_CR_U54_1_MASK (0x01 << 0x9)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_2_OFFSET 0xA
+ #define RAM_DEEPSLEEP_CR_U54_2_MASK (0x01 << 0xA)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_3_OFFSET 0xB
+ #define RAM_DEEPSLEEP_CR_U54_3_MASK (0x01 << 0xB)
+ /* */
+ #define RAM_DEEPSLEEP_CR_U54_4_OFFSET 0xC
+ #define RAM_DEEPSLEEP_CR_U54_4_MASK (0x01 << 0xC)
+ /* */
+ #define RAM_DEEPSLEEP_CR_L2_OFFSET 0xD
+ #define RAM_DEEPSLEEP_CR_L2_MASK (0x01 << 0xD)
+
+/*Puts all the RAMS in that block into shut down mode. RAM contents not pre
+ served. Powers down the RAM and periphery circuits.*/
+#define RAM_SHUTDOWN_CR_OFFSET 0x170
+ /* */
+ #define RAM_SHUTDOWN_CR_CAN0_OFFSET 0x0
+ #define RAM_SHUTDOWN_CR_CAN0_MASK (0x01 << 0x0)
+ /* */
+ #define RAM_SHUTDOWN_CR_CAN1_OFFSET 0x1
+ #define RAM_SHUTDOWN_CR_CAN1_MASK (0x01 << 0x1)
+ /* */
+ #define RAM_SHUTDOWN_CR_USB_OFFSET 0x2
+ #define RAM_SHUTDOWN_CR_USB_MASK (0x01 << 0x2)
+ /* */
+ #define RAM_SHUTDOWN_CR_GEM0_OFFSET 0x3
+ #define RAM_SHUTDOWN_CR_GEM0_MASK (0x01 << 0x3)
+ /* */
+ #define RAM_SHUTDOWN_CR_GEM1_OFFSET 0x4
+ #define RAM_SHUTDOWN_CR_GEM1_MASK (0x01 << 0x4)
+ /* */
+ #define RAM_SHUTDOWN_CR_MMC_OFFSET 0x5
+ #define RAM_SHUTDOWN_CR_MMC_MASK (0x01 << 0x5)
+ /* */
+ #define RAM_SHUTDOWN_CR_ATHENA_OFFSET 0x6
+ #define RAM_SHUTDOWN_CR_ATHENA_MASK (0x01 << 0x6)
+ /* */
+ #define RAM_SHUTDOWN_CR_DDRC_OFFSET 0x7
+ #define RAM_SHUTDOWN_CR_DDRC_MASK (0x01 << 0x7)
+ /* */
+ #define RAM_SHUTDOWN_CR_E51_OFFSET 0x8
+ #define RAM_SHUTDOWN_CR_E51_MASK (0x01 << 0x8)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_1_OFFSET 0x9
+ #define RAM_SHUTDOWN_CR_U54_1_MASK (0x01 << 0x9)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_2_OFFSET 0xA
+ #define RAM_SHUTDOWN_CR_U54_2_MASK (0x01 << 0xA)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_3_OFFSET 0xB
+ #define RAM_SHUTDOWN_CR_U54_3_MASK (0x01 << 0xB)
+ /* */
+ #define RAM_SHUTDOWN_CR_U54_4_OFFSET 0xC
+ #define RAM_SHUTDOWN_CR_U54_4_MASK (0x01 << 0xC)
+ /* */
+ #define RAM_SHUTDOWN_CR_L2_OFFSET 0xD
+ #define RAM_SHUTDOWN_CR_L2_MASK (0x01 << 0xD)
+
+/*Allows each bank of the L2 Cache to be powered down ORed with global shut
+ down */
+#define L2_SHUTDOWN_CR_OFFSET 0x174
+ /* */
+ #define L2_SHUTDOWN_CR_L2_RAMS_OFFSET 0x0
+ #define L2_SHUTDOWN_CR_L2_RAMS_MASK (0x0F << 0x0)
+
+/*Selects whether the peripheral is connected to the Fabric or IOMUX struct
+ ure.*/
+#define IOMUX0_CR_OFFSET 0x200
+ /* */
+ #define IOMUX0_CR_SPI0_FABRIC_OFFSET 0x0
+ #define IOMUX0_CR_SPI0_FABRIC_MASK (0x01 << 0x0)
+ /* */
+ #define IOMUX0_CR_SPI1_FABRIC_OFFSET 0x1
+ #define IOMUX0_CR_SPI1_FABRIC_MASK (0x01 << 0x1)
+ /* */
+ #define IOMUX0_CR_I2C0_FABRIC_OFFSET 0x2
+ #define IOMUX0_CR_I2C0_FABRIC_MASK (0x01 << 0x2)
+ /* */
+ #define IOMUX0_CR_I2C1_FABRIC_OFFSET 0x3
+ #define IOMUX0_CR_I2C1_FABRIC_MASK (0x01 << 0x3)
+ /* */
+ #define IOMUX0_CR_CAN0_FABRIC_OFFSET 0x4
+ #define IOMUX0_CR_CAN0_FABRIC_MASK (0x01 << 0x4)
+ /* */
+ #define IOMUX0_CR_CAN1_FABRIC_OFFSET 0x5
+ #define IOMUX0_CR_CAN1_FABRIC_MASK (0x01 << 0x5)
+ /* */
+ #define IOMUX0_CR_QSPI_FABRIC_OFFSET 0x6
+ #define IOMUX0_CR_QSPI_FABRIC_MASK (0x01 << 0x6)
+ /* */
+ #define IOMUX0_CR_MMUART0_FABRIC_OFFSET 0x7
+ #define IOMUX0_CR_MMUART0_FABRIC_MASK (0x01 << 0x7)
+ /* */
+ #define IOMUX0_CR_MMUART1_FABRIC_OFFSET 0x8
+ #define IOMUX0_CR_MMUART1_FABRIC_MASK (0x01 << 0x8)
+ /* */
+ #define IOMUX0_CR_MMUART2_FABRIC_OFFSET 0x9
+ #define IOMUX0_CR_MMUART2_FABRIC_MASK (0x01 << 0x9)
+ /* */
+ #define IOMUX0_CR_MMUART3_FABRIC_OFFSET 0xA
+ #define IOMUX0_CR_MMUART3_FABRIC_MASK (0x01 << 0xA)
+ /* */
+ #define IOMUX0_CR_MMUART4_FABRIC_OFFSET 0xB
+ #define IOMUX0_CR_MMUART4_FABRIC_MASK (0x01 << 0xB)
+ /* */
+ #define IOMUX0_CR_MDIO0_FABRIC_OFFSET 0xC
+ #define IOMUX0_CR_MDIO0_FABRIC_MASK (0x01 << 0xC)
+ /* */
+ #define IOMUX0_CR_MDIO1_FABRIC_OFFSET 0xD
+ #define IOMUX0_CR_MDIO1_FABRIC_MASK (0x01 << 0xD)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX1_CR_OFFSET 0x204
+ /* */
+ #define IOMUX1_CR_PAD0_OFFSET 0x0
+ #define IOMUX1_CR_PAD0_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX1_CR_PAD1_OFFSET 0x4
+ #define IOMUX1_CR_PAD1_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX1_CR_PAD2_OFFSET 0x8
+ #define IOMUX1_CR_PAD2_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX1_CR_PAD3_OFFSET 0xC
+ #define IOMUX1_CR_PAD3_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX1_CR_PAD4_OFFSET 0x10
+ #define IOMUX1_CR_PAD4_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX1_CR_PAD5_OFFSET 0x14
+ #define IOMUX1_CR_PAD5_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX1_CR_PAD6_OFFSET 0x18
+ #define IOMUX1_CR_PAD6_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX1_CR_PAD7_OFFSET 0x1C
+ #define IOMUX1_CR_PAD7_MASK (0x0F << 0x1C)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX2_CR_OFFSET 0x208
+ /* */
+ #define IOMUX2_CR_PAD8_OFFSET 0x0
+ #define IOMUX2_CR_PAD8_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX2_CR_PAD9_OFFSET 0x4
+ #define IOMUX2_CR_PAD9_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX2_CR_PAD10_OFFSET 0x8
+ #define IOMUX2_CR_PAD10_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX2_CR_PAD11_OFFSET 0xC
+ #define IOMUX2_CR_PAD11_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX2_CR_PAD12_OFFSET 0x10
+ #define IOMUX2_CR_PAD12_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX2_CR_PAD13_OFFSET 0x14
+ #define IOMUX2_CR_PAD13_MASK (0x0F << 0x14)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX3_CR_OFFSET 0x20C
+ /* */
+ #define IOMUX3_CR_PAD14_OFFSET 0x0
+ #define IOMUX3_CR_PAD14_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX3_CR_PAD15_OFFSET 0x4
+ #define IOMUX3_CR_PAD15_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX3_CR_PAD16_OFFSET 0x8
+ #define IOMUX3_CR_PAD16_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX3_CR_PAD17_OFFSET 0xC
+ #define IOMUX3_CR_PAD17_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX3_CR_PAD18_OFFSET 0x10
+ #define IOMUX3_CR_PAD18_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX3_CR_PAD19_OFFSET 0x14
+ #define IOMUX3_CR_PAD19_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX3_CR_PAD20_OFFSET 0x18
+ #define IOMUX3_CR_PAD20_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX3_CR_PAD21_OFFSET 0x1C
+ #define IOMUX3_CR_PAD21_MASK (0x0F << 0x1C)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX4_CR_OFFSET 0x210
+ /* */
+ #define IOMUX4_CR_PAD22_OFFSET 0x0
+ #define IOMUX4_CR_PAD22_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX4_CR_PAD23_OFFSET 0x4
+ #define IOMUX4_CR_PAD23_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX4_CR_PAD24_OFFSET 0x8
+ #define IOMUX4_CR_PAD24_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX4_CR_PAD25_OFFSET 0xC
+ #define IOMUX4_CR_PAD25_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX4_CR_PAD26_OFFSET 0x10
+ #define IOMUX4_CR_PAD26_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX4_CR_PAD27_OFFSET 0x14
+ #define IOMUX4_CR_PAD27_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX4_CR_PAD28_OFFSET 0x18
+ #define IOMUX4_CR_PAD28_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX4_CR_PAD29_OFFSET 0x1C
+ #define IOMUX4_CR_PAD29_MASK (0x0F << 0x1C)
+
+/*Configures the IO Mux structure for each IO pad. See the MSS MAS specific
+ ation for for description.*/
+#define IOMUX5_CR_OFFSET 0x214
+ /* */
+ #define IOMUX5_CR_PAD30_OFFSET 0x0
+ #define IOMUX5_CR_PAD30_MASK (0x0F << 0x0)
+ /* */
+ #define IOMUX5_CR_PAD31_OFFSET 0x4
+ #define IOMUX5_CR_PAD31_MASK (0x0F << 0x4)
+ /* */
+ #define IOMUX5_CR_PAD32_OFFSET 0x8
+ #define IOMUX5_CR_PAD32_MASK (0x0F << 0x8)
+ /* */
+ #define IOMUX5_CR_PAD33_OFFSET 0xC
+ #define IOMUX5_CR_PAD33_MASK (0x0F << 0xC)
+ /* */
+ #define IOMUX5_CR_PAD34_OFFSET 0x10
+ #define IOMUX5_CR_PAD34_MASK (0x0F << 0x10)
+ /* */
+ #define IOMUX5_CR_PAD35_OFFSET 0x14
+ #define IOMUX5_CR_PAD35_MASK (0x0F << 0x14)
+ /* */
+ #define IOMUX5_CR_PAD36_OFFSET 0x18
+ #define IOMUX5_CR_PAD36_MASK (0x0F << 0x18)
+ /* */
+ #define IOMUX5_CR_PAD37_OFFSET 0x1C
+ #define IOMUX5_CR_PAD37_MASK (0x0F << 0x1C)
+
+/*Sets whether the MMC/SD Voltage select lines are inverted on entry to the
+ IOMUX structure*/
+#define IOMUX6_CR_OFFSET 0x218
+ /* */
+ #define IOMUX6_CR_VLT_SEL_OFFSET 0x0
+ #define IOMUX6_CR_VLT_SEL_MASK (0x01 << 0x0)
+ /* */
+ #define IOMUX6_CR_VLT_EN_OFFSET 0x1
+ #define IOMUX6_CR_VLT_EN_MASK (0x01 << 0x1)
+ /* */
+ #define IOMUX6_CR_VLT_CMD_DIR_OFFSET 0x2
+ #define IOMUX6_CR_VLT_CMD_DIR_MASK (0x01 << 0x2)
+ /* */
+ #define IOMUX6_CR_VLT_DIR_0_OFFSET 0x3
+ #define IOMUX6_CR_VLT_DIR_0_MASK (0x01 << 0x3)
+ /* */
+ #define IOMUX6_CR_VLT_DIR_1_3_OFFSET 0x4
+ #define IOMUX6_CR_VLT_DIR_1_3_MASK (0x01 << 0x4)
+ /* */
+ #define IOMUX6_CR_SD_LED_OFFSET 0x5
+ #define IOMUX6_CR_SD_LED_MASK (0x01 << 0x5)
+ /* */
+ #define IOMUX6_CR_SD_VOLT_0_OFFSET 0x6
+ #define IOMUX6_CR_SD_VOLT_0_MASK (0x01 << 0x6)
+ /* */
+ #define IOMUX6_CR_SD_VOLT_1_OFFSET 0x7
+ #define IOMUX6_CR_SD_VOLT_1_MASK (0x01 << 0x7)
+ /* */
+ #define IOMUX6_CR_SD_VOLT_2_OFFSET 0x8
+ #define IOMUX6_CR_SD_VOLT_2_MASK (0x01 << 0x8)
+
+/*Configures the MSSIO block*/
+#define MSSIO_BANK4_CFG_CR_OFFSET 0x230
+ /* Sets the PCODE value*/
+ #define MSSIO_BANK4_CFG_CR_BANK_PCODE_OFFSET 0x0
+ #define MSSIO_BANK4_CFG_CR_BANK_PCODE_MASK (0x3F << 0x0)
+ /* Sets the NCODE value*/
+ #define MSSIO_BANK4_CFG_CR_BANK_NCODE_OFFSET 0x6
+ #define MSSIO_BANK4_CFG_CR_BANK_NCODE_MASK (0x3F << 0x6)
+ /* Sets the voltage controls.*/
+ #define MSSIO_BANK4_CFG_CR_VS_OFFSET 0xC
+ #define MSSIO_BANK4_CFG_CR_VS_MASK (0x0F << 0xC)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_0_1_CR_OFFSET 0x234
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_2_3_CR_OFFSET 0x238
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_4_5_CR_OFFSET 0x23C
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_6_7_CR_OFFSET 0x240
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_8_9_CR_OFFSET 0x244
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_10_11_CR_OFFSET 0x248
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK4_IO_CFG_12_13_CR_OFFSET 0x24C
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_OFFSET 0xA
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_OFFSET 0xB
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_OFFSET 0x1A
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_OFFSET 0x1B
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK4_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*Configures the MSSIO block*/
+#define MSSIO_BANK2_CFG_CR_OFFSET 0x250
+ /* Sets the PCODE value*/
+ #define MSSIO_BANK2_CFG_CR_BANK_PCODE_OFFSET 0x0
+ #define MSSIO_BANK2_CFG_CR_BANK_PCODE_MASK (0x3F << 0x0)
+ /* Sets the NCODE value*/
+ #define MSSIO_BANK2_CFG_CR_BANK_NCODE_OFFSET 0x6
+ #define MSSIO_BANK2_CFG_CR_BANK_NCODE_MASK (0x3F << 0x6)
+ /* Sets the voltage controls.*/
+ #define MSSIO_BANK2_CFG_CR_VS_OFFSET 0xC
+ #define MSSIO_BANK2_CFG_CR_VS_MASK (0x0F << 0xC)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_0_1_CR_OFFSET 0x254
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_0_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_0_1_CR_RPC_IO_CFG_1_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_2_3_CR_OFFSET 0x258
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_2_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_2_3_CR_RPC_IO_CFG_3_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_4_5_CR_OFFSET 0x25C
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_4_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_4_5_CR_RPC_IO_CFG_5_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_6_7_CR_OFFSET 0x260
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_6_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_6_7_CR_RPC_IO_CFG_7_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_8_9_CR_OFFSET 0x264
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_8_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_8_9_CR_RPC_IO_CFG_9_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_10_11_CR_OFFSET 0x268
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_10_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_10_11_CR_RPC_IO_CFG_11_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_12_13_CR_OFFSET 0x26C
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_12_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_12_13_CR_RPC_IO_CFG_13_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_14_15_CR_OFFSET 0x270
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_14_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_14_15_CR_RPC_IO_CFG_15_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_16_17_CR_OFFSET 0x274
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_16_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_16_17_CR_RPC_IO_CFG_17_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_18_19_CR_OFFSET 0x278
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_18_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_18_19_CR_RPC_IO_CFG_19_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_20_21_CR_OFFSET 0x27C
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_20_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_20_21_CR_RPC_IO_CFG_21_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*IO electrical configuration for MSSIO pad*/
+#define MSSIO_BANK2_IO_CFG_22_23_CR_OFFSET 0x280
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_0_OFFSET 0x0
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_0_MASK (0x01 << 0x0)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_1_OFFSET 0x1
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_1_MASK (0x01 << 0x1)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_2_OFFSET 0x2
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_IBUFMD_2_MASK (0x01 << 0x2)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_0_OFFSET 0x3
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_0_MASK (0x01 << 0x3)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_1_OFFSET 0x4
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_1_MASK (0x01 << 0x4)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_2_OFFSET 0x5
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_2_MASK (0x01 << 0x5)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_3_OFFSET 0x6
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_DRV_3_MASK (0x01 << 0x6)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_CLAMP_OFFSET 0x7
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_CLAMP_MASK (0x01 << 0x7)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ENHYST_OFFSET 0x8
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ENHYST_MASK (0x01 << 0x8)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LOCKDN_EN_OFFSET 0x9
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LOCKDN_EN_MASK (0x01 << 0x9)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPD_OFFSET 0xA
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPD_MASK (0x01 << 0xA)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPU_OFFSET 0xB
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_WPU_MASK (0x01 << 0xB)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ATP_EN_OFFSET 0xC
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_ATP_EN_MASK (0x01 << 0xC)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_PERSIST_EN_OFFSET 0xD
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_PERSIST_EN_MASK (0x01 << 0xD)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_BYPASS_EN_OFFSET 0xE
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_22_LP_BYPASS_EN_MASK (0x01 << 0xE)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_0_OFFSET 0x10
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_0_MASK (0x01 << 0x10)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_1_OFFSET 0x11
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_1_MASK (0x01 << 0x11)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_2_OFFSET 0x12
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_IBUFMD_2_MASK (0x01 << 0x12)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_0_OFFSET 0x13
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_0_MASK (0x01 << 0x13)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_1_OFFSET 0x14
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_1_MASK (0x01 << 0x14)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_2_OFFSET 0x15
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_2_MASK (0x01 << 0x15)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_3_OFFSET 0x16
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_DRV_3_MASK (0x01 << 0x16)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_CLAMP_OFFSET 0x17
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_CLAMP_MASK (0x01 << 0x17)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ENHYST_OFFSET 0x18
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ENHYST_MASK (0x01 << 0x18)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LOCKDN_EN_OFFSET 0x19
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LOCKDN_EN_MASK (0x01 << 0x19)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPD_OFFSET 0x1A
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPD_MASK (0x01 << 0x1A)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPU_OFFSET 0x1B
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_WPU_MASK (0x01 << 0x1B)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ATP_EN_OFFSET 0x1C
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_ATP_EN_MASK (0x01 << 0x1C)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_PERSIST_EN_OFFSET 0x1D
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_PERSIST_EN_MASK (0x01 << 0x1D)
+ /* */
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_BYPASS_EN_OFFSET 0x1E
+ #define MSSIO_BANK2_IO_CFG_22_23_CR_RPC_IO_CFG_23_LP_BYPASS_EN_MASK (0x01 << 0x1E)
+
+/*Sets H2F [31:0] Spares out signals*/
+#define MSS_SPARE0_CR_OFFSET 0x2A8
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE0_CR_DATA_OFFSET 0x0
+ #define MSS_SPARE0_CR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Sets H2F [37:32] Spares out signals*/
+#define MSS_SPARE1_CR_OFFSET 0x2AC
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE1_CR_DATA_OFFSET 0x0
+ #define MSS_SPARE1_CR_DATA_MASK (0x3F << 0x0)
+
+/*Read H2F [31:0] Spares out signals*/
+#define MSS_SPARE0_SR_OFFSET 0x2B0
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE0_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE0_SR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Read H2F [37:32] Spares out signals*/
+#define MSS_SPARE1_SR_OFFSET 0x2B4
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE1_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE1_SR_DATA_MASK (0x3F << 0x0)
+
+/*Read F2H [31:0] Spares in1 signals*/
+#define MSS_SPARE2_SR_OFFSET 0x2B8
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE2_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE2_SR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Read F2H [37:32] Spares in1 signals*/
+#define MSS_SPARE3_SR_OFFSET 0x2BC
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE3_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE3_SR_DATA_MASK (0x3F << 0x0)
+
+/*Read F2H [31:0] Spares in2 signals*/
+#define MSS_SPARE4_SR_OFFSET 0x2C0
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE4_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE4_SR_DATA_MASK (0xFFFFFFFF << 0x0)
+
+/*Read F2H [37:32] Spares in2 signals*/
+#define MSS_SPARE5_SR_OFFSET 0x2C4
+ /* See MSS MAS specification for full description*/
+ #define MSS_SPARE5_SR_DATA_OFFSET 0x0
+ #define MSS_SPARE5_SR_DATA_MASK (0x3F << 0x0)
+
+/*Register for ECO usage*/
+#define SPARE_REGISTER_RW_OFFSET 0x2D0
+ /* No function provided for future ECO use*/
+ #define SPARE_REGISTER_RW_DATA_OFFSET 0x0
+ #define SPARE_REGISTER_RW_DATA_MASK (0xFF << 0x0)
+
+/*Register for ECO usage*/
+#define SPARE_REGISTER_W1P_OFFSET 0x2D4
+ /* No function provided for future ECO use*/
+ #define SPARE_REGISTER_W1P_DATA_OFFSET 0x0
+ #define SPARE_REGISTER_W1P_DATA_MASK (0xFF << 0x0)
+
+/*Register for ECO usage*/
+#define SPARE_REGISTER_RO_OFFSET 0x2D8
+ /* Provides read-back of { W1P RW } registers. No function provided for
+ future ECO use.*/
+ #define SPARE_REGISTER_RO_DATA_OFFSET 0x0
+ #define SPARE_REGISTER_RO_DATA_MASK (0xFFFF << 0x0)
+
+/*Spare signal back to G5C*/
+#define SPARE_PERIM_RW_OFFSET 0x2DC
+ /* Allows the MSS to control the perim_spare_out bits [2] & [6]. No fun
+ ction provided for future ECO use.*/
+ #define SPARE_PERIM_RW_DATA_OFFSET 0x0
+ #define SPARE_PERIM_RW_DATA_MASK (0x03 << 0x0)
+
+/*Unused FIC resets*/
+#define SPARE_FIC_OFFSET 0x2E0
+ /* Connected to spare FIC 0-3 Reset inputs to provide simple RO bits. N
+ o defined use*/
+ #define SPARE_FIC_RESET_OFFSET 0x0
+ #define SPARE_FIC_RESET_MASK (0x0F << 0x0)
+/**************************************************************************
+ *******
+********************TOP LEVEL REGISTER STRUCTURE***************************
+ *******
+***************************************************************************
+ *******/
+
+typedef struct _mss_sysreg
+{
+ /*Register for software use*/
+ __IO uint32_t TEMP0;
+
+ /*Register for software use*/
+ __IO uint32_t TEMP1;
+
+ /*Master clock configuration*/
+ __IO uint32_t CLOCK_CONFIG_CR;
+
+ /*RTC clock divider*/
+ __IO uint32_t RTC_CLOCK_CR;
+
+ /*Fabric Reset mask*/
+ __IO uint32_t FABRIC_RESET_CR;
+
+ /**/
+ __IO uint32_t BOOT_FAIL_CR;
+
+ /* Allows the CPU to fully reset the MSS.
+ When written to 16'hDEAD will cause a full MSS reset. The Reset wil clear
+ this register. The register may be writtent to any value but only a value
+ off 16'hDEAD will cause the reset to happen */
+ __IO uint32_t MSS_RESET_CR;
+
+ /*Configuration lock*/
+ __IO uint32_t CONFIG_LOCK_CR;
+
+ /*Indicates which reset caused the last reset. After a reset occurs reg
+ ister should be read and then zero written to allow the next reset event to
+ be correctly captured.*/
+ __IO uint32_t RESET_SR;
+
+ /*Indicates the device status in particular the state of the FPGA fabri
+ c and the MSS IO banks*/
+ __IO uint32_t DEVICE_STATUS ;
+
+ /*MSS Build Info*/
+ __I uint32_t MSS_BUILD;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_1;
+ __I uint32_t RESERVEDREG32B_2;
+ __I uint32_t RESERVEDREG32B_3;
+ __I uint32_t RESERVEDREG32B_4;
+ __I uint32_t RESERVEDREG32B_5;
+
+ /*U54-1 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_1;
+
+ /*U54-2 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_2;
+
+ /*U54-3 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_3;
+
+ /*U54-4 Fabric interrupt enable*/
+ __IO uint32_t FAB_INTEN_U54_4;
+
+ /*Allows the Ethernet interrupts to be directly routed to the U54 CPUS.
+ */
+ __IO uint32_t FAB_INTEN_MISC;
+ /* Enables the Ethernet MAC0 to interrupt U54_1 directly */
+ #define FAB_INTEN_MAC0_U54_1_EN_OFFSET 0x01U
+ /* Enables the Ethernet MAC0 to interrupt U54_2 directly */
+ #define FAB_INTEN_MAC0_U54_2_EN_OFFSET 0x02U
+ /* Enables the Ethernet MAC1 to interrupt U54_3 directly */
+ #define FAB_INTEN_MAC1_U54_3_EN_OFFSET 0x03U
+ /* Enables the Ethernet MAC1 to interrupt U54_4 directly */
+ #define FAB_INTEN_MAC1_U54_4_EN_OFFSET 0x04U
+ #define FAB_INTEN_MAC0_U54_1_EN_MASK 0x01U
+ #define FAB_INTEN_MAC0_U54_2_EN_MASK 0x02U
+ #define FAB_INTEN_MAC1_U54_3_EN_MASK 0x04U
+ #define FAB_INTEN_MAC1_U54_4_EN_MASK 0x08U
+
+ /*Switches GPIO interrupt from PAD to Fabric GPIO*/
+ __IO uint32_t GPIO_INTERRUPT_FAB_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_6;
+ __I uint32_t RESERVEDREG32B_7;
+ __I uint32_t RESERVEDREG32B_8;
+ __I uint32_t RESERVEDREG32B_9;
+ __I uint32_t RESERVEDREG32B_10;
+ __I uint32_t RESERVEDREG32B_11;
+ __I uint32_t RESERVEDREG32B_12;
+ __I uint32_t RESERVEDREG32B_13;
+ __I uint32_t RESERVEDREG32B_14;
+ __I uint32_t RESERVEDREG32B_15;
+
+ /*"AMP Mode peripheral mapping register. When the register bit is '0' t
+ he peripheral is mapped into the 0x2000000 address range using AXI bus 5 fr
+ om the Coreplex. When the register bit is '1' the peripheral is mapped into
+ the 0x28000000 address range using AXI bus 6 from the Coreplex."*/
+ __IO uint32_t APBBUS_CR;
+
+ /*"Enables the clock to the MSS peripheral. By turning clocks off dynam
+ ic power can be saved. When the clock is off the peripheral should not be
+ accessed*/
+ __IO uint32_t SUBBLK_CLOCK_CR;
+
+ /*"Holds the MSS peripherals in reset. When in reset the peripheral sho
+ uld not be accessed*/
+ __IO uint32_t SOFT_RESET_CR;
+
+ /*Configures how many outstanding transfers the AXI-AHB bridges in fron
+ t off the USB and Crypto blocks should allow. (See Synopsys AXI-AHB bridge
+ documentation)*/
+ __IO uint32_t AHBAXI_CR;
+
+ /*Configures the two AHB-APB bridges on S5 and S6*/
+ __IO uint32_t AHBAPB_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ uint32_t reservedReg32b_16;
+
+ /*MSS Corner APB interface controls*/
+ __IO uint32_t DFIAPB_CR;
+
+ /*GPIO Blocks reset control*/
+ __IO uint32_t GPIO_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ uint32_t reservedReg32b_17;
+
+ /*MAC0 configuration register*/
+ __IO uint32_t MAC0_CR;
+
+ /*MAC1 configuration register*/
+ __IO uint32_t MAC1_CR;
+
+ /*USB Configuration register*/
+ __IO uint32_t USB_CR;
+
+ /*Crypto Mesh control and status register*/
+ __IO uint32_t MESH_CR;
+
+ /*Crypto mesh seed and update rate*/
+ __IO uint32_t MESH_SEED_CR;
+
+ /*ENVM AHB Controller setup*/
+ __IO uint32_t ENVM_CR;
+
+ /*Reserved*/
+ __I uint32_t RESERVED_BC;
+
+ /*QOS Athena USB & MMC Configuration*/
+ __IO uint32_t QOS_PERIPHERAL_CR;
+
+ /*QOS Configuration Coreplex*/
+ __IO uint32_t QOS_CPLEXIO_CR;
+
+ /*QOS configuration DDRC*/
+ __IO uint32_t QOS_CPLEXDDR_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_18;
+ __I uint32_t RESERVEDREG32B_19;
+ __I uint32_t RESERVEDREG32B_20;
+ __I uint32_t RESERVEDREG32B_21;
+ __I uint32_t RESERVEDREG32B_22;
+ __I uint32_t RESERVEDREG32B_23;
+ __I uint32_t RESERVEDREG32B_24;
+ __I uint32_t RESERVEDREG32B_25;
+ __I uint32_t RESERVEDREG32B_26;
+
+ /*Indicates that a master caused a MPU violation. Interrupts via mainte
+ nance interrupt.*/
+ __IO uint32_t MPU_VIOLATION_SR;
+
+ /*Enables interrupts on MPU violations*/
+ __IO uint32_t MPU_VIOLATION_INTEN_CR;
+
+ /*AXI switch decode fail*/
+ __IO uint32_t SW_FAIL_ADDR0_CR;
+
+ /*AXI switch decode fail*/
+ __IO uint32_t SW_FAIL_ADDR1_CR;
+
+ /*Set when an ECC event happens*/
+ __IO uint32_t EDAC_SR;
+
+ /*Enables ECC interrupt on event*/
+ __IO uint32_t EDAC_INTEN_CR;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_MMC;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_DDRC;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_MAC0;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_MAC1;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_USB;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_CAN0;
+
+ /*Count off single bit errors*/
+ __IO uint32_t EDAC_CNT_CAN1;
+
+ /*"Will Corrupt write data to rams 1E corrupts bit 0 2E bits 1 and 2.In
+ jects Errors into all RAMS in the block as long as the bits are set. Settin
+ g 1E and 2E will inject a 3-bit error"*/
+ __IO uint32_t EDAC_INJECT_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_27;
+ __I uint32_t RESERVEDREG32B_28;
+ __I uint32_t RESERVEDREG32B_29;
+ __I uint32_t RESERVEDREG32B_30;
+ __I uint32_t RESERVEDREG32B_31;
+ __I uint32_t RESERVEDREG32B_32;
+
+ /*Maintenance Interrupt Enable.*/
+ __IO uint32_t MAINTENANCE_INTEN_CR;
+
+ /*PLL Status interrupt enables*/
+ __IO uint32_t PLL_STATUS_INTEN_CR;
+
+ /*Maintenance interrupt indicates fault and status events.*/
+ __IO uint32_t MAINTENANCE_INT_SR;
+
+ /*PLL interrupt register*/
+ __IO uint32_t PLL_STATUS_SR;
+
+ /*Enable to CFM Timer */
+ __IO uint32_t CFM_TIMER_CR;
+
+ /*Miscellaneous Register*/
+ uint32_t MISC_SR;
+
+ /*DLL Interrupt enables*/
+ __IO uint32_t DLL_STATUS_CR;
+
+ /*DLL interrupt register*/
+ __IO uint32_t DLL_STATUS_SR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_33;
+ __I uint32_t RESERVEDREG32B_34;
+
+ /*Puts all the RAMS in that block into low leakage mode. RAM contents a
+ nd Q value preserved.*/
+ __IO uint32_t RAM_LIGHTSLEEP_CR;
+
+ /*Puts all the RAMS in that block into deep sleep mode. RAM contents pr
+ eserved. Powers down the periphery circuits.*/
+ __IO uint32_t RAM_DEEPSLEEP_CR;
+
+ /*Puts all the RAMS in that block into shut down mode. RAM contents not
+ preserved. Powers down the RAM and periphery circuits.*/
+ __IO uint32_t RAM_SHUTDOWN_CR;
+
+ /*Allows each bank of the L2 Cache to be powered down ORed with global
+ shutdown */
+ __IO uint32_t L2_SHUTDOWN_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_35;
+ __I uint32_t RESERVEDREG32B_36;
+ __I uint32_t RESERVEDREG32B_37;
+ __I uint32_t RESERVEDREG32B_38;
+ __I uint32_t RESERVEDREG32B_39;
+ __I uint32_t RESERVEDREG32B_40;
+ __I uint32_t RESERVEDREG32B_41;
+ __I uint32_t RESERVEDREG32B_42;
+ __I uint32_t RESERVEDREG32B_43;
+ __I uint32_t RESERVEDREG32B_44;
+ __I uint32_t RESERVEDREG32B_45;
+ __I uint32_t RESERVEDREG32B_46;
+ __I uint32_t RESERVEDREG32B_47;
+ __I uint32_t RESERVEDREG32B_48;
+ __I uint32_t RESERVEDREG32B_49;
+ __I uint32_t RESERVEDREG32B_50;
+ __I uint32_t RESERVEDREG32B_51;
+ __I uint32_t RESERVEDREG32B_52;
+ __I uint32_t RESERVEDREG32B_53;
+ __I uint32_t RESERVEDREG32B_54;
+ __I uint32_t RESERVEDREG32B_55;
+ __I uint32_t RESERVEDREG32B_56;
+ __I uint32_t RESERVEDREG32B_57;
+ __I uint32_t RESERVEDREG32B_58;
+ __I uint32_t RESERVEDREG32B_59;
+ __I uint32_t RESERVEDREG32B_60;
+ __I uint32_t RESERVEDREG32B_61;
+ __I uint32_t RESERVEDREG32B_62;
+ __I uint32_t RESERVEDREG32B_63;
+ __I uint32_t RESERVEDREG32B_64;
+ __I uint32_t RESERVEDREG32B_65;
+ __I uint32_t RESERVEDREG32B_66;
+ __I uint32_t RESERVEDREG32B_67;
+ __I uint32_t RESERVEDREG32B_68;
+
+ /*Selects whether the peripheral is connected to the Fabric or IOMUX st
+ ructure.*/
+ __IO uint32_t IOMUX0_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX1_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX2_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX3_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX4_CR;
+
+ /*Configures the IO Mux structure for each IO pad. See the MSS MAS spec
+ ification for for description.*/
+ __IO uint32_t IOMUX5_CR;
+
+ /*Sets whether the MMC/SD Voltage select lines are inverted on entry to
+ the IOMUX structure*/
+ __IO uint32_t IOMUX6_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_69;
+ __I uint32_t RESERVEDREG32B_70;
+ __I uint32_t RESERVEDREG32B_71;
+ __I uint32_t RESERVEDREG32B_72;
+ __I uint32_t RESERVEDREG32B_73;
+
+ /*Configures the MSSIO block*/
+ __IO uint32_t MSSIO_BANK4_CFG_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_0_1_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_2_3_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_4_5_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_6_7_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_8_9_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_10_11_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK4_IO_CFG_12_13_CR;
+
+ /*Configures the MSSIO block*/
+ __IO uint32_t MSSIO_BANK2_CFG_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_0_1_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_2_3_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_4_5_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_6_7_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_8_9_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_10_11_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_12_13_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_14_15_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_16_17_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_18_19_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_20_21_CR;
+
+ /*IO electrical configuration for MSSIO pad*/
+ __IO uint32_t MSSIO_BANK2_IO_CFG_22_23_CR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_74;
+ __I uint32_t RESERVEDREG32B_75;
+ __I uint32_t RESERVEDREG32B_76;
+ __I uint32_t RESERVEDREG32B_77;
+ __I uint32_t RESERVEDREG32B_78;
+ __I uint32_t RESERVEDREG32B_79;
+ __I uint32_t RESERVEDREG32B_80;
+ __I uint32_t RESERVEDREG32B_81;
+ __I uint32_t RESERVEDREG32B_82;
+
+ /*Sets H2F [31:0] Spares out signals*/
+ __IO uint32_t MSS_SPARE0_CR;
+
+ /*Sets H2F [37:32] Spares out signals*/
+ __IO uint32_t MSS_SPARE1_CR;
+
+ /*Read H2F [31:0] Spares out signals*/
+ __IO uint32_t MSS_SPARE0_SR;
+
+ /*Read H2F [37:32] Spares out signals*/
+ __IO uint32_t MSS_SPARE1_SR;
+
+ /*Read F2H [31:0] Spares in1 signals*/
+ __IO uint32_t MSS_SPARE2_SR;
+
+ /*Read F2H [37:32] Spares in1 signals*/
+ __IO uint32_t MSS_SPARE3_SR;
+
+ /*Read F2H [31:0] Spares in2 signals*/
+ __IO uint32_t MSS_SPARE4_SR;
+
+ /*Read F2H [37:32] Spares in2 signals*/
+ __IO uint32_t MSS_SPARE5_SR;
+
+ /* Padding reserved 32-bit registers.*/
+ __I uint32_t RESERVEDREG32B_83;
+ __I uint32_t RESERVEDREG32B_84;
+
+ /*Register for ECO usage*/
+ __IO uint32_t SPARE_REGISTER_RW;
+
+ /*Register for ECO usage*/
+ __IO uint32_t SPARE_REGISTER_W1P;
+
+ /*Register for ECO usage*/
+ __I uint32_t SPARE_REGISTER_RO;
+
+ /*Spare signal back to G5C*/
+ __IO uint32_t SPARE_PERIM_RW;
+
+ /*Unused FIC resets*/
+ __I uint32_t SPARE_FIC;
+} mss_sysreg_t;
+
+#define SYSREG_ATHENACR_RESET (1U << 0U)
+#define SYSREG_ATHENACR_PURGE (1U << 1U)
+#define SYSREG_ATHENACR_GO (1U << 2U)
+#define SYSREG_ATHENACR_RINGOSCON (1U << 3U)
+#define SYSREG_ATHENACR_COMPLETE (1U << 8U)
+#define SYSREG_ATHENACR_ALARM (1U << 9U)
+#define SYSREG_ATHENACR_BUSERROR (1U << 10U)
+#define SYSREG_SOFTRESET_ENVM (1U << 0U)
+#define SYSREG_SOFTRESET_TIMER (1U << 4U)
+#define SYSREG_SOFTRESET_MMUART0 (1U << 5U)
+#define SYSREG_SOFTRESET_DDRC (1U << 23U)
+#define SYSREG_SOFTRESET_FIC3 (1U << 27U)
+#define SYSREG_SOFTRESET_ATHENA (1U << 28U)
+
+#define SYSREG ((volatile mss_sysreg_t * const) BASE32_ADDR_MSS_SYSREG)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MSS_SYSREG_H*/
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_util.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_util.c
new file mode 100644
index 00000000..cb706149
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_util.c
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_util.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Utility functions
+ *
+ */
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void enable_interrupts(void) {
+ __enable_irq();
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+uint64_t disable_interrupts(void) {
+ uint64_t psr;
+ psr = read_csr(mstatus);
+ __disable_irq();
+ return(psr);
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void restore_interrupts(uint64_t saved_psr) {
+ write_csr(mstatus, saved_psr);
+}
+
+/*------------------------------------------------------------------------------
+ * Disable all interrupts.
+ */
+void __disable_irq(void)
+{
+ clear_csr(mstatus, MSTATUS_MIE);
+ clear_csr(mstatus, MSTATUS_MPIE);
+}
+
+void __disable_all_irqs(void)
+{
+ __disable_irq();
+ write_csr(mie, 0x00U);
+ write_csr(mip, 0x00);
+}
+
+/*------------------------------------------------------------------------------
+ * Enable all interrupts.
+ */
+void __enable_irq(void)
+{
+ set_csr(mstatus, MSTATUS_MIE); /* mstatus Register- Machine Interrupt Enable */
+}
+
+/*------------------------------------------------------------------------------
+ * Enable particular local interrupt
+ */
+void __enable_local_irq(uint8_t local_interrupt)
+{
+ if((local_interrupt > (int8_t)0) && (local_interrupt <= LOCAL_INT_MAX))
+ {
+ set_csr(mie, (0x1LLU << (int8_t)(local_interrupt + 16U))); /* mie Register- Machine Interrupt Enable Register */
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Disable particular local interrupt
+ */
+void __disable_local_irq(uint8_t local_interrupt)
+{
+ if((local_interrupt > (int8_t)0) && (local_interrupt <= LOCAL_INT_MAX))
+ {
+ clear_csr(mie, (0x1LLU << (int8_t)(local_interrupt + 16U))); /* mie Register- Machine Interrupt Enable Register */
+ }
+}
+
+/**
+ * readmcycle(void)
+ * @return returns the mcycle count from hart CSR
+ */
+uint64_t readmcycle(void)
+{
+ return (read_csr(mcycle));
+}
+
+void sleep_ms(uint64_t msecs)
+{
+ uint64_t starttime = readmtime();
+ volatile uint64_t endtime = 0U;
+
+ while(endtime < (starttime+msecs)) {
+ endtime = readmtime();
+ }
+}
+
+/**
+ * sleep_cycles(uint64_t ncycles)
+ * @param number of cycles to sleep
+ */
+void sleep_cycles(uint64_t ncycles)
+{
+ uint64_t starttime = readmcycle();
+ volatile uint64_t endtime = 0U;
+
+ while(endtime < (starttime + ncycles)) {
+ endtime = readmcycle();
+ }
+}
+
+/**
+ * get_program_counter(void)
+ * @return returns the program counter
+ */
+__attribute__((aligned(16))) uint64_t get_program_counter(void)
+{
+ uint64_t prog_counter;
+ asm volatile ("auipc %0, 0" : "=r"(prog_counter));
+ return (prog_counter);
+}
+
+/**
+ * get_stack_pointer(void)
+ * @return Return the stack pointer
+ */
+uint64_t get_stack_pointer(void)
+{
+ uint64_t stack_pointer;
+ asm volatile ("addi %0, sp, 0" : "=r"(stack_pointer));
+ return (stack_pointer);
+}
+
+/**
+ * Return the tp register
+ * The tp register holds the value of the Hart Common memory HLS once not in an
+ * interrupt. If the tp value is used in an interrupt, it is saved first and
+ * restored on exit. This conforms to OpenSBI implementation.
+ *
+ * @return returns the tp register value
+ */
+uint64_t get_tp_reg(void)
+{
+ uint64_t tp_reg_val;
+ asm volatile ("addi %0, tp, 0" : "=r"(tp_reg_val));
+ return (tp_reg_val);
+}
+
+/**
+ * mpfs_sync_bool_compare_and_swap()
+ * this works on the E51 / U54s, and operates equivalently to the
+ * __sync_bool_compare_and_swap() intrinsic.
+ * @param ptr
+ * @param oldval
+ * @param newval
+ * @return
+ */
+bool mpfs_sync_bool_compare_and_swap(volatile long *ptr, long oldval, long newval)
+{
+ static long lock = 0;
+ bool result = false;
+
+ if (!__sync_lock_test_and_set(&lock, 1)) { // amoswap.d.aq
+ if (*ptr == oldval) {
+ *ptr = newval;
+ }
+
+ __sync_lock_release(&lock); // fence iorw,ow; ampswap.d
+ result = true;
+ }
+
+ return result;
+}
+
+/**
+ * mpfs_sync_val_compare_and_swap()
+ * this works on the E51 / U54s, and operates equivalently to the
+ * __sync_val_compare_and_swap() intrinsic. It works by using a separate
+ * static lock, and then emulating the behaviour of the lr.w.aq instruction
+ * Required as lr/sr instructions are not supported on the E51 and are only
+ * supported on L1 cached back memory types. These limitations are not present
+ * with this function.
+ * @param ptr
+ * @param oldval
+ * @param newval
+ */
+long mpfs_sync_val_compare_and_swap(volatile long *ptr, long oldval, long newval)
+{
+ long result = *ptr;
+
+ (void)mpfs_sync_bool_compare_and_swap(ptr, oldval, newval);
+
+ return result;
+}
+
+#ifdef PRINTF_DEBUG_SUPPORTED
+void display_address_of_interest(uint64_t * address_of_interest, int nb_locations) {
+ uint64_t * p_addr_of_interest = address_of_interest;
+ int inc;
+ mpfs_printf(" Displaying address of interest: 0x%lx\n", p_addr_of_interest);
+
+ for (inc = 0U; inc < nb_locations; ++inc) {
+ mpfs_printf(" address of interest: 0x%lx: 0x%lx\n", p_addr_of_interest, *p_addr_of_interest);
+ p_addr_of_interest = p_addr_of_interest + 8;
+ }
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_util.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_util.h
new file mode 100644
index 00000000..a418faae
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/mss_util.h
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_util.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MACROs defines and prototypes associated with utility functions
+ *
+ */
+#ifndef MSS_UTIL_H
+#define MSS_UTIL_H
+
+#include
+#include
+#include "encoding.h"
+#include "mss_hart_ints.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Useful macros
+ */
+#define WRITE_REG8(x, y) (*((volatile uint8_t *)(x)) = (y))
+#define READ_REG8(x) (*((volatile uint8_t *)(x)))
+
+#define WRITE_REG32(x, y) (*((volatile uint32_t *)(x)) = (y))
+#define READ_REG32(x) (*((volatile uint32_t *)(x)))
+
+#define WRITE_REG64(x, y) (*((volatile uint64_t *)(x)) = (y))
+#define READ_REG64(x) (*((volatile uint64_t *)(x)))
+
+/*
+ * return mcycle
+ */
+uint64_t readmcycle(void);
+
+void sleep_ms(uint64_t msecs);
+void sleep_cycles(uint64_t ncycles);
+
+
+uint64_t get_stack_pointer(void);
+uint64_t get_tp_reg(void);
+uint64_t get_program_counter(void) __attribute__((aligned(16)));
+
+#ifdef MPFS_PRINTF_DEBUG_SUPPORTED
+void display_address_of_interest(uint64_t * address_of_interest, int nb_locations);
+#endif
+
+void exit_simulation(void);
+
+void enable_interrupts(void);
+uint64_t disable_interrupts(void);
+void restore_interrupts(uint64_t saved_psr);
+void __disable_irq(void);
+void __disable_all_irqs(void);
+void __enable_irq(void);
+void __enable_local_irq(uint8_t local_interrupt);
+void __disable_local_irq(uint8_t local_interrupt);
+
+bool mpfs_sync_bool_compare_and_swap(volatile long *ptr, long oldval, long newval);
+long mpfs_sync_val_compare_and_swap(volatile long *ptr, long oldval, long newval);
+
+static inline void spinunlock(volatile long *lock)
+{
+ *lock = 0;
+}
+
+static inline void spinlock(volatile long *lock)
+{
+ while(!mpfs_sync_bool_compare_and_swap(lock, 0, 1))
+ {
+ /* add yield if OS */
+ }
+ *lock = 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_UTIL_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_cfm.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_cfm.c
new file mode 100644
index 00000000..3ad42107
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_cfm.c
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mpfs_hal/mss_hal.h"
+#include "mss_cfm.h"
+
+/***************************************************************************//**
+ * See mss_cfm.h for description of this function.
+ */
+uint8_t MSS_CFM_control_start(void)
+{
+
+ /* Writing a 1, to this causes measurement circuitry to start. */
+ CFM_REG->controlReg |= 1;
+
+ return (CFM_REG->controlReg & CFM_CONTROL_REG_START_MASK);
+
+}
+
+
+uint8_t MSS_CFM_control_stop(void)
+{
+
+ /* Writing a 1, to this causes measurement circuitry to start. */
+ CFM_REG->controlReg |= (1 << CFM_CONTROL_REG_STOP_BITS_SHIFT);
+
+ return (CFM_REG->controlReg & CFM_CONTROL_REG_START_MASK);
+
+}
+
+
+
+cfm_error_id_t MSS_CLF_clk_configuration(
+ uint8_t clkSel,
+ uint8_t refsel0,
+ uint8_t refsel1,
+ uint8_t monSEL,
+ uint8_t monEN
+ )
+{
+
+ /* Reset the register. */
+ CFM_REG->clkselReg = 0;
+
+ /* Some error checking on configuration values. */
+ if(clkSel > CFM_CLK_SEL_MASK)
+ return ERROR_INVALID_CLK_SELECTION_GROUP;
+
+ if(refsel0 > CFM_CLK_REFSEL0_MASK)
+ return ERROR_INVALID_REF_SEL0;
+
+ if(refsel1 > CFM_CLK_REFSEL1_MASK)
+ return ERROR_INVALID_REF_SEL1;
+
+ if(monSEL > CFM_CLK_MONSEL_MASK)
+ return ERROR_INVALID_CHANNEL_DRIVE_CLK_MONITOR;
+
+
+ CFM_REG->clkselReg |= (clkSel & CFM_CLK_SEL_MASK);
+
+ if(refsel0)
+ CFM_REG->clkselReg |= (uint32_t)(refsel0 << CFM_CLK_REFSEL0SHIFT);
+
+ if(refsel1)
+ CFM_REG->clkselReg |= (uint32_t)(refsel1 << CFM_CLK_REFSEL1SHIFT);
+
+ if(monSEL)
+ CFM_REG->clkselReg |= (uint32_t)(monSEL << CFM_CLK_MONSEL_SHIFT);
+
+
+ if(monEN)
+ CFM_REG->clkselReg |= (uint32_t)(monEN << CFM_CLK_MONEN_SHIFT);
+
+
+ return CFM_OK;
+
+}
+
+
+void MSS_CFM_runtime_register(uint32_t referenceCount)
+{
+
+ /*Sets how many runtime reference clock cycles the frequency and time
+ * measurement shold be made for.. */
+ CFM_REG->runtimeReg = (referenceCount & CFM_RUNTIME_REG_MASK);
+
+ return;
+}
+
+
+void MSS_CFM_channel_mode(cfmChannelMode chMode)
+{
+
+
+ uint32_t chConfiguration = 0;
+
+ chConfiguration |= (chMode.channel0 & CFM_CHANNEL_MODE_MASK) << CFM_CH0_SHIFT_MASK;
+ chConfiguration |= (chMode.channel1 & CFM_CHANNEL_MODE_MASK) << CFM_CH1_SHIFT_MASK;
+ chConfiguration |= (chMode.channel2 & CFM_CHANNEL_MODE_MASK) << CFM_CH2_SHIFT_MASK;
+ chConfiguration |= (chMode.channel3 & CFM_CHANNEL_MODE_MASK) << CFM_CH3_SHIFT_MASK;
+ chConfiguration |= (chMode.channel4 & CFM_CHANNEL_MODE_MASK) << CFM_CH4_SHIFT_MASK;
+ chConfiguration |= (chMode.channel5 & CFM_CHANNEL_MODE_MASK) << CFM_CH5_SHIFT_MASK;
+ chConfiguration |= (chMode.channel6 & CFM_CHANNEL_MODE_MASK) << CFM_CH6_SHIFT_MASK;
+ chConfiguration |= (chMode.channel7 & CFM_CHANNEL_MODE_MASK) << CFM_CH7_SHIFT_MASK;
+
+ CFM_REG->modelReg = chConfiguration;
+
+
+ return;
+}
+
+cfm_error_id_t MSS_CFM_get_count(cfm_count_id_t ch, uint32_t *count)
+{
+
+ if(count == NULL)
+ return ERROR_NULL_VALUE;
+
+ *count = 0;
+
+ if(CFM_REG->controlReg & CFM_CONTROL_REG_BUSY_MASK)
+ return ERROR_INVALID_CFM_BUSY;
+
+ switch(ch)
+ {
+ case CFM_COUNT_0:
+ *count = CFM_REG->count0;
+ break;
+
+ case CFM_COUNT_1:
+ *count = CFM_REG->count1;
+ break;
+
+ case CFM_COUNT_2:
+ *count = CFM_REG->count2;
+ break;
+
+ case CFM_COUNT_3:
+ *count = CFM_REG->count3;
+ break;
+
+ case CFM_COUNT_4:
+ *count = CFM_REG->count4;
+ break;
+
+ case CFM_COUNT_5:
+ *count = CFM_REG->count5;
+ break;
+
+ case CFM_COUNT_6:
+ *count = CFM_REG->count6;
+ break;
+
+ case CFM_COUNT_7:
+ *count = CFM_REG->count7;
+ break;
+
+ default:
+ return 11;
+
+
+ }
+
+ return CFM_OK;
+
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_cfm.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_cfm.h
new file mode 100644
index 00000000..1429da6c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_cfm.h
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire MSS Frequency Meter Bare Metal Driver.
+ The MSS Clock Frequency Meter (CFM) block is used to support test of the
+ DLL's within the MSS. All functional clocks are connected to the CFM block.
+
+ The frequency meter can be configured to measure time or frequency, time
+ allowing items such as PLL lock times to be tested and frequency to test
+ oscillator frequencies.
+
+ Upto 8 circuit counters are implemented.
+
+ @section intro_sec Introduction
+
+ *//*=========================================================================*/
+#ifndef __COREPLEX_PLATFORM_CFM_H_
+#define __COREPLEX_PLATFORM_CFM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/* CFM Register base address. */
+#define CFM_REG_BASE 0x20006000
+
+/***************************************************************************//**
+ The __cfm_count_id_t enumeration is used to identify the channel used.
+ */
+typedef enum __cfm_count_id
+{
+ CFM_COUNT_0 = 0,
+ CFM_COUNT_1,
+ CFM_COUNT_2,
+ CFM_COUNT_3,
+ CFM_COUNT_4,
+ CFM_COUNT_5,
+ CFM_COUNT_6,
+ CFM_COUNT_7,
+ cfm_lastCH,
+} cfm_count_id_t;
+
+
+
+/***************************************************************************//**
+ The cfm_channel_mode enumeration is used to specify the channel mode.
+ */
+typedef enum __cfm_channel_mode
+{
+ CFM_CH_DISABLED = 0,
+ CFM_CH_FREQUENCY_MODE,
+ CFM_CH_RESERVER,
+ CFM_CH_TIMER_MODE,
+ CFM_CH_lastmd
+} cfm_channel_mode;
+
+
+
+typedef enum __cfm_error_id_t
+{
+ CFM_OK = 0,
+ ERROR_INVALID_CLK_SELECTION_GROUP,
+ ERROR_INVALID_REF_SEL0,
+ ERROR_INVALID_REF_SEL1,
+ ERROR_INVALID_CHANNEL_DRIVE_CLK_MONITOR,
+ ERROR_INVALID_CFM_BUSY,
+
+ ERROR_NULL_VALUE,
+
+ ERROR_CFMLAST_ID
+} cfm_error_id_t;
+
+
+typedef struct _cfmRegs
+{
+ __IO uint32_t controlReg; /* CFM Control Register */
+ __IO uint32_t clkselReg; /* Clock Selection Register */
+ __IO uint32_t runtimeReg; /* Reference Count Value */
+ __IO uint32_t modelReg; /* Sets the measurement mode */
+
+ __I uint32_t count0; /* Count x value */
+ __I uint32_t count1;
+ __I uint32_t count2;
+ __I uint32_t count3;
+ __I uint32_t count4;
+ __I uint32_t count5;
+ __I uint32_t count6;
+ __I uint32_t count7;
+
+ __I uint32_t reserved[4]; /*Reserved registers, padding structure */
+
+
+}CFM;
+
+
+#define CFM_REG ((CFM *)CFM_REG_BASE)
+
+typedef struct _cfmChannelMode
+{
+ uint8_t channel0; /* Channel x mode */
+ uint8_t channel1; /* Channel x mode */
+ uint8_t channel2; /* Channel x mode */
+ uint8_t channel3; /* Channel x mode */
+ uint8_t channel4; /* Channel x mode */
+ uint8_t channel5; /* Channel x mode */
+ uint8_t channel6; /* Channel x mode */
+ uint8_t channel7; /* Channel x mode */
+
+}cfmChannelMode;
+
+#define CFM_CONTROL_REG_BUSY_MASK 0x01U
+#define CFM_CONTROL_REG_START_MASK 0x01U
+#define CFM_CONTROL_REG_STOP_BITS_SHIFT 0x01U
+
+#define CFM_CLK_SEL_MASK 0x07U
+
+
+#define CFM_CLK_REFSEL0_MASK 0x01U
+#define CFM_CLK_REFSEL0SHIFT 0x04U
+
+
+#define CFM_CLK_REFSEL1_MASK 0x01U
+#define CFM_CLK_REFSEL1SHIFT 0x05U
+
+
+#define CFM_CLK_MONSEL_MASK 0x07U
+#define CFM_CLK_MONSEL_SHIFT 0x08U
+
+
+
+#define CFM_CLK_MONEN_MASK 0x01
+#define CFM_CLK_MONEN_SHIFT 11U
+
+#define CFM_RUNTIME_REG_MASK 0xFFFFFFU
+
+#define CFM_CHANNEL_MODE_MASK 0x3U
+
+#define CFM_CH0_SHIFT_MASK 0x00U
+#define CFM_CH1_SHIFT_MASK 0x02U
+#define CFM_CH2_SHIFT_MASK 0x04U
+#define CFM_CH3_SHIFT_MASK 0x06U
+#define CFM_CH4_SHIFT_MASK 0x08U
+#define CFM_CH5_SHIFT_MASK 0x0AU
+#define CFM_CH6_SHIFT_MASK 0x0CU
+#define CFM_CH7_SHIFT_MASK 0x0EU
+
+
+
+/*****************************************************************************
+ * CFM Function Prototypes
+ *******************************************************************************
+ */
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_control_start() function causes the measurement circuitry
+ to start. This state of 'busy' will clear which measurement is complete.
+
+
+ @param None
+
+ @return
+ Busy state
+
+ Example:
+ The following call will start the CFM
+ @code
+ MSS_CFM_control_start( );
+ @endcode
+ */
+uint8_t MSS_CFM_control_start(void);
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_control_stop() function causes the measurement circuitry
+ to stop.
+
+
+ @param None
+
+
+ @return uint8_t
+ Returns the busy flag.
+
+
+ Example:
+ The following call will stop the CFM
+ @code
+ MSS_CFM_control_stop( );
+ @endcode
+ */
+uint8_t MSS_CFM_control_stop(void);
+
+
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CLF_clk_configuration() function is used to configure the clock
+ selection register.
+
+ @param clkSel
+ Selects which group of clock inputs are selected by the channels, control
+ the input multiplexer.
+
+ @param refsel0
+ Selects the reference input, 0=clkref1 / 1=clkref2
+
+ @param refsel1
+ When in timer mode allows ATPG (corners) / clkref3 clock input to clock
+ the channel counters. This clock input is expected to be sourced from an
+ on-chip PLL to support at-speed testing. This allows the timer to clocked
+ off a much higher clock frequency that the reference counter that is limited
+ to 100Mhz.
+
+ @param monSEL
+ Selects which channel drives the clock monitor output 0-7.
+
+
+ @param monEN
+ Enables the clock monitor output.
+
+
+ @return
+ cfm_error_id_t
+
+ Example:
+ The following call will configure clk 0, using clkref1, channel zero drives
+ the clock monitor and enable the clock monitor output.
+ @code
+ MSS_GPIO_config( 0, 0, 0, 0, 1 );
+ @endcode
+ */
+cfm_error_id_t MSS_CLF_clk_configuration(
+ uint8_t clkSel,
+ uint8_t refsel0,
+ uint8_t refsel1,
+ uint8_t monSEL,
+ uint8_t monEN
+ );
+
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_runtime_register() function is used to set how many reference
+ clock cycles the frequency and time measurement should be made.
+ The register does NOT change during oepration
+
+ @param refcount
+ The reference count value.
+
+ */
+void MSS_CFM_runtime_register(
+ uint32_t referenceCount
+ );
+
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_channel_mode() function is used to set the measurement mode for
+ the specified channel.
+ 2'b00: Disabled
+ 2'b01: Frequency Mode
+ 2'b11: Timer Mode
+ 2'b10: Reserved
+
+ @param cfmChannelMode
+ Configuration structure for each channel
+
+ @return
+ None
+
+ */
+void MSS_CFM_channel_mode(cfmChannelMode chMode);
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CFM_get_count() function is used to get the count value.
+ Block must not be busy.
+
+ @param ch
+ The channel ID to return the count for.
+
+ @param count
+ The count for the channel register.
+
+ @return
+ cfm_error_id_t
+
+ Example:
+ The following call will return the value in count register. channel 0
+
+ @code
+ MSS_CFM_get_count();
+ @endcode
+ */
+cfm_error_id_t MSS_CFM_get_count(cfm_count_id_t ch, uint32_t *count);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __COREPLEX_PLATFORM_CFM_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr.c
new file mode 100644
index 00000000..6dce7432
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr.c
@@ -0,0 +1,4692 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief DDR related code
+ *
+ */
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#ifdef DDR_SUPPORT
+#include "mss_ddr_debug.h"
+#include "simulation.h"
+#ifdef FABRIC_NOISE_TEST
+#include "drivers/mss_gpio/mss_gpio.h"
+#endif
+
+/*******************************************************************************
+ * Local Defines
+ */
+/* This string is updated if any change to ddr driver */
+#define DDR_DRIVER_VERSION_STRING "0.2.003"
+/* Version | Comment */
+/* 0.2.003 | Updated SEG setup to match Libero 12.7, Removed warnings, */
+/* | shortened timeout in mtc_test */
+/* 0.2.002 | MTC_test() update -added more tests */
+/* 0.2.001 | Reverted ADDCMD training command */
+/* 0.2.000 | RPC166 now does short retrain by default */
+/* 0.1.009 | Removed AXI overrides. Agreed better placed in */
+/* | mss_sw_config.h util until corrected in configurator v3.0 */
+/* 0.1.008 | Added manual addcmd traing for all variants */
+/* 0.1.007 | Added some updates from SVG and DCT. Also overrides AXI */
+/* | ranges if incorrectly set (Liber0 v12.5 and Liber0 v12.6 */
+/* 0.1.006 | Added tuning for rpc166, read lane FIFO alignement */
+/* 0.1.005 | Added parameter to modify rpc166, lane out of sync on read */
+/* 0.1.004 | Corrected default RPC220 setting so dq/dqs window centred */
+/* 0.1.003 | refclk_phase correctly masked during bclk sclk sw training */
+/* 0.1.002 | Reset modified- corrects softreset on retry issue (1.8.x) */
+/* 0.1.001 | Reset modified- corrects softreset on retry issue (1.7.2) */
+/* 0.0.016 | Added #define DDR_FULL_32BIT_NC_CHECK_EN to mss_ddr.h */
+/* 0.0.016 | updated mss_ddr_debug.c with additio of 32-bit write test */
+/* 0.0.015 | DDR3L - Use Software Bclk Sclk training */
+/* 0.0.014 | DDR3 and DDR update to sync with SVG proven golden version */
+/* 0.0.013 | Added code to turn off DM if DDR4 and using ECC */
+/* 0.0.012 | Added support for turning off unused I/O from Libero */
+
+/*
+ * Calibration data records calculated write calibration values during training
+ */
+mss_ddr_calibration calib_data;
+
+/* rx lane FIFO used for tuning */
+#if (TUNE_RPC_166_VALUE == 1)
+static uint32_t rpc_166_fifo_offset;
+#endif
+
+/*
+ * This string is used as a quick sanity check of write/read to DDR.
+ * The memory test core is used for more comprehensive testing during and
+ * post calibration
+ */
+#ifdef DDR_SANITY_CHECKS_EN
+static const uint32_t test_string[] = {
+ 0x12345678,23211234,0x35675678,0x4456789,0x56789123,0x65432198,\
+ 0x45673214,0xABCD1234,0x99999999,0xaaaaaaaa,0xbbbbbbbb,0xcccccccc,\
+ 0xdddddddd,0xeeeeeeee,0x12121212,0x12345678};
+#endif
+
+/*******************************************************************************
+ * external functions
+ */
+#ifdef DEBUG_DDR_INIT
+extern mss_uart_instance_t *g_debug_uart;
+extern uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt);
+#endif
+
+/* Use to record instance of errors during calibration */
+static uint32_t ddr_error_count;
+#ifdef SWEEP_ENABLED
+uint8_t sweep_results[MAX_NUMBER_DPC_VS_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_H_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_V_GEN_SWEEPS]\
+ [MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS]\
+ [MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS];
+#define TOTAL_SWEEPS (MAX_NUMBER_DPC_H_GEN_SWEEPS*MAX_NUMBER_DPC_H_GEN_SWEEPS*\
+ MAX_NUMBER_DPC_V_GEN_SWEEPS*MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS*\
+ MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS)
+#endif
+
+/*******************************************************************************
+ * Local function declarations
+ */
+static uint32_t ddr_setup(void);
+static void init_ddrc(void);
+static uint8_t write_calibration_using_mtc(uint8_t num_of_lanes_to_calibrate);
+/*static uint8_t mode_register_write(uint32_t MR_ADDR, uint32_t MR_DATA);*/
+static uint8_t MTC_test(uint8_t mask, uint64_t start_address, uint32_t size, MTC_PATTERN pattern, MTC_ADD_PATTERN add_pattern, uint32_t *error);
+#ifdef VREFDQ_CALIB
+static uint8_t FPGA_VREFDQ_calibration_using_mtc(void);
+static uint8_t VREFDQ_calibration_using_mtc(void);
+#endif
+#ifdef DDR_SANITY_CHECKS_EN
+static uint8_t rw_sanity_chk(uint64_t * address, uint32_t count);
+static uint8_t mtc_sanity_check(uint64_t start_address);
+#endif
+#ifdef SET_VREF_LPDDR4_MODE_REGS
+static uint8_t mode_register_write(uint32_t MR_ADDR, uint32_t MR_DATA);
+#endif
+#ifdef DDR_SANITY_CHECKS_EN
+static uint8_t memory_tests(void);
+#endif
+static void ddr_off_mode(void);
+static void set_ddr_mode_reg_and_vs_bits(uint32_t dpc_bits);
+static void set_ddr_rpc_regs(DDR_TYPE ddr_type);
+static uint8_t get_num_lanes(void);
+static void load_dq(uint8_t lane);
+static uint8_t use_software_bclk_sclk_training(DDR_TYPE ddr_type);
+static void config_ddr_io_pull_up_downs_rpc_bits(DDR_TYPE ddr_type);
+#ifdef SWEEP_ENABLED
+static uint8_t get_best_sweep(sweep_index *good_index);
+#endif
+#ifdef MANUAL_ADDCMD_TRAINIG
+static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index);
+#endif
+
+/*******************************************************************************
+ * External function declarations
+ */
+extern void delay(uint32_t n);
+
+#ifdef DEBUG_DDR_INIT
+extern mss_uart_instance_t *g_debug_uart;
+#ifdef DEBUG_DDR_DDRCFG
+void debug_read_ddrcfg(void);
+#endif
+#endif
+
+#ifdef FABRIC_NOISE_TEST
+uint32_t fabric_noise_en = 1;
+uint32_t fabric_noise_en_log = 1;
+uint32_t num_of_noise_blocks_en = 3; /* do not set less than 1 */
+uint32_t noise_ena = 0x0;
+#endif
+
+/*******************************************************************************
+ * Instance definitions
+ */
+
+/*******************************************************************************
+ * Public Functions - API
+ ******************************************************************************/
+
+
+/***************************************************************************//**
+ * ddr_state_machine(DDR_SS_COMMAND)
+ * call this routine if you do not require the state machine
+ *
+ * @param ddr_type
+ */
+uint32_t ddr_state_machine(DDR_SS_COMMAND command)
+{
+ static DDR_SM_STATES ddr_state;
+ static uint32_t return_status;
+ if (command == DDR_SS__INIT)
+ {
+ ddr_state = DDR_STATE_INIT;
+ }
+ SIM_FEEDBACK0(100U + ddr_state);
+ SIM_FEEDBACK1(ddr_state);
+ switch (ddr_state)
+ {
+ default:
+ case DDR_STATE_INIT:
+ ddr_state = DDR_STATE_TRAINING;
+ return_status = 0U;
+ break;
+
+ case DDR_STATE_TRAINING:
+ /*
+ * We stay in this state until finished training/fail training
+ */
+ return_status = ddr_setup();
+ break;
+
+ case DDR_STATE_MONITOR:
+ /*
+ * 1. Periodically check DDR access
+ * 2. Run any tests, as directed
+ */
+// return_status = ddr_monitor();
+ break;
+ }
+ SIM_FEEDBACK1(0xFF000000UL + return_status);
+ return (return_status);
+}
+
+
+/***************************************************************************//**
+ * ddr_setup(DDR_TYPE ddr_type)
+ * call this routine if you do not require the state machine
+ *
+ * @param ddr_type
+ */
+static uint32_t ddr_setup(void)
+{
+ static DDR_TRAINING_SM ddr_training_state = DDR_TRAINING_INIT;
+ static uint32_t error;
+ static uint32_t timeout;
+#ifdef DEBUG_DDR_INIT
+ static uint32_t addr_cmd_value;
+ static uint32_t bclk_sclk_offset_value;
+ static uint32_t dpc_vrgen_v_value;
+ static uint32_t dpc_vrgen_h_value;
+ static uint32_t dpc_vrgen_vs_value;
+#endif
+#ifdef SWEEP_ENABLED
+ static SWEEP_STATES sweep_state = INIT_SWEEP;
+#endif
+ static uint32_t retry_count;
+ static uint32_t write_latency;
+ static uint32_t tip_cfg_params;
+ static uint32_t dpc_bits;
+ static uint8_t last_sweep_status;
+#if (TUNE_RPC_166_VALUE == 1)
+ static uint8_t num_rpc_166_retires = 0U;
+#endif
+#ifdef MANUAL_ADDCMD_TRAINIG
+ static uint8_t refclk_offset;
+ static uint8_t refclk_sweep_index =0xFU;
+#endif
+ static uint32_t bclk_answer = 0U;
+ DDR_TYPE ddr_type;
+ uint32_t ret_status = 0U;
+ uint8_t number_of_lanes_to_calibrate;
+
+ ddr_type = LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK;
+
+ SIM_FEEDBACK0(200U + ddr_training_state);
+ SIM_FEEDBACK1(0U);
+
+ switch (ddr_training_state)
+ {
+ case DDR_TRAINING_INIT:
+ tip_cfg_params = LIBERO_SETTING_TIP_CFG_PARAMS;
+ dpc_bits = LIBERO_SETTING_DPC_BITS ;
+ write_latency = LIBERO_SETTING_CFG_WRITE_LATENCY_SET;
+#if (TUNE_RPC_166_VALUE == 1)
+ rpc_166_fifo_offset = DEFAULT_RPC_166_VALUE;
+#endif
+#ifdef MANUAL_ADDCMD_TRAINIG
+ refclk_offset = LIBERO_SETTING_MAX_MANUAL_REF_CLK_PHASE_OFFSET + 1U;
+#endif
+#ifdef SWEEP_ENABLED
+ sweep_state = INIT_SWEEP;
+#endif
+ ddr_error_count = 0U;
+ error = 0U;
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ retry_count = 0U;
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r Start training. TIP_CFG_PARAMS:"\
+ , LIBERO_SETTING_TIP_CFG_PARAMS);
+#endif
+#ifdef SWEEP_ENABLED
+ addr_cmd_value = LIBERO_SETTING_TIP_CFG_PARAMS\
+ & ADDRESS_CMD_OFFSETT_MASK;
+ bclk_sclk_offset_value = (LIBERO_SETTING_TIP_CFG_PARAMS\
+ & BCLK_SCLK_OFFSET_MASK)>>BCLK_SCLK_OFFSET_SHIFT;
+ dpc_vrgen_v_value = (LIBERO_SETTING_DPC_BITS & \
+ BCLK_DPC_VRGEN_V_MASK)>>BCLK_DPC_VRGEN_V_SHIFT;
+ dpc_vrgen_h_value = (LIBERO_SETTING_DPC_BITS & \
+ BCLK_DPC_VRGEN_H_MASK)>>BCLK_DPC_VRGEN_H_SHIFT;
+ dpc_vrgen_vs_value = (LIBERO_SETTING_DPC_BITS & \
+ BCLK_DPC_VRGEN_VS_MASK)>>BCLK_DPC_VRGEN_VS_SHIFT;
+#endif
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ break;
+ case DDR_TRAINING_FAIL_SM2_VERIFY:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM2_VERIFY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_VERIFY:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_VERIFY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_DQ_DQS:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_DQ_DQS: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_RDGATE:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_RDGATE: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_WRLVL:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_WRLVL: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_ADDCMD:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r SM_ADDCMD: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_SM_BCLKSCLK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r BCLKSCLK_SWY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_BCLKSCLK_SW:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r BCLKSCLK_SW: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_FULL_32BIT_NC_CHECK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r 32BIT_NC_CHECK: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_32BIT_CACHE_CHECK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r 32BIT_CACHE_CHECK: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_MIN_LATENCY:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r MIN_LATENCY: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_START_CHECK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r START_CHECK: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_PLL_LOCK:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r PLL LOCK FAIL: ",addr_cmd_value);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ break;
+ case DDR_TRAINING_FAIL_DDR_SANITY_CHECKS:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r DDR_SANITY_CHECKS FAIL: ",\
+ addr_cmd_value);
+ ddr_training_state = DDR_TRAINING_FAIL;
+#endif
+ break;
+ case DDR_SWEEP_AGAIN:
+ retry_count++;
+ last_sweep_status = CALIBRATION_PASSED;
+ #ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR_SWEEP_AGAIN: ",\
+ ddr_training_state);
+ #endif
+ ddr_training_state = DDR_CHECK_TRAINING_SWEEP;
+ break;
+ case DDR_TRAINING_FAIL:
+#ifdef DEBUG_DDR_INIT
+ {
+ tip_register_status (g_debug_uart);
+ (void)uprint32(g_debug_uart, "\n\r ****************************************************", 0U);
+
+ }
+#endif
+ retry_count++;
+ if(last_sweep_status != CALIBRATION_SUCCESS)
+ {
+ last_sweep_status = CALIBRATION_FAILED;
+ }
+ #ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR_TRAINING_FAIL: ",\
+ ddr_training_state);
+ (void)uprint32(g_debug_uart, "\n\r Retry Count: ", retry_count);
+ #endif
+ ddr_training_state = DDR_CHECK_TRAINING_SWEEP;
+ break;
+
+ case DDR_CHECK_TRAINING_SWEEP:
+ {
+#ifdef SWEEP_ENABLED
+ /* first check if we are finished */
+ if(last_sweep_status == CALIBRATION_SUCCESS)
+ {
+ /*
+ * Try again with calculated values
+ */
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ }
+ else if(retry_count == TOTAL_SWEEPS)
+ {
+ sweep_index index;
+#ifdef DEBUG_DDR_INIT
+ sweep_status(g_debug_uart);
+#endif
+ /*
+ * Choose the best index
+ */
+ if (get_best_sweep(&index) == 0U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r sweep success: ",\
+ tip_cfg_params);
+#endif
+ last_sweep_status = CALIBRATION_SUCCESS;
+ /*
+ * Use obtained settings
+ */
+ addr_cmd_value = index.cmd_index +\
+ LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET;
+ bclk_sclk_offset_value = index.bclk_sclk_index +\
+ LIBERO_SETTING_MIN_ADDRESS_BCLK_SCLK_OFFSET;
+ dpc_vrgen_v_value = index.dpc_vgen_index +\
+ LIBERO_SETTING_MIN_DPC_V_GEN;
+ dpc_vrgen_h_value = index.dpc_vgen_h_index +\
+ LIBERO_SETTING_MIN_DPC_H_GEN;
+ dpc_vrgen_vs_value = index.dpc_vgen_vs_index +\
+ LIBERO_SETTING_MIN_DPC_VS_GEN;
+
+ tip_cfg_params = ((tip_cfg_params &\
+ (~BCLK_SCLK_OFFSET_MASK))|\
+ (bclk_sclk_offset_value<DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START = 0x0U;
+ /* reset controller */
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x0U;
+ CFG_DDR_SGMII_PHY->training_start.training_start = 0x0U;
+ }
+#else /* we are not SWEEP_ENABLED */
+ ddr_error_count = 0U;
+ error = 0U;
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START = 0x0U;
+ /* reset controller */
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x0U;
+ CFG_DDR_SGMII_PHY->training_start.training_start = 0x0U;
+
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ }
+#endif
+ break;
+
+ case DDR_TRAINING_SWEEP:
+#ifdef SWEEP_ENABLED
+ {
+ static uint32_t sweep_count_cmd_offset;
+ static uint32_t sweep_count_bck_sclk;
+ static uint32_t sweep_count_dpc_v_bits;
+ static uint32_t sweep_count_dpc_h_bits;
+ static uint32_t sweep_count_dpc_vs_bits;
+
+ switch(sweep_state)
+ {
+ case INIT_SWEEP:
+ /*
+ * Parameter values
+ */
+ addr_cmd_value = LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET;
+ bclk_sclk_offset_value =\
+ LIBERO_SETTING_MIN_ADDRESS_BCLK_SCLK_OFFSET;
+ dpc_vrgen_v_value = LIBERO_SETTING_MIN_DPC_V_GEN;
+ dpc_vrgen_h_value = LIBERO_SETTING_MIN_DPC_H_GEN;
+ dpc_vrgen_vs_value = LIBERO_SETTING_MIN_DPC_VS_GEN;
+ /*
+ * state counts
+ */
+ sweep_count_cmd_offset = 0U;
+ sweep_count_bck_sclk = 0U;
+ sweep_count_dpc_v_bits = 0U;
+ sweep_count_dpc_h_bits = 0U;
+ sweep_count_dpc_vs_bits = 0U;
+ sweep_state = ADDR_CMD_OFFSET_SWEEP;
+ __attribute__((fallthrough)); /* deliberately fall through */
+ case ADDR_CMD_OFFSET_SWEEP:
+ /*
+ * Record sweep result
+ */
+ sweep_results[sweep_count_dpc_vs_bits][sweep_count_dpc_h_bits][sweep_count_dpc_v_bits]\
+ [sweep_count_bck_sclk]\
+ [sweep_count_cmd_offset] = last_sweep_status;
+ /*
+ * sweep: ADDR_CMD OFFSET
+ */
+ addr_cmd_value++;
+ if (addr_cmd_value > \
+ LIBERO_SETTING_MAX_ADDRESS_CMD_OFFSET)
+ {
+ addr_cmd_value = \
+ LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET;
+ }
+
+ tip_cfg_params = ((tip_cfg_params &\
+ (~ADDRESS_CMD_OFFSETT_MASK))|(addr_cmd_value));
+ sweep_count_cmd_offset++;
+ if(sweep_count_cmd_offset > MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS)
+ {
+ sweep_count_cmd_offset = 0U;
+ sweep_state = BCLK_SCLK_OFFSET_SWEEP;
+ }
+ else
+ {
+ /*
+ * Now do a sweep
+ */
+ ddr_error_count = 0U;
+ error = 0U;
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START = 0x00000000U;
+ /* reset controller */
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x00000000U;
+ CFG_DDR_SGMII_PHY->training_start.training_start = 0x00000000U;
+ ddr_training_state = DDR_TRAINING_CHECK_FOR_OFFMODE;
+ }
+ break;
+ case BCLK_SCLK_OFFSET_SWEEP:
+ /*
+ * sweep: BCLK_SCLK
+ */
+ bclk_sclk_offset_value++;
+ if (bclk_sclk_offset_value > \
+ LIBERO_SETTING_MAX_ADDRESS_BCLK_SCLK_OFFSET)
+ {
+ bclk_sclk_offset_value = \
+ LIBERO_SETTING_MIN_ADDRESS_BCLK_SCLK_OFFSET;
+ }
+ tip_cfg_params = ((tip_cfg_params &\
+ (~BCLK_SCLK_OFFSET_MASK))|\
+ (bclk_sclk_offset_value< MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS)
+ {
+ sweep_count_bck_sclk = 0U;
+ sweep_state = DPC_VRGEN_V_SWEEP;
+ }
+ else
+ {
+ sweep_state = ADDR_CMD_OFFSET_SWEEP;
+ }
+ break;
+ case DPC_VRGEN_V_SWEEP:
+ /*
+ * sweep: DPC_VRGEN_V [4:6]
+ * LIBERO_SETTING_DPC_BITS
+ */
+ dpc_vrgen_v_value++;
+ if (dpc_vrgen_v_value > \
+ LIBERO_SETTING_MAX_DPC_V_GEN)
+ {
+ dpc_vrgen_v_value = \
+ LIBERO_SETTING_MIN_DPC_V_GEN;
+ }
+ dpc_bits = ((dpc_bits &\
+ (~BCLK_DPC_VRGEN_V_MASK))|\
+ (dpc_vrgen_v_value< MAX_NUMBER_DPC_V_GEN_SWEEPS)
+ {
+ sweep_count_dpc_v_bits = 0U;
+ sweep_state = DPC_VRGEN_H_SWEEP;
+ }
+ else
+ {
+ sweep_state = BCLK_SCLK_OFFSET_SWEEP;
+ }
+ break;
+ case DPC_VRGEN_H_SWEEP:
+ /*
+ * sweep: DPC_VRGEN_V [4:6]
+ * LIBERO_SETTING_DPC_BITS
+ */
+ dpc_vrgen_h_value++;
+ if (dpc_vrgen_h_value > \
+ LIBERO_SETTING_MAX_DPC_H_GEN)
+ {
+ dpc_vrgen_h_value = \
+ LIBERO_SETTING_MIN_DPC_H_GEN;
+ }
+ dpc_bits = ((dpc_bits &\
+ (~BCLK_DPC_VRGEN_H_MASK))|\
+ (dpc_vrgen_h_value< MAX_NUMBER_DPC_H_GEN_SWEEPS)
+ {
+ sweep_count_dpc_h_bits = 0U;
+ sweep_state = DPC_VRGEN_VS_SWEEP;
+ }
+ else
+ {
+ sweep_state = DPC_VRGEN_V_SWEEP;
+ }
+ break;
+ case DPC_VRGEN_VS_SWEEP:
+ /*
+ * sweep: DPC_VRGEN_V [4:6]
+ * LIBERO_SETTING_DPC_BITS
+ */
+ dpc_vrgen_vs_value++;
+ if (dpc_vrgen_vs_value > \
+ LIBERO_SETTING_MAX_DPC_VS_GEN)
+ {
+ dpc_vrgen_vs_value = \
+ LIBERO_SETTING_MIN_DPC_VS_GEN;
+ }
+ dpc_bits = ((dpc_bits &\
+ (~BCLK_DPC_VRGEN_VS_MASK))|\
+ (dpc_vrgen_vs_value< MAX_NUMBER_DPC_VS_GEN_SWEEPS)
+ {
+ sweep_count_dpc_vs_bits = 0U;
+ }
+ sweep_state = DPC_VRGEN_H_SWEEP;
+ break;
+ case FINISHED_SWEEP:
+ break;
+ default:
+ break;
+ }
+ }
+#endif /* SWEEP_ENABLED */
+ break;
+
+ case DDR_TRAINING_CHECK_FOR_OFFMODE:
+ /*
+ * check if we are in off mode
+ */
+ if (ddr_type == DDR_OFF_MODE)
+ {
+ ddr_off_mode();
+ ret_status |= DDR_SETUP_DONE;
+ return (ret_status);
+ }
+ else
+ {
+ /*
+ * set initial conditions
+ */
+ /* enable fabric noise */
+#ifdef FABRIC_NOISE_TEST
+ if(fabric_noise_en)
+ {
+ SYSREG->SOFT_RESET_CR &= 0x00U;
+ SYSREG->SUBBLK_CLOCK_CR = 0xffffffffUL;
+ SYSREG->GPIO_INTERRUPT_FAB_CR = 0x00000000UL;
+ PLIC_init();
+ PLIC_SetPriority_Threshold(0);
+ __enable_irq();
+ /* bit0-bit15 used to enable noise logic in steps of 5%
+ bit 16 noise logic reset
+ bit 17 clkmux sel
+ bit 18 pll powerdown
+ bit 19 external io enable for GCLKINT */
+ PLIC_SetPriority(GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0, 4U);
+ PLIC_SetPriority(GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1, 4U);
+ PLIC_SetPriority(GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2, 4U);
+ PLIC_SetPriority(GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3, 4U);
+ PLIC_SetPriority(GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4, 4U);
+ PLIC_SetPriority(GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5, 4U);
+ PLIC_SetPriority(GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6, 4U);
+ PLIC_SetPriority(GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7, 4U);
+ PLIC_SetPriority(GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8, 4U);
+ PLIC_SetPriority(GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9, 4U);
+ PLIC_SetPriority(GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10, 4U);
+ PLIC_SetPriority(GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11, 4U);
+ PLIC_SetPriority(GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12, 4U);
+ PLIC_SetPriority(GPIO0_BIT13_or_GPIO2_BIT13_PLIC_13, 4U);
+ PLIC_SetPriority(GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14, 4U);
+ PLIC_SetPriority(GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15, 4U);
+ PLIC_SetPriority(GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16, 4U);
+ PLIC_SetPriority(GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17, 4U);
+ PLIC_SetPriority(GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18, 4U);
+ PLIC_SetPriority(GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19, 4U);
+
+ MSS_GPIO_init(GPIO2_LO);
+ MSS_GPIO_config_all(GPIO2_LO, MSS_GPIO_OUTPUT_MODE);
+ MSS_GPIO_set_outputs(GPIO2_LO, 0x00000UL); /* bits 15:0 - 0, noise logic disabled */
+ delay(100);
+ /*MSS_GPIO_set_outputs(GPIO2_LO, 0x00FFFUL);*/ /* bits 12:0 - 1, 56% enabled */
+ noise_ena = (1 << num_of_noise_blocks_en) - 1;
+ MSS_GPIO_set_outputs(GPIO2_LO, noise_ena); /* num_of_noise_blocks_en * 4.72% */
+ fabric_noise_en = 0;
+ }
+#endif /* FABRIC_NOISE_TEST */
+ write_latency = MIN_LATENCY;
+ ddr_training_state = DDR_TRAINING_SET_MODE_VS_BITS;
+ }
+ break;
+
+ case DDR_TRAINING_SET_MODE_VS_BITS:
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r dpc_bits: ",\
+ dpc_bits);
+#endif
+ /*
+ * Set the training mode
+ */
+ set_ddr_mode_reg_and_vs_bits(dpc_bits);
+ ddr_training_state = DDR_TRAINING_FLASH_REGS;
+ break;
+
+ case DDR_TRAINING_FLASH_REGS:
+ /*
+ * flash registers with RPC values
+ * Enable DDR IO decoders
+ * Note :
+ * rpc sequence:
+ * power-up -> mss_boot -> re-flash nv_map -> override
+ * any changes (to fix issues)
+ *
+ * SOFT_RESET_ bit 0 == periph soft reset, auto cleared
+ */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_DRIVER.SOFT_RESET_DECODER_DRIVER = 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_ODT.SOFT_RESET_DECODER_ODT=1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_IO.SOFT_RESET_DECODER_IO = 1U;
+ ddr_training_state = DDR_TRAINING_CORRECT_RPC;
+ break;
+
+ case DDR_TRAINING_CORRECT_RPC:
+ /*
+ * correct some rpc registers, which were incorrectly set in mode
+ * setting
+ */
+ set_ddr_rpc_regs(ddr_type);
+ ddr_training_state = DDR_TRAINING_SOFT_RESET;
+ break;
+ case DDR_TRAINING_SOFT_RESET:
+ /*
+ * Set soft reset on IP to load RPC to SCB regs (dynamic mode)
+ * Bring the DDR bank controller out of reset
+ */
+ IOSCB_BANKCONT_DDR->soft_reset = 1U; /* DPC_BITS NV_MAP reset */
+ ddr_training_state = DDR_TRAINING_CALIBRATE_IO;
+ break;
+ case DDR_TRAINING_CALIBRATE_IO:
+ /*
+ * Calibrate DDR I/O here, once all RPC settings correct
+ */
+ ddr_pvt_calibration();
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r PCODE = ",\
+ (CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2 & 0x7FU));
+ (void)uprint32(g_debug_uart, "\n\r NCODE = ", \
+ (((CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2) >> 7U) & 0x7FU));
+ (void)uprint32(g_debug_uart, "\n\r addr_cmd_value: ",\
+ addr_cmd_value);
+ (void)uprint32(g_debug_uart, "\n\r bclk_sclk_offset_value: ",\
+ bclk_sclk_offset_value);
+ (void)uprint32(g_debug_uart, "\n\r dpc_vrgen_v_value: ",\
+ dpc_vrgen_v_value);
+ (void)uprint32(g_debug_uart, "\n\r dpc_vrgen_h_value: ",\
+ dpc_vrgen_h_value);
+ (void)uprint32(g_debug_uart, "\n\r dpc_vrgen_vs_value: ",\
+ dpc_vrgen_vs_value);
+#endif
+ ddr_training_state = DDR_TRAINING_CONFIG_PLL;
+ break;
+ case DDR_TRAINING_CONFIG_PLL:
+ /*
+ * Configure the DDR PLL
+ */
+ ddr_pll_config(SCB_UPDATE);
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_VERIFY_PLL_LOCK;
+ break;
+ case DDR_TRAINING_VERIFY_PLL_LOCK:
+ /*
+ * Verify DDR PLL lock
+ */
+ if (ddr_pll_lock_scb() == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_SETUP_SEGS;
+ }
+ else if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_PLL_LOCK;
+ }
+ break;
+ case DDR_TRAINING_SETUP_SEGS:
+ /*
+ * Configure Segments- address mapping, CFG0/CFG1
+ */
+ setup_ddr_segments(DEFAULT_SEG_SETUP);
+ /*
+ * enable the DDRC
+ */
+ /* Turn on DDRC clock */
+ SYSREG->SUBBLK_CLOCK_CR |= SUBBLK_CLOCK_CR_DDRC_MASK;
+ /* Remove soft reset */
+ SYSREG->SOFT_RESET_CR &= (uint32_t)~SOFT_RESET_CR_DDRC_MASK;
+ ddr_training_state = DDR_TRAINING_SETUP_DDRC;
+ break;
+ case DDR_TRAINING_SETUP_DDRC:
+ /*
+ * set-up DDRC
+ * Configuration taken from the user.
+ */
+ {
+ init_ddrc();
+ ddr_training_state = DDR_TRAINING_RESET;
+ }
+ break;
+ case DDR_TRAINING_RESET:
+ /*
+ * Assert training reset
+ * reset pin is bit [1]
+ * and load skip setting
+ */
+ /* leave in reset */
+/* To verify if separate reset required for DDR4 - believe it is not */
+#ifndef SPECIAL_TRAINIG_RESET
+ CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U;
+#ifndef SOFT_RESET_PRE_TAG_172
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000000U;
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000001U;
+#endif /* !SOFT_RESET_PRE_TAG_172 */
+#else
+ /* Disable CKE */
+ DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1;
+
+ /* Assert FORCE_RESET */
+ DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x1;
+ delay(100);
+ /* release reset to memory here, set INIT_FORCE_RESET to 0 */
+ DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x0;
+ delay(500000);
+
+ /* Enable CKE */
+ DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x0;
+ delay(1000);
+
+ /* reset pin is bit [1] */
+ CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U;
+
+#endif
+ ddr_training_state = DDR_TRAINING_ROTATE_CLK;
+ break;
+ case DDR_TRAINING_ROTATE_CLK:
+ /*
+ * Rotate bclk90 by 90 deg
+ */
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt = 0x00000004U;
+ /*expert mode enabling */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000002U;
+ /* */
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x7CU; /* loading */
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x78U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x78U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x7CU;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x4U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x64U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x66U; /* increment */
+ for (uint32_t d=0;d< \
+ LIBERO_SETTING_TIP_CONFIG_PARAMS_BCLK_VCOPHS_OFFSET;d++)
+ {
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x67U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x66U;
+ }
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x64U;
+ CFG_DDR_SGMII_PHY->expert_pllcnt.expert_pllcnt= 0x4U;
+
+ /* setting load delay lines */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_mv_rd_dly_reg.expert_dlycnt_mv_rd_dly_reg\
+ = 0x1FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xFFFFFFFFU; /* setting to 1 to load delaylines */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x00000000U;
+
+ /* write w DFICFG_REG mv_rd_dly 0x00000000 #
+ tip_apb_write(12'h89C, 32'h0); mv_rd_dly */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_mv_rd_dly_reg.expert_dlycnt_mv_rd_dly_reg \
+ = 0x0U;
+
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xFFFFFFFFU; /* setting to 1 to load delaylines */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x00000000U;
+
+
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x0000003FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x00000000U;
+
+ /* DQ */
+ /* dfi_training_complete_shim = 1'b1
+ dfi_wrlvl_en_shim = 1'b1 */
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x6;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0xFFFFFFFFU; /* load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xF; /* (ECC) - load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0x0; /* clear */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x0; /* (ECC) clear */
+
+ /* DQS
+ * dfi_wrlvl_en_shim = 1'b1 */
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x4;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0xFFFFFFFFU; /* load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0xF; /* (ECC) - load output delays */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0=\
+ 0x0; /* clear */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1=\
+ 0x0; /* (ECC) clear */
+
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x0; /* clear */
+
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x0000003FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x00000000U;
+
+ /* expert mode disabling */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en =\
+ 0x00000000U;
+ ddr_training_state = DDR_TRAINING_SET_TRAINING_PARAMETERS;
+ break;
+ case DDR_TRAINING_SET_TRAINING_PARAMETERS:
+ /*
+ * SET TRAINING PARAMETERS
+ *
+ * TIP STATIC PARAMETERS 0
+ *
+ * 30:22 Number of VCO Phase offsets between BCLK and SCLK
+ * 21:13 Number of VCO Phase offsets between BCLK and SCLK
+ * 12:6 Number of VCO Phase offsets between BCLK and SCLK
+ * 5:3 Number of VCO Phase offsets between BCLK and SCLK
+ * 2:0 Number of VCO Phase offsets between REFCLK and ADDCMD bits
+ */
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r tip_cfg_params: ",\
+ tip_cfg_params);
+#endif
+
+ CFG_DDR_SGMII_PHY->tip_cfg_params.tip_cfg_params =\
+ tip_cfg_params;
+ timeout = 0xFFFF;
+
+ if(use_software_bclk_sclk_training(ddr_type) == 1U)
+ {
+ /*
+ * Initiate software training
+ */
+#ifdef SOFT_RESET_PRE_TAG_172
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000001U;
+#endif
+ ddr_training_state = DDR_TRAINING_IP_SM_BCLKSCLK_SW;
+ }
+ else
+ {
+ /*
+ * Initiate IP training and wait for dfi_init_complete
+ */
+ /*asserting training_reset */
+ if (ddr_type != DDR3)
+ {
+ CFG_DDR_SGMII_PHY->training_reset.training_reset =\
+ 0x00000000U;
+ }
+ else
+ {
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ 0x00000001U;
+ }
+ ddr_training_state = DDR_TRAINING_IP_SM_START;
+ }
+ }
+ break;
+
+ case DDR_TRAINING_IP_SM_BCLKSCLK_SW:
+ /*
+ * We have chosen to use software bclk sclk sweep instead of IP
+ */
+ {
+ uint32_t bclk_phase, bclk90_phase,refclk_phase;
+ bclk_answer = 0U;
+ {
+ /*
+ * BEGIN MANUAL BCLKSCLK TRAINING
+ */
+ uint32_t rx_previous=0x3U;
+ uint32_t rx_current=0U;
+ uint32_t answer_count[8U]={0U,0U,0U,0U,0U,0U,0U,0U};
+ uint32_t answer_index=0U;
+
+ /*UPPER LIMIT MUST BE MULTIPLE OF 8 */
+ for (uint32_t i=0U; i<(8U * 100); i++)
+ {
+
+ bclk_phase = ( i & 0x07UL ) << 8U;
+ bclk90_phase = ((i+2U) & 0x07UL ) << 11U;
+ /*
+ * LOAD BCLK90 PHASE
+ */
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+
+ /*
+ * No pause required, causes an issue
+ */
+
+ /*
+ * SAMPLE RX_BCLK
+ */
+ rx_current = ((CFG_DDR_SGMII_PHY->expert_addcmd_ln_readback.expert_addcmd_ln_readback) >> 12)& 0x03;
+ /* IF WE FOUND A TRANSITION, BREAK THE LOOP */
+ if ((rx_current & (~rx_previous)) != 0x00000000UL)
+ {
+ answer_index=i&0x07U;
+ /* increment the answer count for this index */
+ answer_count[answer_index]++;
+ }
+
+ rx_previous = rx_current;
+ uint32_t max=0U;
+ for (uint32_t j=0U;j<8U;j++)
+ {
+ /* sweep through found answers and select the most common */
+ if (answer_count[j] > max)
+ {
+ bclk_answer = j;
+ max=answer_count[j];
+ }
+ }
+ }
+ }
+ ddr_training_state = DDR_MANUAL_ADDCMD_TRAINING_SW;
+ break;
+
+ case DDR_MANUAL_ADDCMD_TRAINING_SW:
+ {
+ /*
+ * APPLY OFFSET & LOAD THE PHASE
+ * bclk_sclk_offset_value
+ * BCLK_SCLK_OFFSET_BASE
+ */
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT)
+ {
+ /*
+ * We are skipping add/cmd training so need to set
+ * refclk phase offset manually
+ * We may need to sweep this
+ */
+ refclk_phase = (uint32_t)(((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET + 5U + LIBERO_SETTING_MANUAL_REF_CLK_PHASE_OFFSET ) & 0x07UL) << 2U);
+ bclk_phase = ((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET) & 0x07UL ) << 8U;
+ bclk90_phase= ((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET+2U) & 0x07UL ) << 11U;
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase | refclk_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase);
+ }
+ else
+ {
+ bclk_phase = ((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET) & 0x07UL ) << 8U;
+ bclk90_phase=((bclk_answer+SW_TRAING_BCLK_SCLK_OFFSET+2U) & 0x07UL ) << 11U;
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase);
+ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase);
+ }
+ ddr_training_state = DDR_TRAINING_IP_SM_START;
+ /* END MANUAL BCLKSCLK TRAINING */
+ }
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_BCLKSCLK_SW;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_START:
+ {
+ CFG_DDR_SGMII_PHY->training_skip.training_skip =\
+ LIBERO_SETTING_TRAINING_SKIP_SETTING;
+ if ((ddr_type == DDR3)||(ddr_type == LPDDR4)||(ddr_type == DDR4))
+ {
+ /* RX_MD_CLKN */
+ CFG_DDR_SGMII_PHY->rpc168.rpc168 = 0x0U;
+ }
+#ifdef DDR_TRAINING_IP_SM_START_DELAY
+ delay(100);
+#endif
+ /* release reset to training */
+ CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000000U;
+#ifdef IP_SM_START_TRAINING_PAUSE
+ /* todo: pause removed at Alister's request for test. Will
+ * remove once verified not required after further testing
+ */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0xffU;
+ delay(100);
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x00000000U;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x0000003FU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x00000000U;
+ delay(100);
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00U;
+ delay(100);
+#endif
+ }
+ {
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START =\
+ 0x00000000U;
+ /* kick off training- DDRC, set dfi_init_start */
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START =\
+ 0x00000001U;
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x00000000U;
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = 0x00000001U;
+
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_START_CHECK;
+ }
+#ifdef DEBUG_DDR_INIT
+#ifdef MANUAL_ADDCMD_TRAINIG
+ (void)uprint32(g_debug_uart, "\n\r\n\r ADDCMD_OFFSET ", refclk_offset);
+#endif
+#endif
+ break;
+ case DDR_TRAINING_IP_SM_START_CHECK:
+#ifndef RENODE_DEBUG
+ if((DDRCFG->DFI.STAT_DFI_INIT_COMPLETE.STAT_DFI_INIT_COMPLETE\
+ & 0x01U) == 0x01U)
+#endif
+ {
+#ifdef LANE_ALIGNMENT_RESET_REQUIRED
+ CFG_DDR_SGMII_PHY->lane_alignment_fifo_control.lane_alignment_fifo_control = 0x00U;
+ CFG_DDR_SGMII_PHY->lane_alignment_fifo_control.lane_alignment_fifo_control = 0x02U;
+#endif
+
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, \
+ "\n\r\n\r pll_phadj_after_hw_training ",\
+ MSS_SCB_DDR_PLL->PLL_DIV_2_3);
+ (void)uprint32(g_debug_uart, \
+ "\n\r\n\r pll_phadj_after_hw_training ",\
+ MSS_SCB_DDR_PLL->PLL_DIV_0_1);
+#endif
+
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & BCLK_SCLK_BIT)
+ {
+ ddr_training_state = DDR_TRAINING_IP_SM_ADDCMD;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_IP_SM_BCLKSCLK;
+ }
+ timeout = 0xFFFF;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_START_CHECK;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_BCLKSCLK:
+ if(CFG_DDR_SGMII_PHY->training_status.training_status & BCLK_SCLK_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_ADDCMD;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_BCLKSCLK;
+ }
+ break;
+
+ case DDR_TRAINING_IP_SM_ADDCMD:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT)
+ {
+ timeout = 0xFFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_WRLVL;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & ADDCMD_BIT)
+ {
+ timeout = 0xFFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_WRLVL;
+ }
+ if(--timeout == 0U)
+ {
+ /*
+ * Typically this can fail for two
+ * reasons:
+ * 1. ADD/CMD not being received
+ * We need to sweep:
+ * ADDCMD_OFFSET [0:3] RW value
+ * sweep-> 0x2 -> 4 -> C -> 0
+ * 2. DQ not received
+ * We need to sweep:
+ * LIBERO_SETTING_DPC_BITS
+ * DPC_VRGEN_H [4:6] value= 0x8->0xC
+ *
+ * */
+ ddr_training_state = DDR_TRAINING_FAIL_SM_ADDCMD;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_WRLVL:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & WRLVL_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_RDGATE;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & WRLVL_BIT)
+ {
+ timeout = 0xFFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_RDGATE;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_WRLVL;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_RDGATE:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & RDGATE_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_DQ_DQS;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & RDGATE_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_DQ_DQS;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_RDGATE;
+ }
+ break;
+ case DDR_TRAINING_IP_SM_DQ_DQS:
+ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & DQ_DQS_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_VERIFY;
+ }
+ else if(CFG_DDR_SGMII_PHY->training_status.training_status & DQ_DQS_BIT)
+ {
+ timeout = 0xFFFF;
+ ddr_training_state = DDR_TRAINING_IP_SM_VERIFY;
+ }
+ if(--timeout == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM_DQ_DQS;
+ }
+ break;
+
+ case DDR_TRAINING_IP_SM_VERIFY:
+ if ((DDRCFG->DFI.STAT_DFI_TRAINING_COMPLETE.STAT_DFI_TRAINING_COMPLETE & 0x01U) == 0x01U)
+ {
+ /*
+ * Step 15:
+ * check worked for each lane
+ */
+ uint32_t lane_sel, t_status = 0U;
+ for (lane_sel=0U; lane_sel< \
+ LIBERO_SETTING_DATA_LANES_USED; lane_sel++)
+ {
+ SIM_FEEDBACK1(1000U);
+ delay(10U);
+ SIM_FEEDBACK1(1001U);
+ CFG_DDR_SGMII_PHY->lane_select.lane_select =\
+ lane_sel;
+ delay(10U);
+ /*
+ * verify cmd address results
+ * rejects if not acceptable
+ * */
+ {
+ uint32_t ca_status[8]= {\
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0>>8U)&0xFFU), \
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0>>16U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0>>24U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1>>8U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1>>16U)&0xFFU),\
+ ((CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1>>24U)&0xFFU)};
+ uint32_t low_ca_dly_count = 0U;
+ uint32_t last = 0U;
+ uint32_t decrease_count = 0U;
+ for(uint32_t i =0U; i<8U;i++)
+ {
+ if(ca_status[i] < 5U)
+ {
+ low_ca_dly_count++;
+ }
+ if(ca_status[i]<=last)
+ {
+ decrease_count++;
+ }
+ last = ca_status[i];
+ }
+ if(ca_status[0]<= ca_status[7U])
+ {
+ decrease_count++;
+ }
+ if((LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT) != ADDCMD_BIT)
+ {
+ /* Retrain if abnormal CA training result detected */
+ if(low_ca_dly_count > ABNORMAL_RETRAIN_CA_DLY_DECREASE_COUNT)
+ {
+ t_status = t_status | 0x01U;
+ }
+ /* Retrain if abnormal CA training result detected */
+ if(decrease_count > ABNORMAL_RETRAIN_CA_DECREASE_COUNT)
+ {
+ t_status = t_status | 0x01U;
+ }
+ }
+ }
+ /* Check that gate training passed without error */
+ t_status =t_status |\
+ CFG_DDR_SGMII_PHY->gt_err_comb.gt_err_comb;
+ delay(10U);
+ /* Check that DQ/DQS training passed without error */
+ if(CFG_DDR_SGMII_PHY->dq_dqs_err_done.dq_dqs_err_done != 8U)
+ {
+ t_status = t_status | 0x01U;
+ }
+ /* Check that DQ/DQS calculated window is above 5 taps. */
+ if(CFG_DDR_SGMII_PHY->dqdqs_status1.dqdqs_status1 < \
+ DQ_DQS_NUM_TAPS)
+ {
+ t_status = t_status | 0x01U;
+ }
+#ifdef DCT_EXTRA_CHECKS /* todo: Theses checks was added by DCT */
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly)&0xFFU) == 0U) // Gate training tx_dly check: AL
+ {
+ t_status = t_status | 0x01U;
+ }
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly>>8U)&0xFFU) == 0U)
+ {
+ t_status = t_status | 0x01U;
+ }
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly>>16U)&0xFFU) == 0U)
+ {
+ t_status = t_status | 0x01U;
+ }
+ if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly>>24U)&0xFFU) == 0U)
+ {
+ t_status = t_status | 0x01U;
+ }
+#endif
+ }
+ #ifdef RENODE_DEBUG
+ t_status = 0U; /* Dummy success -move on to
+ next stage */
+ #endif
+ if(t_status == 0U)
+ {
+ SIM_FEEDBACK1(21U);
+ /*
+ * We can now set vref on the memory
+ * mode register for lpddr4
+ * May include other modes, and include a sweep
+ * Alister looking into this and will revert.
+ */
+ if (ddr_type == LPDDR4)
+ {
+#ifdef SET_VREF_LPDDR4_MODE_REGS
+ mode_register_write(DDR_MODE_REG_VREF,\
+ DDR_MODE_REG_VREF_VALUE);
+#endif
+ }
+ ddr_training_state = DDR_TRAINING_SET_FINAL_MODE;
+ }
+ else /* fail, try again */
+ {
+ SIM_FEEDBACK1(20U);
+ ddr_training_state = DDR_TRAINING_FAIL_SM_VERIFY;
+ }
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_SM2_VERIFY;
+ }
+ break;
+
+
+ case DDR_TRAINING_SET_FINAL_MODE:
+ /*
+ * Set final mode register value.
+ */
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ LIBERO_SETTING_DDRPHY_MODE;
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR FINAL_MODE: ",\
+ LIBERO_SETTING_DDRPHY_MODE);
+#ifdef DEBUG_DDR_CFG_DDR_SGMII_PHY
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)CFG_DDR_SGMII_PHY,\
+ (sizeof(CFG_DDR_SGMII_PHY_TypeDef)/4U));
+#endif
+#ifdef DEBUG_DDR_DDRCFG
+ debug_read_ddrcfg();
+#endif
+#endif
+#ifdef DEBUG_DDR_INIT
+ {
+ tip_register_status (g_debug_uart);
+ (void)uprint32(g_debug_uart, "\n\r ****************************************************", 0U);
+
+ }
+#endif
+ ddr_training_state = DDR_TRAINING_WRITE_CALIBRATION;
+ break;
+
+ case DDR_TRAINING_WRITE_CALIBRATION:
+ /*
+ * Does the following in the DDRC need to be checked??
+ * DDRCFG->DFI.STAT_DFI_TRAINING_COMPLETE.STAT_DFI_TRAINING_COMPLETE;
+ *
+ */
+ number_of_lanes_to_calibrate = get_num_lanes();
+ /*
+ * Now start the write calibration as training has been successful
+ */
+ if(error == 0U)
+ {
+ if (ddr_type == LPDDR4)
+ {
+ uint8_t lane;
+ /* Changed default value to centre dq/dqs on window */
+ CFG_DDR_SGMII_PHY->rpc220.rpc220 = 0xCUL;
+ for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++)
+ {
+ load_dq(lane);
+ }
+ SIM_FEEDBACK1(1U);
+
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+ error =\
+ write_calibration_lpddr4_using_mtc(\
+ number_of_lanes_to_calibrate);
+#else
+ error =\
+ write_calibration_using_mtc(\
+ number_of_lanes_to_calibrate);
+#endif
+ }
+ else
+ {
+ SIM_FEEDBACK1(2U);
+ error =\
+ write_calibration_using_mtc(number_of_lanes_to_calibrate);
+ }
+ if(error)
+ {
+ ddr_error_count++;
+ SIM_FEEDBACK1(106U);
+ }
+ }
+#if (EN_RETRY_ON_FIRST_TRAIN_PASS == 1)
+ if((error == 0U)&&(retry_count != 0U))
+#else
+ if(error == 0U)
+#endif
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r wr calib result ",\
+ calib_data.write_cal.lane_calib_result);
+#endif
+ ddr_training_state = DDR_SWEEP_CHECK;
+ }
+ else if(error == MTC_TIMEOUT_ERROR)
+ {
+ error = 0U;
+ ddr_training_state = DDR_TRAINING_FAIL_DDR_SANITY_CHECKS;
+ }
+ else
+ {
+ error = 0U;
+ ddr_training_state = DDR_TRAINING_WRITE_CALIBRATION_RETRY;
+ }
+ break;
+
+ case DDR_TRAINING_WRITE_CALIBRATION_RETRY:
+ /*
+ * Clear write calibration data
+ */
+ memfill((uint8_t *)&calib_data,0U,sizeof(calib_data));
+ /*
+ * Try the next offset
+ */
+ write_latency++;
+ if (write_latency > MAX_LATENCY)
+ {
+ write_latency = MIN_LATENCY;
+ ddr_training_state = DDR_TRAINING_FAIL_MIN_LATENCY;
+ }
+ else
+ {
+ DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT =\
+ write_latency;
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\
+ write_latency);
+#endif
+ ddr_training_state = DDR_TRAINING_WRITE_CALIBRATION;
+ }
+ break;
+
+ case DDR_SWEEP_CHECK:
+#ifdef SWEEP_ENABLED
+ if((retry_count != 0U)&&(retry_count < (TOTAL_SWEEPS-1U)))
+ {
+ ddr_training_state = DDR_SWEEP_AGAIN;
+ }
+ else
+#endif
+ {
+ ddr_training_state = DDR_SANITY_CHECKS;
+ }
+ break;
+
+ case DDR_SANITY_CHECKS:
+ /*
+ * Now start the write calibration if training successful
+ */
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR SANITY_CHECKS: ",\
+ error);
+#endif
+ if(error == 0U)
+ {
+#ifdef DDR_SANITY_CHECKS_EN
+ error = memory_tests();
+#endif
+ }
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_MTC_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_DDR_SANITY_CHECKS;
+ }
+ break;
+
+ case DDR_FULL_MTC_CHECK:
+ {
+ uint64_t start_address = 0x0000000000000000ULL;
+ uint32_t size = ONE_MB_MTC; /* Number of reads for each iteration 2**size*/
+ uint8_t mask;
+ if (get_num_lanes() <= 3U)
+ {
+ mask = 0x3U;
+ }
+ else
+ {
+ mask = 0xFU;
+ }
+ error = MTC_test(mask, start_address, size, MTC_COUNTING_PATTERN, MTC_ADD_SEQUENTIAL, &error);
+ /* Read using different patterns */
+ error = 0U;
+ error |= MTC_test(mask, start_address, size, MTC_COUNTING_PATTERN, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_WALKING_ONE, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_NO_REPEATING_PSEUDO_RANDOM, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_ONES_ZEROS, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_5_A, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_16BIT, MTC_ADD_SEQUENTIAL, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_8BIT, MTC_ADD_SEQUENTIAL, &error);
+
+ error |= MTC_test(mask, start_address, size, MTC_COUNTING_PATTERN, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_WALKING_ONE, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_NO_REPEATING_PSEUDO_RANDOM, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_ONES_ZEROS, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_ALT_5_A, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_16BIT, MTC_ADD_RANDOM, &error);
+ error |= MTC_test(mask, start_address, size, MTC_PSEUDO_RANDOM_8BIT, MTC_ADD_RANDOM, &error);
+ }
+ if(error == 0U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r Passed MTC full check ", error);
+#endif
+ ddr_training_state = DDR_FULL_32BIT_NC_CHECK;
+ }
+ else
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r Failed MTC full check ", error);
+#endif
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+
+ case DDR_FULL_32BIT_NC_CHECK:
+ /*
+ * write and read back test from drr, non cached access
+ */
+ {
+#if (DDR_FULL_32BIT_NC_CHECK_EN == 1)
+ error = ddr_read_write_fn((uint64_t*)LIBERO_SETTING_DDR_32_NON_CACHE,\
+ SW_CFG_NUM_READS_WRITES,\
+ SW_CONFIG_PATTERN);
+#endif
+ }
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_32BIT_CACHE_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_FULL_32BIT_NC_CHECK;
+ }
+ break;
+ case DDR_FULL_32BIT_CACHE_CHECK:
+#if (DDR_FULL_32BIT_CACHED_CHECK_EN == 1)
+ error = ddr_read_write_fn((uint64_t*)LIBERO_SETTING_DDR_32_CACHE,\
+ SW_CFG_NUM_READS_WRITES,\
+ SW_CONFIG_PATTERN);
+#endif
+ if(error == 0U)
+ {
+#ifdef SKIP_VERIFY_PATTERN_IN_CACHE
+ ddr_training_state = DDR_FULL_32BIT_WRC_CHECK;
+#else
+ ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE;
+#endif
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL_32BIT_CACHE_CHECK;
+ }
+ break;
+ case DDR_LOAD_PATTERN_TO_CACHE:
+ load_ddr_pattern(LIBERO_SETTING_DDR_32_CACHE, SIZE_OF_PATTERN_TEST, SIZE_OF_PATTERN_OFFSET);
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_VERIFY_PATTERN_IN_CACHE;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_VERIFY_PATTERN_IN_CACHE:
+ error = test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST);
+ if(error == 0U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\
+ write_latency);
+#if (TUNE_RPC_166_VALUE == 1)
+ (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\
+ rpc_166_fifo_offset);
+#endif
+#endif
+ ddr_training_state = DDR_FULL_32BIT_WRC_CHECK;
+ }
+ else
+ {
+#if (TUNE_RPC_166_VALUE == 1)
+
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\
+ rpc_166_fifo_offset);
+#endif
+
+#ifdef NOT_A_FULL_RETRAIN
+
+ /* this fails post tests */
+ if(num_rpc_166_retires < NUM_RPC_166_VALUES)
+ {
+ num_rpc_166_retires++;
+ rpc_166_fifo_offset++;
+ if(rpc_166_fifo_offset > MAX_RPC_166_VALUE)
+ {
+ rpc_166_fifo_offset = MIN_RPC_166_VALUE;
+ }
+ /* try again here DDR_LOAD_PATTERN_TO_CACHE */
+ }
+ else
+ {
+ num_rpc_166_retires = 0U;
+ rpc_166_fifo_offset = DEFAULT_RPC_166_VALUE;
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ CFG_DDR_SGMII_PHY->rpc166.rpc166 = rpc_166_fifo_offset;
+ //PAUSE to reset fifo (loads new RXPTR value).
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x1U;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x0000003EU;
+ CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\
+ 0x00000000U;
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U;
+ //delay(10);
+ //END PAUSE
+#else
+ if(num_rpc_166_retires < NUM_RPC_166_VALUES)
+ {
+ num_rpc_166_retires++;
+ rpc_166_fifo_offset++;
+ if(rpc_166_fifo_offset > MAX_RPC_166_VALUE)
+ {
+ rpc_166_fifo_offset = MIN_RPC_166_VALUE;
+ }
+ /* try again here DDR_LOAD_PATTERN_TO_CACHE */
+ }
+ else
+ {
+ num_rpc_166_retires = 0U;
+ rpc_166_fifo_offset = DEFAULT_RPC_166_VALUE;
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ ddr_training_state = DDR_TRAINING_FAIL;
+#endif
+#else /* (TUNE_RPC_166_VALUE == 0) */
+ ddr_training_state = DDR_TRAINING_FAIL;
+#endif
+ }
+ break;
+ case DDR_FULL_32BIT_WRC_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_64BIT_NC_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_FULL_64BIT_NC_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_64BIT_CACHE_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_FULL_64BIT_CACHE_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_FULL_64BIT_WRC_CHECK;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+ break;
+ case DDR_FULL_64BIT_WRC_CHECK:
+ if(error == 0U)
+ {
+ ddr_training_state = DDR_TRAINING_VREFDQ_CALIB;
+ }
+ else
+ {
+ ddr_training_state = DDR_TRAINING_FAIL;
+ }
+
+ break;
+
+ case DDR_TRAINING_VREFDQ_CALIB:
+#ifdef VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+ error = VREFDQ_calibration_using_mtc();
+ if(error != 0U)
+ {
+ ddr_error_count++;
+ }
+#endif
+ ddr_training_state = DDR_TRAINING_FPGA_VREFDQ_CALIB;
+ break;
+
+ case DDR_TRAINING_FPGA_VREFDQ_CALIB:
+#ifdef FPGA_VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+ error = FPGA_VREFDQ_calibration_using_mtc();
+ if(error != 0U)
+ {
+ ddr_error_count++;
+ }
+#endif
+ ddr_training_state = DDR_TRAINING_FINISH_CHECK;
+ break;
+
+ case DDR_TRAINING_FINISH_CHECK:
+ /*
+ * return status
+ */
+#ifdef DEBUG_DDR_INIT
+ {
+ tip_register_status (g_debug_uart);
+ (void)uprint32(g_debug_uart, "\n\r\n\r DDR_TRAINING_PASS: ",\
+ ddr_training_state);
+ (void)uprint32(g_debug_uart, "\n ****************************************************", 0);
+
+ }
+#endif
+ if(ddr_error_count > 0)
+ {
+ ret_status |= DDR_SETUP_FAIL;
+ }
+ else
+ {
+ /*
+ * Configure Segments- address mapping, CFG0/CFG1
+ */
+ setup_ddr_segments(LIBERO_SEG_SETUP);
+ }
+ ret_status |= DDR_SETUP_DONE;
+ ddr_training_state = DDR_TRAINING_FINISHED;
+ break;
+
+ default:
+ case DDR_TRAINING_FINISHED:
+ break;
+ } /* end of case statement */
+
+ return (ret_status);
+}
+
+
+/**
+ * get_num_lanes(void)
+ * @return number of lanes used, 2(16 bit), 3(16 bit + ecc), 4(32 bit) or 5
+ * Note: Lane 4 always used when ECC enabled, even for x16
+ */
+static uint8_t get_num_lanes(void)
+{
+ uint8_t lanes;
+ /* Check width, 16bit or 32bit bit supported, 1 => 32 bit */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_BUS_WIDTH_MASK) ==\
+ DDRPHY_MODE_BUS_WIDTH_4_LANE)
+ {
+ lanes = 4U;
+ }
+ else
+ {
+ lanes = 2U;
+ }
+ /* Check if using ECC, add a lane */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_ECC_MASK) ==\
+ DDRPHY_MODE_ECC_ON)
+ {
+ lanes++;
+ }
+ return lanes;
+}
+
+
+
+/***************************************************************************//**
+ * set_ddr_mode_reg_and_vs_bits()
+ *
+ */
+static void set_ddr_mode_reg_and_vs_bits(uint32_t dpc_bits)
+{
+ DDR_TYPE ddr_type = LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK;
+ /*
+ * R1.6
+ * Write DDR phy mode reg (eg DDR3)
+ * When we write to the mode register, an ip state machine copies default
+ * values for the particular mode chosen to RPC registers associated with
+ * DDR in the MSS custom block.
+ * ( Note: VS bits are not include in the copy so we set below )
+ * The RPC register values are transferred to the SCB registers in a
+ * subsequent step.
+ */
+ /*
+ * Set VS bits
+ * Select VS bits for DDR mode selected --- set dynamic pc bit settings to
+ * allow editing of RPC registers
+ * pvt calibration etc
+ *
+ * [19] dpc_move_en_v enable dynamic control of vrgen circuit for
+ * ADDCMD pins
+ * [18] dpc_vrgen_en_v enable vref generator for ADDCMD pins
+ * [17:12] dpc_vrgen_v reference voltage ratio setting for ADDCMD
+ * pins
+ * [11:11] dpc_move_en_h enable dynamic control of vrgen circuit for
+ * DQ/DQS pins
+ * [10:10] dpc_vrgen_en_h enable vref generator for DQ/DQS pins
+ * [9:4] dpc_vrgen_h reference voltage ratio setting for DQ/DQS
+ * pins
+ * [3:0] dpc_vs bank voltage select for pvt calibration
+ */
+ /*
+ DDRPHY_MODE setting from MSS configurator
+ DDRMODE :3;
+ ECC :1;
+ CRC :1;
+ Bus_width :3;
+ DMI_DBI :1;
+ DQ_drive :2;
+ DQS_drive :2;
+ ADD_CMD_drive :2;
+ Clock_out_drive :2;
+ DQ_termination :2;
+ DQS_termination :2;
+ ADD_CMD_input_pin_termination :2;
+ preset_odt_clk :2;
+ Power_down :1;
+ rank :1;
+ Command_Address_Pipe :2;
+ */
+ {
+ if ((ddr_type == DDR4) &&\
+ (LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_ECC_MASK) ==\
+ DDRPHY_MODE_ECC_ON)
+ {
+ /*
+ * For ECC on when DDR4, and data mask on during training, training
+ * will not pass
+ * This will eventually be handled by the configurator
+ * DM will not be allowed for DDR4 with ECC
+ */
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ (LIBERO_SETTING_DDRPHY_MODE & DMI_DBI_MASK );
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ LIBERO_SETTING_DDRPHY_MODE;
+ }
+ delay((uint32_t) 100U);
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS = dpc_bits;
+ }
+}
+
+
+
+/***************************************************************************//**
+ * set_ddr_rpc_regs()
+ * @param ddr_type
+ */
+static void set_ddr_rpc_regs(DDR_TYPE ddr_type)
+{
+ /*
+ * Write DDR phy mode reg (eg DDR3)
+ * When we write to the mode register, an ip state machine copies default
+ * values for the particular mode chossen
+ * to RPC registers associated with DDR in the MSS custom block.
+ * The RPC register values are transferred to the SCB registers in a
+ * subsequent step.
+ *
+ * Question:
+ * Select VS bits (eg DDR3 ) (vs bits not included in mode setup - should
+ * be??)
+ * Small wait while state machine transfer takes place required here.
+ * (status bit required?)
+ *
+ */
+ /*
+ DDRPHY_MODE setting from MSS configurator
+ DDRMODE :3;
+ ECC :1;
+ CRC :1;
+ Bus_width :3;
+ DMI_DBI :1;
+ DQ_drive :2;
+ DQS_drive :2;
+ ADD_CMD_drive :2;
+ Clock_out_drive :2;
+ DQ_termination :2;
+ DQS_termination :2;
+ ADD_CMD_input_pin_termination :2;
+ preset_odt_clk :2;
+ Power_down :1;
+ rank :1;
+ Command_Address_Pipe :2;
+ */
+ {
+ switch (ddr_type)
+ {
+ default:
+ case DDR_OFF_MODE:
+ /* Below have already been set */
+ /* CFG_DDR_SGMII_PHY->rpc95.rpc95 = 0x07; */ /* addcmd I/O*/
+ /* CFG_DDR_SGMII_PHY->rpc96.rpc96 = 0x07; */ /* clk */
+ /* CFG_DDR_SGMII_PHY->rpc97.rpc97 = 0x07; */ /* dq */
+ /* CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x07; */ /* dqs */
+ /*
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ break;
+ case DDR3L:
+ case DDR3:
+ /* Required when rank x 2 */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_RANK_MASK) ==\
+ DDRPHY_MODE_TWO_RANKS)
+ {
+ CFG_DDR_SGMII_PHY->spio253.spio253 = 1U;
+ }
+
+ {
+ /*
+ * firmware set this to 3'b100 for all cases except when we
+ * are in OFF mode (DDR3,DDR4,LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ }
+ /*
+ * SAR xxxx
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ break;
+ case DDR4:
+ {
+ /*
+ * Sar 108017
+ * ODT_STATIC setting is wrong for DDR4/LPDDR3, needs to
+ * be overwritten in embedded SW for E51
+ *
+ * ODT_STATIC is set to 001 for DQ/DQS/DBI bits in
+ * DDR3/LPDDR4, this enables termination to VSS.
+ *
+ * This needs to be switched to VDDI termination.
+ *
+ * To do this, we do APB register writes to override
+ * the following PC bits:
+ * odt_static_dq=010
+ * odt_static_dqs=010
+ */
+ CFG_DDR_SGMII_PHY->rpc10_ODT.rpc10_ODT = 2U;
+ CFG_DDR_SGMII_PHY->rpc11_ODT.rpc11_ODT = 2U;
+ /*
+ * SAR 108218
+ * The firmware should set this to 3'b100 for
+ * all cases except when we are in OFF mode (DDR3,DDR4,
+ * LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ /*
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ }
+ break;
+ case LPDDR3:
+ {
+ /*
+ * Sar 108017
+ * ODT_STATIC setting is wrong for DDR4/LPDDR3, needs to be
+ * overwritten in embedded SW for E51
+ *
+ * ODT_STATIC is set to 001 for DQ/DQS/DBI bits in
+ * DDR3/LPDDR4, this enables termination to VSS.
+ *
+ * This needs to be switched to VDDI termination.
+ *
+ * To do this, we should do APB register writes to override
+ * the following PC bits:
+ * odt_static_dq=010
+ * odt_static_dqs=010
+ */
+ CFG_DDR_SGMII_PHY->rpc10_ODT.rpc10_ODT = 2U;
+ CFG_DDR_SGMII_PHY->rpc11_ODT.rpc11_ODT = 2U;
+ /*
+ * SAR 108218
+ * I've reviewed the results, and the ibufmd bit should be
+ * fixed in firmware for ibufmd_dqs. Malachy please have
+ * the firmware set this to 3'b100 for all cases except
+ * when we are in OFF mode (DDR3,DDR4,LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ /*
+ * SAR xxxx
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0U;
+ }
+ break;
+ case LPDDR4:
+ {
+ /*
+ * We need to be able to implement different physical
+ * configurations of LPDDR4, given the twindie architecture.
+ * These are not fully decoded by the APB decoder (we dont
+ * have all the options).
+ * Basically we want to support:
+ * Hook the CA buses from the 2 die up in parallel on the
+ * same FPGA pins
+ * Hook the CA buses from the 2 die up in parallel using
+ * the mirrored FPGA pins (IE CA_A/CA_B)
+ * Some combination of the 2, ie duplicate the clocks but
+ * not the CA, duplicate the clocks and command, but not
+ * address, etc.
+ */
+ /* OVRT_EN_ADDCMD1 (default 0xF00), register named ovrt11 */
+#ifndef LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9
+ /*
+ * If this define is not present, indicates older
+ * Libero core (pre 2.0.109)
+ * So we run this code
+ */
+ CFG_DDR_SGMII_PHY->ovrt10.ovrt10 =\
+ LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10;
+ {
+ /* Use pull-ups to set the CMD/ADD ODT */
+ CFG_DDR_SGMII_PHY->rpc245.rpc245 =\
+ 0x00000000U;
+
+ CFG_DDR_SGMII_PHY->rpc237.rpc237 =\
+ 0xffffffff;
+ }
+
+ /* OVRT_EN_ADDCMD2 (default 0xE06U), register named ovrt12 */
+ CFG_DDR_SGMII_PHY->ovrt11.ovrt11 =\
+ LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11;
+#endif
+ /* Required when rank x 2 */
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_RANK_MASK) ==\
+ DDRPHY_MODE_TWO_RANKS)
+ {
+ /* todo: need to verify this setting with verification */
+ CFG_DDR_SGMII_PHY->spio253.spio253 = 1;
+ }
+
+ {
+ /*
+ * SAR 108218
+ * I've reviewed the results, and the ibufmd bit should be
+ * fixed in firmware for ibufmd_dqs. Malachy please have the
+ * firmware set this to 3'b100 for all cases except when we
+ * are in OFF mode (DDR3,DDR4,LPDDR3,LPDDR4).
+ */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x04U;
+ }
+ /*
+ * SAR xxxx
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0xA000U;
+
+ }
+
+ break;
+ }
+ }
+
+ {
+
+ /*
+ * sar107009 found by Paul in Crevin,
+ * This has been fixed in tag g5_mss_ddrphy_apb tag 2.9.130
+ * todo: remove this software workaround as no longer required
+ *
+ * Default of rpc27 should be 2, currently is 0
+ * We will set to 2 for the moment with software.
+ */
+ CFG_DDR_SGMII_PHY->rpc27.rpc27 = 0x2U;
+ /*
+ * Default of rpc27 Issue see by Paul/Alister 10th June
+ * tb_top.duv_wrapper.u_design.mss_custom.gbank6.tip.gapb.\
+ * MAIN.u_apb_mss_decoder_io.rpc203_spare_iog_dqsn
+ */
+ CFG_DDR_SGMII_PHY->rpc203.rpc203 = 0U;
+ }
+
+ {
+ /*
+ *
+ * We'll have to pass that one in via E51, meaning APB writes to
+ * addresses:
+ * 0x2000 7384 rpc1_ODT ODT_CA
+ * 0x2000 7388 rpc2_ODT RPC_ODT_CLK
+ * 0x2000 738C rpc3_ODT ODT_DQ
+ * 0x2000 7390 rpc4_ODT ODT_DQS
+ *
+ * todo: replace with Libero settings below, once values verified
+ */
+ CFG_DDR_SGMII_PHY->rpc1_ODT.rpc1_ODT = LIBERO_SETTING_RPC_ODT_ADDCMD;
+ CFG_DDR_SGMII_PHY->rpc2_ODT.rpc2_ODT = LIBERO_SETTING_RPC_ODT_CLK;
+ CFG_DDR_SGMII_PHY->rpc3_ODT.rpc3_ODT = LIBERO_SETTING_RPC_ODT_DQ;
+ CFG_DDR_SGMII_PHY->rpc4_ODT.rpc4_ODT = LIBERO_SETTING_RPC_ODT_DQS;
+ }
+ {
+ /*
+ * bclk_sel_clkn - selects bclk sclk training clock
+ */
+ CFG_DDR_SGMII_PHY->rpc19.rpc19 = 0x01U; /* bclk_sel_clkn */
+ /*
+ * add cmd - selects bclk sclk training clock
+ */
+ CFG_DDR_SGMII_PHY->rpc20.rpc20 = 0x00U; /* bclk_sel_clkp */
+
+ }
+
+ {
+ /*
+ * Each lane has its own FIFO. This paramater adjusts offset for all lanes.
+ */
+#if (TUNE_RPC_166_VALUE == 1)
+ CFG_DDR_SGMII_PHY->rpc166.rpc166 = rpc_166_fifo_offset;
+#endif
+ }
+
+ /*
+ * Override RPC bits for weak PU and PD's
+ * Set over-ride bit for unused I/O
+ */
+ config_ddr_io_pull_up_downs_rpc_bits(ddr_type);
+}
+
+/**
+ Info on OFF modes:
+
+ OFF MODE from reset- I/O not being used
+ MSSIO from reset- non default values
+ Needs non default values to completely go completely OFF
+ Drive bits and ibuff mode
+ Ciaran to define what need to be done
+ SAR107676
+ DDR - by default put to DDR4 mode so needs active intervention
+ Bills sac spec (DDR PHY SAC spec section 6.1)
+ Mode register set to 7
+ Ibuff mode set to 7 (rx turned off)
+ P-Code/ N-code of no relevance as not used
+ Disable DDR PLL
+ Will be off from reset- no need
+ Need to reflash
+ DDR APB ( three resets - soft reset bit 0 to 1)
+ Drive odt etc
+ SGMII - from reset nothing to be done
+ See Jeff's spread sheet- default values listed
+ Extn clock off also defined in spread sheet
+ */
+
+
+/**
+ * ddr_off_mode(void)
+ * Assumed in Dynamic mode.
+ * i.e.
+ * SCB dynamic enable bit is high
+ * MSS core_up = 1
+ * dce[0,1,2] 0,0,0
+ * flash valid = 1
+ * IP:
+ * DECODER_DRIVER, ODT, IO all out of reset
+ *
+ * DDR PHY off mode that I took from version 1.58 of the DDR SAC spec.
+ * 1. DDR PHY OFF mode (not used at all).
+ * 1. Set the DDR_MODE register to 7
+ * This will disable all the drive and ODT to 0, as well as set all WPU bits.
+ * 2. Set the RPC_IBUF_MD_* registers to 7
+ * This will disable all receivers.
+ * 3. Set the REG_POWERDOWN_B register to 0
+ * This will disable the DDR PLL
+ *
+ */
+static void ddr_off_mode(void)
+{
+ /*
+ * DDR PLL is not turn on on reset- so no need to do anything
+ */
+ /*
+ * set the mode register to 7 => off mode
+ * From the DDRPHY training firmware spec.:
+ * If the DDR interface is unused, the firmware will have to write 3'b111
+ * into the APB_DDR_MODE register. This will disable all the DRIVERs, ODT
+ * and INPUT receivers.
+ * By default, WPD will be applied to all pads.
+ *
+ * If a user wants to apply WPU, this will have to be applied through
+ * firmware, by changing all RPC_WPU_*=0, and RPC_WPD_*=1, via APB register
+ * writes.
+ *
+ * Unused IO within an interface will automatically be shut off, as unused
+ * DQ/DM/DQS/and CA buffers and odt are automatically disabled by the
+ * decode, and put into WPD mode.
+ * Again, if the user wants to change this to WPU, the will have to write
+ * RPC_WPU_*=0 and RPC_WPD_*=1 to override the default.
+ *
+ */
+ /* Note: DMI_DBI [8:1] needs to be 0 (off) during training */
+ CFG_DDR_SGMII_PHY->DDRPHY_MODE.DDRPHY_MODE =\
+ (LIBERO_SETTING_DDRPHY_MODE_OFF /* & DMI_DBI_MASK */);
+ /*
+ * VS for off mode
+ */
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ LIBERO_SETTING_DPC_BITS_OFF_MODE;
+
+ /*
+ * Toggle decoder here
+ * bit 0 == PERIPH soft reset, auto cleared
+ */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_DRIVER.SOFT_RESET_DECODER_DRIVER= 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_ODT.SOFT_RESET_DECODER_ODT = 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_DECODER_IO.SOFT_RESET_DECODER_IO = 1U;
+
+ /*
+ * set ibuff mode to 7 in off mode
+ *
+ */
+ CFG_DDR_SGMII_PHY->rpc95.rpc95 = 0x07; /* addcmd I/O*/
+ CFG_DDR_SGMII_PHY->rpc96.rpc96 = 0x07; /* clk */
+ CFG_DDR_SGMII_PHY->rpc97.rpc97 = 0x07; /* dq */
+ CFG_DDR_SGMII_PHY->rpc98.rpc98 = 0x07; /* dqs */
+
+ /*
+ * Default WPU, modify If user wants Weak Pull Up
+ */
+ /*
+ * UNUSED_SPACE0
+ * bits 15:14 connect to ibufmx DQ/DQS/DM
+ * bits 13:12 connect to ibufmx CA/CK
+ * todo: Do we need to add Pu/PD option for off mode to Libero setting?
+ */
+ CFG_DDR_SGMII_PHY->UNUSED_SPACE0[0] = 0x0000U;
+
+ /*
+ * REG_POWERDOWN_B on PLL turn-off, in case was turned on.
+ */
+ ddr_pll_config_scb_turn_off();
+ return;
+}
+
+
+/***************************************************************************//**
+ * Number of tests which write and read from DDR
+ * Tests data path through the cache and through AXI4 switch.
+ */
+#ifdef DDR_SANITY_CHECKS_EN
+static uint8_t memory_tests(void)
+{
+ uint64_t shift_walking_one = 4U;
+ uint64_t start_address = 0x0000000000000000U;
+ uint8_t error = 0U;
+ SIM_FEEDBACK1(199U);
+ /*
+ * Verify seg1 reg 2, datapath through AXI4 switch
+ */
+ while(shift_walking_one <= 28U) /* 28 => 1G, as 2**28 == 256K and this is
+ mult by (4 lanes) */
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0xC0000000U + (0x1U< 1G
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x1400000000U + (0x1U<= 4U)
+ {
+ start_address = (uint64_t)(0x1400000000U + \
+ (((0x1U<<(shift_walking_one +1)) - 1U) -0x0F) );
+ error = rw_sanity_chk((uint64_t *)start_address , (uint32_t)0x5U);
+
+ if(error)
+ {
+ ddr_error_count++;
+ SIM_FEEDBACK1(201U);
+ }
+ }
+
+ shift_walking_one++;
+ }
+ /*
+ * Verify mtc
+ */
+ SIM_FEEDBACK1(600U);
+ shift_walking_one = 4U;
+ while(shift_walking_one <= 28U) //28 => 1G
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x1U<= 4U)
+ {
+ start_address = (uint64_t)((((0x1U<<(shift_walking_one +1)) - 1U)\
+ -0x0F) );
+ error = mtc_sanity_check(start_address);
+
+ if(error)
+ {
+ ddr_error_count++;
+ SIM_FEEDBACK1(204U);
+ }
+ }
+ shift_walking_one++;
+ }
+
+ /*
+ * Verify seg0 reg 0, datapath through cache
+ */
+ SIM_FEEDBACK1(700U);
+ shift_walking_one = 4U;
+ while(shift_walking_one <= 27U) //28 => 1G
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x80000000U + (0x1U< 1G (0x10000000(address) * 4 (32bits wide))
+ {
+ SIM_FEEDBACK1(shift_walking_one);
+ start_address = (uint64_t)(0x1000000000U + (0x1U<expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\
+ & (uint32_t)~0x0FU);
+ }
+ //set expert_dfi_status_override_to_shim = 0x7
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U;
+ //set expert_mode_en = 0x21
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x21U;
+ //set dyn_ovr_dlycnt_dq_load* = 1
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 =\
+ (0xFFU << (lane * 8U));
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 |=\
+ 0x0FU;
+ }
+ //set dyn_ovr_dlycnt_dq_load* = 0
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 = 0U;
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1\
+ & (uint32_t)~0x0FU);
+ }
+ //set expert_mode_en = 0x8
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U;
+}
+
+/***************************************************************************//**
+ * increment_dq()
+ * set dyn_ovr_dlycnt_dq_move* = 0
+ * set dyn_ovr_dlycnt_dq_direction* = 1
+ * set expert_dfi_status_override_to_shim = 0x7
+ * set expert_mode_en = 0x21
+ *
+ * #to increment multiple times loop the move=0/1 multiple times
+ * set dyn_ovr_dlycnt_dq_move* = 1
+ * set dyn_ovr_dlycnt_dq_move* = 0
+ * #
+ * set expert_mode_en = 0x8
+ * @param lane
+ * @param move_count
+ */
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+static void increment_dq(uint8_t lane, uint32_t move_count)
+{
+ //set dyn_ovr_dlycnt_dq_move* = 0
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\
+ & ~0x0FU);
+ }
+ //set dyn_ovr_dlycnt_dq_direction* = 1
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg0.expert_dlycnt_direction_reg0\
+ = (0xFFU << (lane * 8U));
+ }
+ else
+ {
+ /* only four lines, use 0xFU */
+ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 |= 0xFU;
+ }
+ /* set expert_dfi_status_override_to_shim = 0x7 */
+ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U;
+ /* set expert_mode_en = 0x21 */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x21U;
+ /* #to increment multiple times loop the move=0/1 multiple times */
+ move_count = move_count + move_count + move_count;
+ while(move_count)
+ {
+ // set dyn_ovr_dlycnt_dq_move* = 1
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0\
+ = (0xFFU << (lane * 8U));
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\
+ |= 0x0FU;
+ }
+ // set dyn_ovr_dlycnt_dq_move* = 0
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U;
+ if(lane < 4U)
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0\
+ = 0U;
+ }
+ else
+ {
+ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = \
+ (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 & ~0x0FU);
+ }
+ move_count--;
+ }
+ /* set expert_mode_en = 0x8 */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U;
+}
+#endif
+
+/***************************************************************************//**
+ *
+ */
+static void set_write_calib(uint8_t user_lanes)
+{
+ uint32_t temp = 0U;
+ uint8_t lane_to_set;
+ uint8_t shift = 0U;
+
+ /*
+ * Calculate the calibrated value and write back
+ */
+ calib_data.write_cal.lane_calib_result = 0U;
+ for (lane_to_set = 0x00U;\
+ lane_to_setexpert_mode_en.expert_mode_en = 0x00000008U;
+
+ SIM_FEEDBACK1(0xFF000000);
+ SIM_FEEDBACK1(calib_data.write_cal.lane_calib_result);
+ SIM_FEEDBACK1(0xFF000000);
+
+ /* set the calibrated value */
+ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib =\
+ calib_data.write_cal.lane_calib_result;
+}
+
+/***************************************************************************//**
+ *
+ * @param lane_to_set
+ */
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+static void set_calc_dq_delay_offset(uint8_t lane_to_set)
+{
+ uint32_t move_count;
+
+ load_dq(lane_to_set); /* set to start */
+
+ /* shift by 1 to divide by two */
+ move_count = ((calib_data.dq_cal.upper[lane_to_set] -\
+ calib_data.dq_cal.lower[lane_to_set] ) >> 1U) +\
+ calib_data.dq_cal.lower[lane_to_set];
+
+ increment_dq(lane_to_set, move_count);
+
+}
+#endif
+
+/***************************************************************************//**
+ *
+ * @param user_lanes
+ */
+#ifdef SW_CONFIG_LPDDR_WR_CALIB_FN
+static void set_calib_values(uint8_t user_lanes)
+{
+ uint8_t lane_to_set;
+ uint32_t move_count;
+
+ for (lane_to_set = 0x00U;\
+ lane_to_set< user_lanes ; lane_to_set++)
+ {
+ set_calc_dq_delay_offset(lane_to_set);
+ }
+
+ /* and set the write calibration calculated */
+ set_write_calib(user_lanes);
+}
+#endif
+
+
+/***************************************************************************//**
+ * write_calibration_using_mtc
+ * Use Memory Test Core plugged in to the front end of the DDR controller to
+ * perform lane-based writes and read backs and increment write calibration
+ * offset for each lane until data match occurs. The Memory Test Core is the
+ * basis for all training.
+ *
+ * @param number_of_lanes_to_calibrate
+ * @return
+ */
+static uint8_t \
+ write_calibration_using_mtc(uint8_t number_of_lanes_to_calibrate)
+{
+ uint8_t laneToTest;
+ uint32_t result = 0U;
+ uint32_t cal_data;
+ uint64_t start_address = 0x0000000000000000ULL;
+ uint32_t size = ONE_MB_MTC; /* Number of reads for each iteration 2**size*/
+
+ calib_data.write_cal.status_lower = 0U;
+ /*
+ * bit 3 must be set if we want to use the
+ * expert_wrcalib
+ * register
+ */
+ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000008U;
+
+ /*
+ * training carried out here- sweeping write calibration offset from 0 to F
+ * Explanation: A register, expert_wrcalib, is described in MSS DDR TIP
+ * Register Map [1], and its purpose is to delay--by X number of memory clock
+ * cycles--the write data, write data mask, and write output enable with the
+ * respect to the address and command for each lane.
+ */
+ for (cal_data=0x00000U;cal_data<0xfffffU;cal_data=cal_data+0x11111U)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\rCalibration offset used:",cal_data &0xFUL);
+#endif
+ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib = cal_data;
+
+ for (laneToTest = 0x00U; laneToTestMC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE = 0x01;
+ DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = MR_ADDR ;
+ /*
+ * next:
+ * write desired VREF calibration range (0=Range 1, 1=Range 2) to bit 6
+ * of MR6
+ * write 0x00 to bits 5:0 of MR6 (base calibration value)
+ */
+ DDRCFG->MC_BASE2.INIT_MR_WR_DATA.INIT_MR_WR_DATA = MR_DATA;
+ DDRCFG->MC_BASE2.INIT_MR_WR_MASK.INIT_MR_WR_MASK = 0U;
+
+ DDRCFG->MC_BASE2.INIT_MR_W_REQ.INIT_MR_W_REQ = 0x01U;
+ while((DDRCFG->MC_BASE2.INIT_ACK.INIT_ACK & 0x01U) == 0U) /* wait for ack-
+ to confirm register is written */
+ {
+ test--;
+ if(test-- == 0U)
+ {
+ result = 1U;
+ break;
+ }
+ }
+ return result;
+}
+#endif
+
+#define VREF_INVALID 0x01U
+/***************************************************************************//**
+ * FPGA_VREFDQ_calibration_using_mtc(void)
+ * vary DQ voltage and set optimum DQ voltage
+ * @return
+ */
+#ifdef VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+static uint8_t FPGA_VREFDQ_calibration_using_mtc(void)
+{
+ uint8_t laneToTest, result = 0U;
+ uint64_t mask;
+ uint32_t vRef;
+ uint64_t start_address = 0x0000000000000000ULL;
+ uint64_t size = 4U;
+
+ /*
+ * Step 2a. FPGA VREF (Local VREF training)
+ * Train FPGA VREF using the vrgen_h and vrgen_v registers
+ */
+ {
+ /*
+ * To manipulate the FPGA VREF value, firmware must write to the
+ * DPC_BITS register, located at physical address 0x2000 7184.
+ * Full documentation for this register can be found in
+ * DFICFG Register Map [4].
+ */
+ /*
+ * See DPC_BITS definition in .h file
+ */
+ /* CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_h; */
+ /* CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_v; */
+
+ }
+
+ /*
+ * training carried out here- sweeping write calibration offset from 0 to F
+ * Explanation: A register, expert_wrcalib, is described in MSS DDR TIP
+ * Register Map [1], and its purpose is to delay--by X number of memory
+ * clock cycles--the write data, write data mask, and write output enable
+ * with the respect to the address and command for each lane.
+ */
+ calib_data.fpga_vref.vref_result = 0U;
+ calib_data.fpga_vref.lower = VREF_INVALID;
+ calib_data.fpga_vref.upper = VREF_INVALID;
+ calib_data.fpga_vref.status_lower = 0x00U;
+ calib_data.fpga_vref.status_upper = 0x00U;
+ mask = 0xFU; /* todo: obtain data width from user parameters */
+ uint32_t count = 0U;
+ /* each bit .25% of VDD ?? */
+ for (vRef=(0x1U<<4U);vRef<(0x1fU<<4U);vRef=vRef+(0x1U<<4U))
+ {
+ /*
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (~(0x1U<<10U)));
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (~(0x1fU<<4U))) | vRef;
+ */
+ /* need to set via the SCB, otherwise reset required. So lines below
+ * rather than above used */
+
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits &\
+ (~(0x1U<<10U)));
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits &\
+ (~(0x1fU<<4U))) | vRef;
+
+
+ /* read one to flush MTC - this is required */
+ result = MTC_test(1U<>1U);
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (0x1fU<<4U)) | vRef;
+ /* need to set via the SCB, otherwise reset required. */
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits &\
+ (0x1fU<<4U)) | vRef;
+ }
+ else
+ {
+ result = 1U; /* failed to get good data at any voltage level */
+ }
+
+ return result;
+}
+
+#endif
+
+#ifdef VREFDQ_CALIB
+ /*
+ * This step is optional
+ * todo: Test once initial board verification complete
+ */
+#define MEM_VREF_INVALID 0xFFFFFFFFU
+/***************************************************************************//**
+ *
+ * VREFDQ_calibration_using_mtc
+ * In order to write to mode registers, the E51 must use the INIT_* interface
+ * at the front end of the DDR controller,
+ * which is available via a series of control registers described in the DDR
+ * CSR APB Register Map.
+ *
+ * @return
+ */
+static uint8_t VREFDQ_calibration_using_mtc(void)
+{
+ uint8_t laneToTest, result = 0U;
+ uint64_t mask;
+ uint32_t vRef;
+ uint64_t start_address = 0x00000000C0000000ULL;
+ uint64_t size = 4U;
+
+ /*
+ * Step 2a. FPGA VREF (Local VREF training)
+ * Train FPGA VREF using the vrgen_h and vrgen_v registers
+ */
+ {
+ /*
+ *
+ */
+ DDRCFG->MC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE = 0x01U;
+ DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = 6U ;
+ /*
+ * next:
+ * write desired VREF calibration range (0=Range 1, 1=Range 2) to bit 6
+ * of MR6
+ * write 0x00 to bits 5:0 of MR6 (base calibration value)
+ */
+ DDRCFG->MC_BASE2.INIT_MR_WR_DATA.INIT_MR_WR_DATA = 0U;
+ DDRCFG->MC_BASE2.INIT_MR_WR_MASK.INIT_MR_WR_MASK = (0x01U <<6U) |\
+ (0x3FU) ;
+
+ DDRCFG->MC_BASE2.INIT_MR_W_REQ.INIT_MR_W_REQ = 0x01U;
+ if((DDRCFG->MC_BASE2.INIT_ACK.INIT_ACK & 0x01U) == 0U) /* wait for ack-
+ to confirm register is written */
+ {
+
+ }
+ }
+
+ /*
+ * training carried out here- sweeping write calibration offset from 0 to F
+ * Explanation: A register, expert_wrcalib, is described in MSS DDR TIP
+ * Register Map [1], and its purpose is to delay--by X number of memory clock
+ * cycles--the write data, write data mask, and write output enable with the
+ * respect to the address and command for each lane.
+ */
+ calib_data.mem_vref.vref_result = 0U;
+ calib_data.mem_vref.lower = MEM_VREF_INVALID;
+ calib_data.mem_vref.upper = MEM_VREF_INVALID;
+ calib_data.mem_vref.status_lower = 0x00U;
+ calib_data.mem_vref.status_upper = 0x00U;
+ mask = 0xFU; /* todo: obtain data width from user paramaters */
+
+ for (vRef=(0x1U<<4U);vRef<0x3fU;vRef=(vRef+0x1U))
+ {
+ /*
+ * We change the value in the RPC register, but we will lso need to
+ * change SCB as will not be reflected without a soft reset
+ */
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (0x1fU<<4U)) | vRef;
+ /* need to set via the SCB, otherwise reset required. */
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits\
+ & (0x1fU<<4U)) | vRef;
+
+ /* read one to flush MTC - this is required */
+ result = MTC_test(1U<1U);
+ CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS =\
+ (CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & (0x1fU<<4U)) | vRef;
+ /* need to set via the SCB, otherwise reset required. */
+ IOSCB_BANKCONT_DDR->dpc_bits = (IOSCB_BANKCONT_DDR->dpc_bits & (0x1fU<<4U)) | vRef;
+ }
+ else
+ {
+ result = 1U; /* failed to get good data at any voltage level */
+ }
+
+ return result;
+ }
+#endif
+
+/***************************************************************************//**
+ * MTC_test
+ * test memory using the NWL memory test core
+ * There are numerous options
+ * todo: Add user input as to option to use?
+ * @param laneToTest
+ * @param mask0
+ * @param mask1 some lane less DQ as only used for parity
+ * @param start_address
+ * @param size = x, where x is used as power of two 2**x e.g. 256K => x == 18
+ * @return pass/fail
+ */
+static uint8_t MTC_test(uint8_t mask, uint64_t start_address, uint32_t size, MTC_PATTERN data_pattern, MTC_ADD_PATTERN add_pattern, uint32_t *error)
+{
+ if((*error & MTC_TIMEOUT_ERROR) == MTC_TIMEOUT_ERROR)
+ {
+ return (uint8_t)*error;
+ }
+ /* Write Calibration - first configure memory test */
+ {
+ /*
+ * write calibration
+ * configure common memory test interface by writing registers:
+ * MT_STOP_ON_ERROR, MT_DATA_PATTERN, MT_ADDR_PATTERN, MT_ADDR_BITS
+ */
+ /* see MTC user guide */
+ DDRCFG->MEM_TEST.MT_STOP_ON_ERROR.MT_STOP_ON_ERROR = 0U;
+ /* make sure off, will turn on later. */
+ DDRCFG->MEM_TEST.MT_EN_SINGLE.MT_EN_SINGLE = 0x00U;
+ /*
+ * MT_DATA_PATTERN
+ *
+ * 0x00 => Counting pattern
+ * 0x01 => walking 1's
+ * 0x02 => pseudo random
+ * 0x03 => no repeating pseudo random
+ * 0x04 => alt 1's and 0's
+ * 0x05 => alt 5's and A's
+ * 0x06 => User specified
+ * 0x07 => pseudo random 16-bit
+ * 0x08 => pseudo random 8-bit
+ * 0x09- 0x0f reserved
+ *
+ */
+ {
+ /*
+ * Added changing pattern so write pattern is different, read back
+ * can not pass on previously written data
+ */
+ DDRCFG->MEM_TEST.MT_DATA_PATTERN.MT_DATA_PATTERN = data_pattern;
+ }
+ if(add_pattern == MTC_ADD_RANDOM)
+ {
+ /*
+ * MT_ADDR_PATTERN
+ * 0x00 => Count in pattern
+ * 0x01 => Pseudo Random Pattern
+ * 0x02 => Arbiatry Pattern Gen (user defined ) - Using RAMS
+ */
+ DDRCFG->MEM_TEST.MT_ADDR_PATTERN.MT_ADDR_PATTERN = 1U;
+ }
+ else
+ {
+ DDRCFG->MEM_TEST.MT_ADDR_PATTERN.MT_ADDR_PATTERN = 0U;
+ }
+ }
+
+ if(add_pattern != MTC_ADD_RANDOM)
+ {
+ /*
+ * Set the starting address and number to test
+ *
+ * MT_START_ADDR
+ * Starting address
+ * MT_ADRESS_BITS
+ * Length to test = 2 ** MT_ADRESS_BITS
+ */
+ DDRCFG->MEM_TEST.MT_START_ADDR_0.MT_START_ADDR_0 =\
+ (uint32_t)(start_address & 0xFFFFFFFFUL);
+ /* The address here is as see from DDR controller => start at 0x0*/
+ DDRCFG->MEM_TEST.MT_START_ADDR_1.MT_START_ADDR_1 =\
+ (uint32_t)((start_address >> 32U));
+ }
+ else
+ {
+ DDRCFG->MEM_TEST.MT_START_ADDR_0.MT_START_ADDR_0 = 0U;
+ DDRCFG->MEM_TEST.MT_START_ADDR_1.MT_START_ADDR_1 = 0U;
+ }
+ DDRCFG->MEM_TEST.MT_ADDR_BITS.MT_ADDR_BITS =\
+ size; /* 2 power 24 => 256k to do- make user programmable */
+
+ {
+ /*
+ * FOR each DQ lane
+ * set error mask registers MT_ERROR_MASK_* to mask out
+ * all error bits but the ones for the current DQ lane
+ * WHILE timeout counter is less than a threshold
+ * perform memory test by writing MT_EN or MT_EN_SINGLE
+ * wait for memory test completion by polling MT_DONE_ACK
+ * read back memory test error status from MT_ERROR_STS
+ * IF no error detected
+ * exit loop
+ * ELSE
+ * increment write calibration offset for current DQ lane
+ * by writing EXPERT_WRCALIB
+ * ENDWHILE
+ * ENDFOR
+ */
+ {
+ /*
+ * MT_ERROR_MASK
+ * All bits set in this field mask corresponding bits in data fields
+ * i.e. mt_error and mt_error_hold will not be set for errors in
+ * those fields
+ *
+ * Structure of 144 bits same as DFI bus
+ * 36 bits per lane ( 8 physical * 4) + (1ECC * 4) = 36
+ *
+ * If we wrote out the following pattern from software:
+ * 0x12345678
+ * 0x87654321
+ * 0x56789876
+ * 0x43211234
+ * We should see:
+ * NNNN_YXXX_XXX3_4YXX_XXXX_76YX_XXXX_X21Y_XXXX_XX78
+ * N: not used
+ * Y:
+ */
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 = 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 = 0xFFFFFFFFU;
+
+ if (mask & 0x1U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFFFFFF00U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xFFFFF00FU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFFFF00FFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xFFF00FFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFFFFFU;
+ }
+ if (mask & 0x2U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFFFF00FFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xFFF00FFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFF00FFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xF00FFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFFFFFU;
+ }
+ if (mask & 0x4U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFF00FFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xF00FFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0x00FFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0x0FFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFFFF0U;
+ }
+ if (mask & 0x8U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0x00FFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0x0FFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFFFFFFF0U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xFFFFFF00U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFFF00FU;
+ }
+ if (mask & 0x10U)
+ {
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_0.MT_ERROR_MASK_0 &= 0xFFFFFFFFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_1.MT_ERROR_MASK_1 &= 0xFFFFFFF0U;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_2.MT_ERROR_MASK_2 &= 0xFFFFFF0FU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_3.MT_ERROR_MASK_3 &= 0xFFFFF0FFU;
+ DDRCFG->MEM_TEST.MT_ERROR_MASK_4.MT_ERROR_MASK_4 &= 0xFFFF0FFFU;
+ }
+
+ /*
+ * MT_EN
+ * Enables memory test
+ * If asserted at end of memory test, will keep going
+ */
+ DDRCFG->MEM_TEST.MT_EN.MT_EN = 0U;
+ /*
+ * MT_EN_SINGLE
+ * Will not repeat if this is set
+ */
+ DDRCFG->MEM_TEST.MT_EN_SINGLE.MT_EN_SINGLE = 0x00U;
+ DDRCFG->MEM_TEST.MT_EN_SINGLE.MT_EN_SINGLE = 0x01U;
+ /*
+ * MT_DONE_ACK
+ * Set when test completes
+ */
+ volatile uint64_t something_to_do = 0U;
+ #ifndef UNITTEST
+ while (( DDRCFG->MEM_TEST.MT_DONE_ACK.MT_DONE_ACK & 0x01U) == 0U)
+ {
+ something_to_do++;
+ if(something_to_do > 0xFFFFFFUL)
+ {
+#ifdef DEBUG_DDR_INIT
+ (void)uprint32(g_debug_uart, "\n\rmtc test error:",MTC_TIMEOUT_ERROR);
+#endif
+ return (MTC_TIMEOUT_ERROR);
+ }
+ #ifdef RENODE_DEBUG
+ break;
+ #endif
+ }
+ #endif
+ }
+ }
+ /*
+ * MT_ERROR_STS
+ * Return the error status
+ * todo:Check NWL data and detail error states here
+ */
+
+ return (DDRCFG->MEM_TEST.MT_ERROR_STS.MT_ERROR_STS & 0x01U);
+
+}
+
+
+/***************************************************************************//**
+ * Setup DDRC
+ * These settings come from config tool
+ *
+ */
+#define _USE_SETTINGS_USED_IN_DDR3_FULL_CHIP_TEST
+
+static void init_ddrc(void)
+{
+ DDRCFG->ADDR_MAP.CFG_MANUAL_ADDRESS_MAP.CFG_MANUAL_ADDRESS_MAP =\
+ LIBERO_SETTING_CFG_MANUAL_ADDRESS_MAP;
+ DDRCFG->ADDR_MAP.CFG_CHIPADDR_MAP.CFG_CHIPADDR_MAP =\
+ LIBERO_SETTING_CFG_CHIPADDR_MAP;
+ DDRCFG->ADDR_MAP.CFG_CIDADDR_MAP.CFG_CIDADDR_MAP =\
+ LIBERO_SETTING_CFG_CIDADDR_MAP;
+ DDRCFG->ADDR_MAP.CFG_MB_AUTOPCH_COL_BIT_POS_LOW.CFG_MB_AUTOPCH_COL_BIT_POS_LOW =\
+ LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_LOW;
+ DDRCFG->ADDR_MAP.CFG_MB_AUTOPCH_COL_BIT_POS_HIGH.CFG_MB_AUTOPCH_COL_BIT_POS_HIGH =\
+ LIBERO_SETTING_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH;
+ DDRCFG->ADDR_MAP.CFG_BANKADDR_MAP_0.CFG_BANKADDR_MAP_0 =\
+ LIBERO_SETTING_CFG_BANKADDR_MAP_0;
+ DDRCFG->ADDR_MAP.CFG_BANKADDR_MAP_1.CFG_BANKADDR_MAP_1 =\
+ LIBERO_SETTING_CFG_BANKADDR_MAP_1;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_0.CFG_ROWADDR_MAP_0 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_0;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_1.CFG_ROWADDR_MAP_1 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_1;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_2.CFG_ROWADDR_MAP_2 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_2;
+ DDRCFG->ADDR_MAP.CFG_ROWADDR_MAP_3.CFG_ROWADDR_MAP_3 =\
+ LIBERO_SETTING_CFG_ROWADDR_MAP_3;
+ DDRCFG->ADDR_MAP.CFG_COLADDR_MAP_0.CFG_COLADDR_MAP_0 =\
+ LIBERO_SETTING_CFG_COLADDR_MAP_0;
+ DDRCFG->ADDR_MAP.CFG_COLADDR_MAP_1.CFG_COLADDR_MAP_1 =\
+ LIBERO_SETTING_CFG_COLADDR_MAP_1;
+ DDRCFG->ADDR_MAP.CFG_COLADDR_MAP_2.CFG_COLADDR_MAP_2 =\
+ LIBERO_SETTING_CFG_COLADDR_MAP_2;
+ DDRCFG->MC_BASE3.CFG_VRCG_ENABLE.CFG_VRCG_ENABLE =\
+ LIBERO_SETTING_CFG_VRCG_ENABLE;
+ DDRCFG->MC_BASE3.CFG_VRCG_DISABLE.CFG_VRCG_DISABLE =\
+ LIBERO_SETTING_CFG_VRCG_DISABLE;
+ DDRCFG->MC_BASE3.CFG_WRITE_LATENCY_SET.CFG_WRITE_LATENCY_SET =\
+ LIBERO_SETTING_CFG_WRITE_LATENCY_SET;
+ DDRCFG->MC_BASE3.CFG_THERMAL_OFFSET.CFG_THERMAL_OFFSET =\
+ LIBERO_SETTING_CFG_THERMAL_OFFSET;
+ DDRCFG->MC_BASE3.CFG_SOC_ODT.CFG_SOC_ODT = LIBERO_SETTING_CFG_SOC_ODT;
+ DDRCFG->MC_BASE3.CFG_ODTE_CK.CFG_ODTE_CK = LIBERO_SETTING_CFG_ODTE_CK;
+ DDRCFG->MC_BASE3.CFG_ODTE_CS.CFG_ODTE_CS = LIBERO_SETTING_CFG_ODTE_CS;
+ DDRCFG->MC_BASE3.CFG_ODTD_CA.CFG_ODTD_CA = LIBERO_SETTING_CFG_ODTD_CA;
+ DDRCFG->MC_BASE3.CFG_LPDDR4_FSP_OP.CFG_LPDDR4_FSP_OP =\
+ LIBERO_SETTING_CFG_LPDDR4_FSP_OP;
+ DDRCFG->MC_BASE3.CFG_GENERATE_REFRESH_ON_SRX.CFG_GENERATE_REFRESH_ON_SRX =\
+ LIBERO_SETTING_CFG_GENERATE_REFRESH_ON_SRX;
+ DDRCFG->MC_BASE3.CFG_DBI_CL.CFG_DBI_CL = LIBERO_SETTING_CFG_DBI_CL;
+ DDRCFG->MC_BASE3.CFG_NON_DBI_CL.CFG_NON_DBI_CL =\
+ LIBERO_SETTING_CFG_NON_DBI_CL;
+ DDRCFG->MC_BASE3.INIT_FORCE_WRITE_DATA_0.INIT_FORCE_WRITE_DATA_0 =\
+ LIBERO_SETTING_INIT_FORCE_WRITE_DATA_0;
+ DDRCFG->MC_BASE1.CFG_WRITE_CRC.CFG_WRITE_CRC =\
+ LIBERO_SETTING_CFG_WRITE_CRC;
+ DDRCFG->MC_BASE1.CFG_MPR_READ_FORMAT.CFG_MPR_READ_FORMAT =\
+ LIBERO_SETTING_CFG_MPR_READ_FORMAT;
+ DDRCFG->MC_BASE1.CFG_WR_CMD_LAT_CRC_DM.CFG_WR_CMD_LAT_CRC_DM =\
+ LIBERO_SETTING_CFG_WR_CMD_LAT_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_FINE_GRAN_REF_MODE.CFG_FINE_GRAN_REF_MODE =\
+ LIBERO_SETTING_CFG_FINE_GRAN_REF_MODE;
+ DDRCFG->MC_BASE1.CFG_TEMP_SENSOR_READOUT.CFG_TEMP_SENSOR_READOUT =\
+ LIBERO_SETTING_CFG_TEMP_SENSOR_READOUT;
+ DDRCFG->MC_BASE1.CFG_PER_DRAM_ADDR_EN.CFG_PER_DRAM_ADDR_EN =\
+ LIBERO_SETTING_CFG_PER_DRAM_ADDR_EN;
+ DDRCFG->MC_BASE1.CFG_GEARDOWN_MODE.CFG_GEARDOWN_MODE =\
+ LIBERO_SETTING_CFG_GEARDOWN_MODE;
+ DDRCFG->MC_BASE1.CFG_WR_PREAMBLE.CFG_WR_PREAMBLE =\
+ LIBERO_SETTING_CFG_WR_PREAMBLE;
+ DDRCFG->MC_BASE1.CFG_RD_PREAMBLE.CFG_RD_PREAMBLE =\
+ LIBERO_SETTING_CFG_RD_PREAMBLE;
+ DDRCFG->MC_BASE1.CFG_RD_PREAMB_TRN_MODE.CFG_RD_PREAMB_TRN_MODE =\
+ LIBERO_SETTING_CFG_RD_PREAMB_TRN_MODE;
+ DDRCFG->MC_BASE1.CFG_SR_ABORT.CFG_SR_ABORT = LIBERO_SETTING_CFG_SR_ABORT;
+ DDRCFG->MC_BASE1.CFG_CS_TO_CMDADDR_LATENCY.CFG_CS_TO_CMDADDR_LATENCY =\
+ LIBERO_SETTING_CFG_CS_TO_CMDADDR_LATENCY;
+ DDRCFG->MC_BASE1.CFG_INT_VREF_MON.CFG_INT_VREF_MON =\
+ LIBERO_SETTING_CFG_INT_VREF_MON;
+ DDRCFG->MC_BASE1.CFG_TEMP_CTRL_REF_MODE.CFG_TEMP_CTRL_REF_MODE =\
+ LIBERO_SETTING_CFG_TEMP_CTRL_REF_MODE;
+ DDRCFG->MC_BASE1.CFG_TEMP_CTRL_REF_RANGE.CFG_TEMP_CTRL_REF_RANGE =\
+ LIBERO_SETTING_CFG_TEMP_CTRL_REF_RANGE;
+ DDRCFG->MC_BASE1.CFG_MAX_PWR_DOWN_MODE.CFG_MAX_PWR_DOWN_MODE =\
+ LIBERO_SETTING_CFG_MAX_PWR_DOWN_MODE;
+ DDRCFG->MC_BASE1.CFG_READ_DBI.CFG_READ_DBI = LIBERO_SETTING_CFG_READ_DBI;
+ DDRCFG->MC_BASE1.CFG_WRITE_DBI.CFG_WRITE_DBI =\
+ LIBERO_SETTING_CFG_WRITE_DBI;
+ DDRCFG->MC_BASE1.CFG_DATA_MASK.CFG_DATA_MASK =\
+ LIBERO_SETTING_CFG_DATA_MASK;
+ DDRCFG->MC_BASE1.CFG_CA_PARITY_PERSIST_ERR.CFG_CA_PARITY_PERSIST_ERR =\
+ LIBERO_SETTING_CFG_CA_PARITY_PERSIST_ERR;
+ DDRCFG->MC_BASE1.CFG_RTT_PARK.CFG_RTT_PARK = LIBERO_SETTING_CFG_RTT_PARK;
+ DDRCFG->MC_BASE1.CFG_ODT_INBUF_4_PD.CFG_ODT_INBUF_4_PD =\
+ LIBERO_SETTING_CFG_ODT_INBUF_4_PD;
+ DDRCFG->MC_BASE1.CFG_CA_PARITY_ERR_STATUS.CFG_CA_PARITY_ERR_STATUS =\
+ LIBERO_SETTING_CFG_CA_PARITY_ERR_STATUS;
+ DDRCFG->MC_BASE1.CFG_CRC_ERROR_CLEAR.CFG_CRC_ERROR_CLEAR =\
+ LIBERO_SETTING_CFG_CRC_ERROR_CLEAR;
+ DDRCFG->MC_BASE1.CFG_CA_PARITY_LATENCY.CFG_CA_PARITY_LATENCY =\
+ LIBERO_SETTING_CFG_CA_PARITY_LATENCY;
+ DDRCFG->MC_BASE1.CFG_CCD_S.CFG_CCD_S = LIBERO_SETTING_CFG_CCD_S;
+ DDRCFG->MC_BASE1.CFG_CCD_L.CFG_CCD_L = LIBERO_SETTING_CFG_CCD_L;
+ DDRCFG->MC_BASE1.CFG_VREFDQ_TRN_ENABLE.CFG_VREFDQ_TRN_ENABLE =\
+ LIBERO_SETTING_CFG_VREFDQ_TRN_ENABLE;
+ DDRCFG->MC_BASE1.CFG_VREFDQ_TRN_RANGE.CFG_VREFDQ_TRN_RANGE =\
+ LIBERO_SETTING_CFG_VREFDQ_TRN_RANGE;
+ DDRCFG->MC_BASE1.CFG_VREFDQ_TRN_VALUE.CFG_VREFDQ_TRN_VALUE =\
+ LIBERO_SETTING_CFG_VREFDQ_TRN_VALUE;
+ DDRCFG->MC_BASE1.CFG_RRD_S.CFG_RRD_S = LIBERO_SETTING_CFG_RRD_S;
+ DDRCFG->MC_BASE1.CFG_RRD_L.CFG_RRD_L = LIBERO_SETTING_CFG_RRD_L;
+ DDRCFG->MC_BASE1.CFG_WTR_S.CFG_WTR_S = LIBERO_SETTING_CFG_WTR_S;
+ DDRCFG->MC_BASE1.CFG_WTR_L.CFG_WTR_L = LIBERO_SETTING_CFG_WTR_L;
+ DDRCFG->MC_BASE1.CFG_WTR_S_CRC_DM.CFG_WTR_S_CRC_DM =\
+ LIBERO_SETTING_CFG_WTR_S_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_WTR_L_CRC_DM.CFG_WTR_L_CRC_DM =\
+ LIBERO_SETTING_CFG_WTR_L_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_WR_CRC_DM.CFG_WR_CRC_DM =\
+ LIBERO_SETTING_CFG_WR_CRC_DM;
+ DDRCFG->MC_BASE1.CFG_RFC1.CFG_RFC1 = LIBERO_SETTING_CFG_RFC1;
+ DDRCFG->MC_BASE1.CFG_RFC2.CFG_RFC2 = LIBERO_SETTING_CFG_RFC2;
+ DDRCFG->MC_BASE1.CFG_RFC4.CFG_RFC4 = LIBERO_SETTING_CFG_RFC4;
+ DDRCFG->MC_BASE1.CFG_NIBBLE_DEVICES.CFG_NIBBLE_DEVICES =\
+ LIBERO_SETTING_CFG_NIBBLE_DEVICES;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS0_0.CFG_BIT_MAP_INDEX_CS0_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS0_1.CFG_BIT_MAP_INDEX_CS0_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS0_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS1_0.CFG_BIT_MAP_INDEX_CS1_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS1_1.CFG_BIT_MAP_INDEX_CS1_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS1_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS2_0.CFG_BIT_MAP_INDEX_CS2_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS2_1.CFG_BIT_MAP_INDEX_CS2_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS2_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS3_0.CFG_BIT_MAP_INDEX_CS3_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS3_1.CFG_BIT_MAP_INDEX_CS3_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS3_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS4_0.CFG_BIT_MAP_INDEX_CS4_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS4_1.CFG_BIT_MAP_INDEX_CS4_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS4_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS5_0.CFG_BIT_MAP_INDEX_CS5_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS5_1.CFG_BIT_MAP_INDEX_CS5_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS5_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS6_0.CFG_BIT_MAP_INDEX_CS6_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS6_1.CFG_BIT_MAP_INDEX_CS6_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS6_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS7_0.CFG_BIT_MAP_INDEX_CS7_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS7_1.CFG_BIT_MAP_INDEX_CS7_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS7_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS8_0.CFG_BIT_MAP_INDEX_CS8_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS8_1.CFG_BIT_MAP_INDEX_CS8_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS8_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS9_0.CFG_BIT_MAP_INDEX_CS9_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS9_1.CFG_BIT_MAP_INDEX_CS9_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS9_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS10_0.CFG_BIT_MAP_INDEX_CS10_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS10_1.CFG_BIT_MAP_INDEX_CS10_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS10_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS11_0.CFG_BIT_MAP_INDEX_CS11_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS11_1.CFG_BIT_MAP_INDEX_CS11_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS11_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS12_0.CFG_BIT_MAP_INDEX_CS12_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS12_1.CFG_BIT_MAP_INDEX_CS12_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS12_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS13_0.CFG_BIT_MAP_INDEX_CS13_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS13_1.CFG_BIT_MAP_INDEX_CS13_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS13_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS14_0.CFG_BIT_MAP_INDEX_CS14_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS14_1.CFG_BIT_MAP_INDEX_CS14_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS14_1;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS15_0.CFG_BIT_MAP_INDEX_CS15_0 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_0;
+ DDRCFG->MC_BASE1.CFG_BIT_MAP_INDEX_CS15_1.CFG_BIT_MAP_INDEX_CS15_1 =\
+ LIBERO_SETTING_CFG_BIT_MAP_INDEX_CS15_1;
+ DDRCFG->MC_BASE1.CFG_NUM_LOGICAL_RANKS_PER_3DS.CFG_NUM_LOGICAL_RANKS_PER_3DS =\
+ LIBERO_SETTING_CFG_NUM_LOGICAL_RANKS_PER_3DS;
+ DDRCFG->MC_BASE1.CFG_RFC_DLR1.CFG_RFC_DLR1 = LIBERO_SETTING_CFG_RFC_DLR1;
+ DDRCFG->MC_BASE1.CFG_RFC_DLR2.CFG_RFC_DLR2 = LIBERO_SETTING_CFG_RFC_DLR2;
+ DDRCFG->MC_BASE1.CFG_RFC_DLR4.CFG_RFC_DLR4 = LIBERO_SETTING_CFG_RFC_DLR4;
+ DDRCFG->MC_BASE1.CFG_RRD_DLR.CFG_RRD_DLR = LIBERO_SETTING_CFG_RRD_DLR;
+ DDRCFG->MC_BASE1.CFG_FAW_DLR.CFG_FAW_DLR = LIBERO_SETTING_CFG_FAW_DLR;
+ DDRCFG->MC_BASE1.CFG_ADVANCE_ACTIVATE_READY.CFG_ADVANCE_ACTIVATE_READY =\
+ LIBERO_SETTING_CFG_ADVANCE_ACTIVATE_READY;
+ DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\
+ LIBERO_SETTING_CTRLR_SOFT_RESET_N;
+ DDRCFG->MC_BASE2.CFG_LOOKAHEAD_PCH.CFG_LOOKAHEAD_PCH =\
+ LIBERO_SETTING_CFG_LOOKAHEAD_PCH;
+ DDRCFG->MC_BASE2.CFG_LOOKAHEAD_ACT.CFG_LOOKAHEAD_ACT =\
+ LIBERO_SETTING_CFG_LOOKAHEAD_ACT;
+ DDRCFG->MC_BASE2.INIT_AUTOINIT_DISABLE.INIT_AUTOINIT_DISABLE =\
+ LIBERO_SETTING_INIT_AUTOINIT_DISABLE;
+ DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET =\
+ LIBERO_SETTING_INIT_FORCE_RESET;
+ DDRCFG->MC_BASE2.INIT_GEARDOWN_EN.INIT_GEARDOWN_EN =\
+ LIBERO_SETTING_INIT_GEARDOWN_EN;
+ DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE =\
+ LIBERO_SETTING_INIT_DISABLE_CKE;
+ DDRCFG->MC_BASE2.INIT_CS.INIT_CS = LIBERO_SETTING_INIT_CS;
+ DDRCFG->MC_BASE2.INIT_PRECHARGE_ALL.INIT_PRECHARGE_ALL =\
+ LIBERO_SETTING_INIT_PRECHARGE_ALL;
+ DDRCFG->MC_BASE2.INIT_REFRESH.INIT_REFRESH = LIBERO_SETTING_INIT_REFRESH;
+ DDRCFG->MC_BASE2.INIT_ZQ_CAL_REQ.INIT_ZQ_CAL_REQ =\
+ LIBERO_SETTING_INIT_ZQ_CAL_REQ;
+ DDRCFG->MC_BASE2.CFG_BL.CFG_BL = LIBERO_SETTING_CFG_BL;
+ DDRCFG->MC_BASE2.CTRLR_INIT.CTRLR_INIT = LIBERO_SETTING_CTRLR_INIT;
+ DDRCFG->MC_BASE2.CFG_AUTO_REF_EN.CFG_AUTO_REF_EN =\
+ LIBERO_SETTING_CFG_AUTO_REF_EN;
+ DDRCFG->MC_BASE2.CFG_RAS.CFG_RAS = LIBERO_SETTING_CFG_RAS;
+ DDRCFG->MC_BASE2.CFG_RCD.CFG_RCD = LIBERO_SETTING_CFG_RCD;
+ DDRCFG->MC_BASE2.CFG_RRD.CFG_RRD = LIBERO_SETTING_CFG_RRD;
+ DDRCFG->MC_BASE2.CFG_RP.CFG_RP = LIBERO_SETTING_CFG_RP;
+ DDRCFG->MC_BASE2.CFG_RC.CFG_RC = LIBERO_SETTING_CFG_RC;
+ DDRCFG->MC_BASE2.CFG_FAW.CFG_FAW = LIBERO_SETTING_CFG_FAW;
+ DDRCFG->MC_BASE2.CFG_RFC.CFG_RFC = LIBERO_SETTING_CFG_RFC;
+ DDRCFG->MC_BASE2.CFG_RTP.CFG_RTP = LIBERO_SETTING_CFG_RTP;
+ DDRCFG->MC_BASE2.CFG_WR.CFG_WR = LIBERO_SETTING_CFG_WR;
+ DDRCFG->MC_BASE2.CFG_WTR.CFG_WTR = LIBERO_SETTING_CFG_WTR;
+ DDRCFG->MC_BASE2.CFG_PASR.CFG_PASR = LIBERO_SETTING_CFG_PASR;
+ DDRCFG->MC_BASE2.CFG_XP.CFG_XP = LIBERO_SETTING_CFG_XP;
+ DDRCFG->MC_BASE2.CFG_XSR.CFG_XSR = LIBERO_SETTING_CFG_XSR;
+ DDRCFG->MC_BASE2.CFG_CL.CFG_CL = LIBERO_SETTING_CFG_CL;
+ DDRCFG->MC_BASE2.CFG_READ_TO_WRITE.CFG_READ_TO_WRITE =\
+ LIBERO_SETTING_CFG_READ_TO_WRITE;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_WRITE.CFG_WRITE_TO_WRITE =\
+ LIBERO_SETTING_CFG_WRITE_TO_WRITE;
+ DDRCFG->MC_BASE2.CFG_READ_TO_READ.CFG_READ_TO_READ =\
+ LIBERO_SETTING_CFG_READ_TO_READ;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_READ.CFG_WRITE_TO_READ =\
+ LIBERO_SETTING_CFG_WRITE_TO_READ;
+ DDRCFG->MC_BASE2.CFG_READ_TO_WRITE_ODT.CFG_READ_TO_WRITE_ODT =\
+ LIBERO_SETTING_CFG_READ_TO_WRITE_ODT;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_WRITE_ODT.CFG_WRITE_TO_WRITE_ODT =\
+ LIBERO_SETTING_CFG_WRITE_TO_WRITE_ODT;
+ DDRCFG->MC_BASE2.CFG_READ_TO_READ_ODT.CFG_READ_TO_READ_ODT =\
+ LIBERO_SETTING_CFG_READ_TO_READ_ODT;
+ DDRCFG->MC_BASE2.CFG_WRITE_TO_READ_ODT.CFG_WRITE_TO_READ_ODT =\
+ LIBERO_SETTING_CFG_WRITE_TO_READ_ODT;
+ DDRCFG->MC_BASE2.CFG_MIN_READ_IDLE.CFG_MIN_READ_IDLE =\
+ LIBERO_SETTING_CFG_MIN_READ_IDLE;
+ DDRCFG->MC_BASE2.CFG_MRD.CFG_MRD = LIBERO_SETTING_CFG_MRD;
+ DDRCFG->MC_BASE2.CFG_BT.CFG_BT = LIBERO_SETTING_CFG_BT;
+ DDRCFG->MC_BASE2.CFG_DS.CFG_DS = LIBERO_SETTING_CFG_DS;
+ DDRCFG->MC_BASE2.CFG_QOFF.CFG_QOFF = LIBERO_SETTING_CFG_QOFF;
+ DDRCFG->MC_BASE2.CFG_RTT.CFG_RTT = LIBERO_SETTING_CFG_RTT;
+ DDRCFG->MC_BASE2.CFG_DLL_DISABLE.CFG_DLL_DISABLE =\
+ LIBERO_SETTING_CFG_DLL_DISABLE;
+ DDRCFG->MC_BASE2.CFG_REF_PER.CFG_REF_PER = LIBERO_SETTING_CFG_REF_PER;
+ DDRCFG->MC_BASE2.CFG_STARTUP_DELAY.CFG_STARTUP_DELAY =\
+ LIBERO_SETTING_CFG_STARTUP_DELAY;
+ DDRCFG->MC_BASE2.CFG_MEM_COLBITS.CFG_MEM_COLBITS =\
+ LIBERO_SETTING_CFG_MEM_COLBITS;
+ DDRCFG->MC_BASE2.CFG_MEM_ROWBITS.CFG_MEM_ROWBITS =\
+ LIBERO_SETTING_CFG_MEM_ROWBITS;
+ DDRCFG->MC_BASE2.CFG_MEM_BANKBITS.CFG_MEM_BANKBITS =\
+ LIBERO_SETTING_CFG_MEM_BANKBITS;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS0.CFG_ODT_RD_MAP_CS0 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS0;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS1.CFG_ODT_RD_MAP_CS1 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS1;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS2.CFG_ODT_RD_MAP_CS2 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS2;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS3.CFG_ODT_RD_MAP_CS3 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS3;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS4.CFG_ODT_RD_MAP_CS4 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS4;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS5.CFG_ODT_RD_MAP_CS5 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS5;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS6.CFG_ODT_RD_MAP_CS6 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS6;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_MAP_CS7.CFG_ODT_RD_MAP_CS7 =\
+ LIBERO_SETTING_CFG_ODT_RD_MAP_CS7;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS0.CFG_ODT_WR_MAP_CS0 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS0;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS1.CFG_ODT_WR_MAP_CS1 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS1;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS2.CFG_ODT_WR_MAP_CS2 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS2;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS3.CFG_ODT_WR_MAP_CS3 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS3;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS4.CFG_ODT_WR_MAP_CS4 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS4;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS5.CFG_ODT_WR_MAP_CS5 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS5;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS6.CFG_ODT_WR_MAP_CS6 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS6;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_MAP_CS7.CFG_ODT_WR_MAP_CS7 =\
+ LIBERO_SETTING_CFG_ODT_WR_MAP_CS7;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_TURN_ON.CFG_ODT_RD_TURN_ON =\
+ LIBERO_SETTING_CFG_ODT_RD_TURN_ON;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_TURN_ON.CFG_ODT_WR_TURN_ON =\
+ LIBERO_SETTING_CFG_ODT_WR_TURN_ON;
+ DDRCFG->MC_BASE2.CFG_ODT_RD_TURN_OFF.CFG_ODT_RD_TURN_OFF =\
+ LIBERO_SETTING_CFG_ODT_RD_TURN_OFF;
+ DDRCFG->MC_BASE2.CFG_ODT_WR_TURN_OFF.CFG_ODT_WR_TURN_OFF =\
+ LIBERO_SETTING_CFG_ODT_WR_TURN_OFF;
+ DDRCFG->MC_BASE2.CFG_EMR3.CFG_EMR3 = LIBERO_SETTING_CFG_EMR3;
+ DDRCFG->MC_BASE2.CFG_TWO_T.CFG_TWO_T = LIBERO_SETTING_CFG_TWO_T;
+ DDRCFG->MC_BASE2.CFG_TWO_T_SEL_CYCLE.CFG_TWO_T_SEL_CYCLE =\
+ LIBERO_SETTING_CFG_TWO_T_SEL_CYCLE;
+ DDRCFG->MC_BASE2.CFG_REGDIMM.CFG_REGDIMM = LIBERO_SETTING_CFG_REGDIMM;
+ DDRCFG->MC_BASE2.CFG_MOD.CFG_MOD = LIBERO_SETTING_CFG_MOD;
+ DDRCFG->MC_BASE2.CFG_XS.CFG_XS = LIBERO_SETTING_CFG_XS;
+ DDRCFG->MC_BASE2.CFG_XSDLL.CFG_XSDLL = LIBERO_SETTING_CFG_XSDLL;
+ DDRCFG->MC_BASE2.CFG_XPR.CFG_XPR = LIBERO_SETTING_CFG_XPR;
+ DDRCFG->MC_BASE2.CFG_AL_MODE.CFG_AL_MODE = LIBERO_SETTING_CFG_AL_MODE;
+ DDRCFG->MC_BASE2.CFG_CWL.CFG_CWL = LIBERO_SETTING_CFG_CWL;
+ DDRCFG->MC_BASE2.CFG_BL_MODE.CFG_BL_MODE = LIBERO_SETTING_CFG_BL_MODE;
+ DDRCFG->MC_BASE2.CFG_TDQS.CFG_TDQS = LIBERO_SETTING_CFG_TDQS;
+ DDRCFG->MC_BASE2.CFG_RTT_WR.CFG_RTT_WR = LIBERO_SETTING_CFG_RTT_WR;
+ DDRCFG->MC_BASE2.CFG_LP_ASR.CFG_LP_ASR = LIBERO_SETTING_CFG_LP_ASR;
+ DDRCFG->MC_BASE2.CFG_AUTO_SR.CFG_AUTO_SR = LIBERO_SETTING_CFG_AUTO_SR;
+ DDRCFG->MC_BASE2.CFG_SRT.CFG_SRT = LIBERO_SETTING_CFG_SRT;
+ DDRCFG->MC_BASE2.CFG_ADDR_MIRROR.CFG_ADDR_MIRROR =\
+ LIBERO_SETTING_CFG_ADDR_MIRROR;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_TYPE.CFG_ZQ_CAL_TYPE =\
+ LIBERO_SETTING_CFG_ZQ_CAL_TYPE;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_PER.CFG_ZQ_CAL_PER =\
+ LIBERO_SETTING_CFG_ZQ_CAL_PER;
+ DDRCFG->MC_BASE2.CFG_AUTO_ZQ_CAL_EN.CFG_AUTO_ZQ_CAL_EN =\
+ LIBERO_SETTING_CFG_AUTO_ZQ_CAL_EN;
+ DDRCFG->MC_BASE2.CFG_MEMORY_TYPE.CFG_MEMORY_TYPE =\
+ LIBERO_SETTING_CFG_MEMORY_TYPE;
+ DDRCFG->MC_BASE2.CFG_ONLY_SRANK_CMDS.CFG_ONLY_SRANK_CMDS =\
+ LIBERO_SETTING_CFG_ONLY_SRANK_CMDS;
+ DDRCFG->MC_BASE2.CFG_NUM_RANKS.CFG_NUM_RANKS =\
+ LIBERO_SETTING_CFG_NUM_RANKS;
+ DDRCFG->MC_BASE2.CFG_QUAD_RANK.CFG_QUAD_RANK =\
+ LIBERO_SETTING_CFG_QUAD_RANK;
+ DDRCFG->MC_BASE2.CFG_EARLY_RANK_TO_WR_START.CFG_EARLY_RANK_TO_WR_START =\
+ LIBERO_SETTING_CFG_EARLY_RANK_TO_WR_START;
+ DDRCFG->MC_BASE2.CFG_EARLY_RANK_TO_RD_START.CFG_EARLY_RANK_TO_RD_START =\
+ LIBERO_SETTING_CFG_EARLY_RANK_TO_RD_START;
+ DDRCFG->MC_BASE2.CFG_PASR_BANK.CFG_PASR_BANK =\
+ LIBERO_SETTING_CFG_PASR_BANK;
+ DDRCFG->MC_BASE2.CFG_PASR_SEG.CFG_PASR_SEG = LIBERO_SETTING_CFG_PASR_SEG;
+ DDRCFG->MC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE =\
+ LIBERO_SETTING_INIT_MRR_MODE;
+ DDRCFG->MC_BASE2.INIT_MR_W_REQ.INIT_MR_W_REQ =\
+ LIBERO_SETTING_INIT_MR_W_REQ;
+ DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = LIBERO_SETTING_INIT_MR_ADDR;
+ DDRCFG->MC_BASE2.INIT_MR_WR_DATA.INIT_MR_WR_DATA =\
+ LIBERO_SETTING_INIT_MR_WR_DATA;
+ DDRCFG->MC_BASE2.INIT_MR_WR_MASK.INIT_MR_WR_MASK =\
+ LIBERO_SETTING_INIT_MR_WR_MASK;
+ DDRCFG->MC_BASE2.INIT_NOP.INIT_NOP = LIBERO_SETTING_INIT_NOP;
+ DDRCFG->MC_BASE2.CFG_INIT_DURATION.CFG_INIT_DURATION =\
+ LIBERO_SETTING_CFG_INIT_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQINIT_CAL_DURATION.CFG_ZQINIT_CAL_DURATION =\
+ LIBERO_SETTING_CFG_ZQINIT_CAL_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_L_DURATION.CFG_ZQ_CAL_L_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_L_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_S_DURATION.CFG_ZQ_CAL_S_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_S_DURATION;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_R_DURATION.CFG_ZQ_CAL_R_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_R_DURATION;
+ DDRCFG->MC_BASE2.CFG_MRR.CFG_MRR = LIBERO_SETTING_CFG_MRR;
+ DDRCFG->MC_BASE2.CFG_MRW.CFG_MRW = LIBERO_SETTING_CFG_MRW;
+ DDRCFG->MC_BASE2.CFG_ODT_POWERDOWN.CFG_ODT_POWERDOWN =\
+ LIBERO_SETTING_CFG_ODT_POWERDOWN;
+ DDRCFG->MC_BASE2.CFG_WL.CFG_WL = LIBERO_SETTING_CFG_WL;
+ DDRCFG->MC_BASE2.CFG_RL.CFG_RL = LIBERO_SETTING_CFG_RL;
+ DDRCFG->MC_BASE2.CFG_CAL_READ_PERIOD.CFG_CAL_READ_PERIOD =\
+ LIBERO_SETTING_CFG_CAL_READ_PERIOD;
+ DDRCFG->MC_BASE2.CFG_NUM_CAL_READS.CFG_NUM_CAL_READS =\
+ LIBERO_SETTING_CFG_NUM_CAL_READS;
+ DDRCFG->MC_BASE2.INIT_SELF_REFRESH.INIT_SELF_REFRESH =\
+ LIBERO_SETTING_INIT_SELF_REFRESH;
+ DDRCFG->MC_BASE2.INIT_POWER_DOWN.INIT_POWER_DOWN =\
+ LIBERO_SETTING_INIT_POWER_DOWN;
+ DDRCFG->MC_BASE2.INIT_FORCE_WRITE.INIT_FORCE_WRITE =\
+ LIBERO_SETTING_INIT_FORCE_WRITE;
+ DDRCFG->MC_BASE2.INIT_FORCE_WRITE_CS.INIT_FORCE_WRITE_CS =\
+ LIBERO_SETTING_INIT_FORCE_WRITE_CS;
+ DDRCFG->MC_BASE2.CFG_CTRLR_INIT_DISABLE.CFG_CTRLR_INIT_DISABLE =\
+ LIBERO_SETTING_CFG_CTRLR_INIT_DISABLE;
+ DDRCFG->MC_BASE2.INIT_RDIMM_COMPLETE.INIT_RDIMM_COMPLETE =\
+ LIBERO_SETTING_INIT_RDIMM_COMPLETE;
+ DDRCFG->MC_BASE2.CFG_RDIMM_LAT.CFG_RDIMM_LAT =\
+ LIBERO_SETTING_CFG_RDIMM_LAT;
+ DDRCFG->MC_BASE2.CFG_RDIMM_BSIDE_INVERT.CFG_RDIMM_BSIDE_INVERT =\
+ LIBERO_SETTING_CFG_RDIMM_BSIDE_INVERT;
+ DDRCFG->MC_BASE2.CFG_LRDIMM.CFG_LRDIMM = LIBERO_SETTING_CFG_LRDIMM;
+ DDRCFG->MC_BASE2.INIT_MEMORY_RESET_MASK.INIT_MEMORY_RESET_MASK =\
+ LIBERO_SETTING_INIT_MEMORY_RESET_MASK;
+ DDRCFG->MC_BASE2.CFG_RD_PREAMB_TOGGLE.CFG_RD_PREAMB_TOGGLE =\
+ LIBERO_SETTING_CFG_RD_PREAMB_TOGGLE;
+ DDRCFG->MC_BASE2.CFG_RD_POSTAMBLE.CFG_RD_POSTAMBLE =\
+ LIBERO_SETTING_CFG_RD_POSTAMBLE;
+ DDRCFG->MC_BASE2.CFG_PU_CAL.CFG_PU_CAL = LIBERO_SETTING_CFG_PU_CAL;
+ DDRCFG->MC_BASE2.CFG_DQ_ODT.CFG_DQ_ODT = LIBERO_SETTING_CFG_DQ_ODT;
+ DDRCFG->MC_BASE2.CFG_CA_ODT.CFG_CA_ODT = LIBERO_SETTING_CFG_CA_ODT;
+ DDRCFG->MC_BASE2.CFG_ZQLATCH_DURATION.CFG_ZQLATCH_DURATION =\
+ LIBERO_SETTING_CFG_ZQLATCH_DURATION;
+ DDRCFG->MC_BASE2.INIT_CAL_SELECT.INIT_CAL_SELECT =\
+ LIBERO_SETTING_INIT_CAL_SELECT;
+ DDRCFG->MC_BASE2.INIT_CAL_L_R_REQ.INIT_CAL_L_R_REQ =\
+ LIBERO_SETTING_INIT_CAL_L_R_REQ;
+ DDRCFG->MC_BASE2.INIT_CAL_L_B_SIZE.INIT_CAL_L_B_SIZE =\
+ LIBERO_SETTING_INIT_CAL_L_B_SIZE;
+ DDRCFG->MC_BASE2.INIT_RWFIFO.INIT_RWFIFO = LIBERO_SETTING_INIT_RWFIFO;
+ DDRCFG->MC_BASE2.INIT_RD_DQCAL.INIT_RD_DQCAL =\
+ LIBERO_SETTING_INIT_RD_DQCAL;
+ DDRCFG->MC_BASE2.INIT_START_DQSOSC.INIT_START_DQSOSC =\
+ LIBERO_SETTING_INIT_START_DQSOSC;
+ DDRCFG->MC_BASE2.INIT_STOP_DQSOSC.INIT_STOP_DQSOSC =\
+ LIBERO_SETTING_INIT_STOP_DQSOSC;
+ DDRCFG->MC_BASE2.INIT_ZQ_CAL_START.INIT_ZQ_CAL_START =\
+ LIBERO_SETTING_INIT_ZQ_CAL_START;
+ DDRCFG->MC_BASE2.CFG_WR_POSTAMBLE.CFG_WR_POSTAMBLE =\
+ LIBERO_SETTING_CFG_WR_POSTAMBLE;
+ DDRCFG->MC_BASE2.INIT_CAL_L_ADDR_0.INIT_CAL_L_ADDR_0 =\
+ LIBERO_SETTING_INIT_CAL_L_ADDR_0;
+ DDRCFG->MC_BASE2.INIT_CAL_L_ADDR_1.INIT_CAL_L_ADDR_1 =\
+ LIBERO_SETTING_INIT_CAL_L_ADDR_1;
+ DDRCFG->MC_BASE2.CFG_CTRLUPD_TRIG.CFG_CTRLUPD_TRIG =\
+ LIBERO_SETTING_CFG_CTRLUPD_TRIG;
+ DDRCFG->MC_BASE2.CFG_CTRLUPD_START_DELAY.CFG_CTRLUPD_START_DELAY =\
+ LIBERO_SETTING_CFG_CTRLUPD_START_DELAY;
+ DDRCFG->MC_BASE2.CFG_DFI_T_CTRLUPD_MAX.CFG_DFI_T_CTRLUPD_MAX =\
+ LIBERO_SETTING_CFG_DFI_T_CTRLUPD_MAX;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_SEL.CFG_CTRLR_BUSY_SEL =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_SEL;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_VALUE.CFG_CTRLR_BUSY_VALUE =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_VALUE;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_TURN_OFF_DELAY.CFG_CTRLR_BUSY_TURN_OFF_DELAY =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_TURN_OFF_DELAY;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW.CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_RESTART_HOLDOFF.CFG_CTRLR_BUSY_RESTART_HOLDOFF =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_RESTART_HOLDOFF;
+ DDRCFG->MC_BASE2.CFG_PARITY_RDIMM_DELAY.CFG_PARITY_RDIMM_DELAY =\
+ LIBERO_SETTING_CFG_PARITY_RDIMM_DELAY;
+ DDRCFG->MC_BASE2.CFG_CTRLR_BUSY_ENABLE.CFG_CTRLR_BUSY_ENABLE =\
+ LIBERO_SETTING_CFG_CTRLR_BUSY_ENABLE;
+ DDRCFG->MC_BASE2.CFG_ASYNC_ODT.CFG_ASYNC_ODT =\
+ LIBERO_SETTING_CFG_ASYNC_ODT;
+ DDRCFG->MC_BASE2.CFG_ZQ_CAL_DURATION.CFG_ZQ_CAL_DURATION =\
+ LIBERO_SETTING_CFG_ZQ_CAL_DURATION;
+ DDRCFG->MC_BASE2.CFG_MRRI.CFG_MRRI = LIBERO_SETTING_CFG_MRRI;
+ DDRCFG->MC_BASE2.INIT_ODT_FORCE_EN.INIT_ODT_FORCE_EN =\
+ LIBERO_SETTING_INIT_ODT_FORCE_EN;
+ DDRCFG->MC_BASE2.INIT_ODT_FORCE_RANK.INIT_ODT_FORCE_RANK =\
+ LIBERO_SETTING_INIT_ODT_FORCE_RANK;
+ DDRCFG->MC_BASE2.CFG_PHYUPD_ACK_DELAY.CFG_PHYUPD_ACK_DELAY =\
+ LIBERO_SETTING_CFG_PHYUPD_ACK_DELAY;
+ DDRCFG->MC_BASE2.CFG_MIRROR_X16_BG0_BG1.CFG_MIRROR_X16_BG0_BG1 =\
+ LIBERO_SETTING_CFG_MIRROR_X16_BG0_BG1;
+ DDRCFG->MC_BASE2.INIT_PDA_MR_W_REQ.INIT_PDA_MR_W_REQ =\
+ LIBERO_SETTING_INIT_PDA_MR_W_REQ;
+ DDRCFG->MC_BASE2.INIT_PDA_NIBBLE_SELECT.INIT_PDA_NIBBLE_SELECT =\
+ LIBERO_SETTING_INIT_PDA_NIBBLE_SELECT;
+ DDRCFG->MC_BASE2.CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH.CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH =\
+ LIBERO_SETTING_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH;
+ DDRCFG->MC_BASE2.CFG_CKSRE.CFG_CKSRE = LIBERO_SETTING_CFG_CKSRE;
+ DDRCFG->MC_BASE2.CFG_CKSRX.CFG_CKSRX = LIBERO_SETTING_CFG_CKSRX;
+ DDRCFG->MC_BASE2.CFG_RCD_STAB.CFG_RCD_STAB = LIBERO_SETTING_CFG_RCD_STAB;
+ DDRCFG->MC_BASE2.CFG_DFI_T_CTRL_DELAY.CFG_DFI_T_CTRL_DELAY =\
+ LIBERO_SETTING_CFG_DFI_T_CTRL_DELAY;
+ DDRCFG->MC_BASE2.CFG_DFI_T_DRAM_CLK_ENABLE.CFG_DFI_T_DRAM_CLK_ENABLE =\
+ LIBERO_SETTING_CFG_DFI_T_DRAM_CLK_ENABLE;
+ DDRCFG->MC_BASE2.CFG_IDLE_TIME_TO_SELF_REFRESH.CFG_IDLE_TIME_TO_SELF_REFRESH =\
+ LIBERO_SETTING_CFG_IDLE_TIME_TO_SELF_REFRESH;
+ DDRCFG->MC_BASE2.CFG_IDLE_TIME_TO_POWER_DOWN.CFG_IDLE_TIME_TO_POWER_DOWN =\
+ LIBERO_SETTING_CFG_IDLE_TIME_TO_POWER_DOWN;
+ DDRCFG->MC_BASE2.CFG_BURST_RW_REFRESH_HOLDOFF.CFG_BURST_RW_REFRESH_HOLDOFF =\
+ LIBERO_SETTING_CFG_BURST_RW_REFRESH_HOLDOFF;
+ DDRCFG->MC_BASE2.CFG_BG_INTERLEAVE.CFG_BG_INTERLEAVE =\
+ LIBERO_SETTING_CFG_BG_INTERLEAVE;
+ DDRCFG->MC_BASE2.CFG_REFRESH_DURING_PHY_TRAINING.CFG_REFRESH_DURING_PHY_TRAINING =\
+ LIBERO_SETTING_CFG_REFRESH_DURING_PHY_TRAINING;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P0.CFG_STARVE_TIMEOUT_P0 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P0;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P1.CFG_STARVE_TIMEOUT_P1 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P1;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P2.CFG_STARVE_TIMEOUT_P2 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P2;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P3.CFG_STARVE_TIMEOUT_P3 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P3;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P4.CFG_STARVE_TIMEOUT_P4 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P4;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P5.CFG_STARVE_TIMEOUT_P5 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P5;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P6.CFG_STARVE_TIMEOUT_P6 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P6;
+ DDRCFG->MPFE.CFG_STARVE_TIMEOUT_P7.CFG_STARVE_TIMEOUT_P7 =\
+ LIBERO_SETTING_CFG_STARVE_TIMEOUT_P7;
+ DDRCFG->REORDER.CFG_REORDER_EN.CFG_REORDER_EN =\
+ LIBERO_SETTING_CFG_REORDER_EN;
+ DDRCFG->REORDER.CFG_REORDER_QUEUE_EN.CFG_REORDER_QUEUE_EN =\
+ LIBERO_SETTING_CFG_REORDER_QUEUE_EN;
+ DDRCFG->REORDER.CFG_INTRAPORT_REORDER_EN.CFG_INTRAPORT_REORDER_EN =\
+ LIBERO_SETTING_CFG_INTRAPORT_REORDER_EN;
+ DDRCFG->REORDER.CFG_MAINTAIN_COHERENCY.CFG_MAINTAIN_COHERENCY =\
+ LIBERO_SETTING_CFG_MAINTAIN_COHERENCY;
+ DDRCFG->REORDER.CFG_Q_AGE_LIMIT.CFG_Q_AGE_LIMIT =\
+ LIBERO_SETTING_CFG_Q_AGE_LIMIT;
+ DDRCFG->REORDER.CFG_RO_CLOSED_PAGE_POLICY.CFG_RO_CLOSED_PAGE_POLICY =\
+ LIBERO_SETTING_CFG_RO_CLOSED_PAGE_POLICY;
+ DDRCFG->REORDER.CFG_REORDER_RW_ONLY.CFG_REORDER_RW_ONLY =\
+ LIBERO_SETTING_CFG_REORDER_RW_ONLY;
+ DDRCFG->REORDER.CFG_RO_PRIORITY_EN.CFG_RO_PRIORITY_EN =\
+ LIBERO_SETTING_CFG_RO_PRIORITY_EN;
+ DDRCFG->RMW.CFG_DM_EN.CFG_DM_EN = LIBERO_SETTING_CFG_DM_EN;
+ DDRCFG->RMW.CFG_RMW_EN.CFG_RMW_EN = LIBERO_SETTING_CFG_RMW_EN;
+ DDRCFG->ECC.CFG_ECC_CORRECTION_EN.CFG_ECC_CORRECTION_EN =\
+ LIBERO_SETTING_CFG_ECC_CORRECTION_EN;
+ DDRCFG->ECC.CFG_ECC_BYPASS.CFG_ECC_BYPASS = LIBERO_SETTING_CFG_ECC_BYPASS;
+ DDRCFG->ECC.INIT_WRITE_DATA_1B_ECC_ERROR_GEN.INIT_WRITE_DATA_1B_ECC_ERROR_GEN =\
+ LIBERO_SETTING_INIT_WRITE_DATA_1B_ECC_ERROR_GEN;
+ DDRCFG->ECC.INIT_WRITE_DATA_2B_ECC_ERROR_GEN.INIT_WRITE_DATA_2B_ECC_ERROR_GEN =\
+ LIBERO_SETTING_INIT_WRITE_DATA_2B_ECC_ERROR_GEN;
+ DDRCFG->ECC.CFG_ECC_1BIT_INT_THRESH.CFG_ECC_1BIT_INT_THRESH =\
+ LIBERO_SETTING_CFG_ECC_1BIT_INT_THRESH;
+ DDRCFG->READ_CAPT.INIT_READ_CAPTURE_ADDR.INIT_READ_CAPTURE_ADDR =\
+ LIBERO_SETTING_INIT_READ_CAPTURE_ADDR;
+ DDRCFG->MTA.CFG_ERROR_GROUP_SEL.CFG_ERROR_GROUP_SEL =\
+ LIBERO_SETTING_CFG_ERROR_GROUP_SEL;
+ DDRCFG->MTA.CFG_DATA_SEL.CFG_DATA_SEL = LIBERO_SETTING_CFG_DATA_SEL;
+ DDRCFG->MTA.CFG_TRIG_MODE.CFG_TRIG_MODE = LIBERO_SETTING_CFG_TRIG_MODE;
+ DDRCFG->MTA.CFG_POST_TRIG_CYCS.CFG_POST_TRIG_CYCS =\
+ LIBERO_SETTING_CFG_POST_TRIG_CYCS;
+ DDRCFG->MTA.CFG_TRIG_MASK.CFG_TRIG_MASK = LIBERO_SETTING_CFG_TRIG_MASK;
+ DDRCFG->MTA.CFG_EN_MASK.CFG_EN_MASK = LIBERO_SETTING_CFG_EN_MASK;
+ DDRCFG->MTA.MTC_ACQ_ADDR.MTC_ACQ_ADDR = LIBERO_SETTING_MTC_ACQ_ADDR;
+ DDRCFG->MTA.CFG_TRIG_MT_ADDR_0.CFG_TRIG_MT_ADDR_0 =\
+ LIBERO_SETTING_CFG_TRIG_MT_ADDR_0;
+ DDRCFG->MTA.CFG_TRIG_MT_ADDR_1.CFG_TRIG_MT_ADDR_1 =\
+ LIBERO_SETTING_CFG_TRIG_MT_ADDR_1;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_0.CFG_TRIG_ERR_MASK_0 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_0;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_1.CFG_TRIG_ERR_MASK_1 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_1;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_2.CFG_TRIG_ERR_MASK_2 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_2;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_3.CFG_TRIG_ERR_MASK_3 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_3;
+ DDRCFG->MTA.CFG_TRIG_ERR_MASK_4.CFG_TRIG_ERR_MASK_4 =\
+ LIBERO_SETTING_CFG_TRIG_ERR_MASK_4;
+ DDRCFG->MTA.MTC_ACQ_WR_DATA_0.MTC_ACQ_WR_DATA_0 =\
+ LIBERO_SETTING_MTC_ACQ_WR_DATA_0;
+ DDRCFG->MTA.MTC_ACQ_WR_DATA_1.MTC_ACQ_WR_DATA_1 =\
+ LIBERO_SETTING_MTC_ACQ_WR_DATA_1;
+ DDRCFG->MTA.MTC_ACQ_WR_DATA_2.MTC_ACQ_WR_DATA_2 =\
+ LIBERO_SETTING_MTC_ACQ_WR_DATA_2;
+ DDRCFG->MTA.CFG_PRE_TRIG_CYCS.CFG_PRE_TRIG_CYCS =\
+ LIBERO_SETTING_CFG_PRE_TRIG_CYCS;
+ DDRCFG->MTA.CFG_DATA_SEL_FIRST_ERROR.CFG_DATA_SEL_FIRST_ERROR =\
+ LIBERO_SETTING_CFG_DATA_SEL_FIRST_ERROR;
+ DDRCFG->DYN_WIDTH_ADJ.CFG_DQ_WIDTH.CFG_DQ_WIDTH =\
+ LIBERO_SETTING_CFG_DQ_WIDTH;
+ DDRCFG->DYN_WIDTH_ADJ.CFG_ACTIVE_DQ_SEL.CFG_ACTIVE_DQ_SEL =\
+ LIBERO_SETTING_CFG_ACTIVE_DQ_SEL;
+ DDRCFG->CA_PAR_ERR.INIT_CA_PARITY_ERROR_GEN_REQ.INIT_CA_PARITY_ERROR_GEN_REQ =\
+ LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_REQ;
+ DDRCFG->CA_PAR_ERR.INIT_CA_PARITY_ERROR_GEN_CMD.INIT_CA_PARITY_ERROR_GEN_CMD =\
+ LIBERO_SETTING_INIT_CA_PARITY_ERROR_GEN_CMD;
+ DDRCFG->DFI.CFG_DFI_T_RDDATA_EN.CFG_DFI_T_RDDATA_EN =\
+ LIBERO_SETTING_CFG_DFI_T_RDDATA_EN;
+ DDRCFG->DFI.CFG_DFI_T_PHY_RDLAT.CFG_DFI_T_PHY_RDLAT =\
+ LIBERO_SETTING_CFG_DFI_T_PHY_RDLAT;
+ DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT =\
+ LIBERO_SETTING_CFG_DFI_T_PHY_WRLAT;
+ DDRCFG->DFI.CFG_DFI_PHYUPD_EN.CFG_DFI_PHYUPD_EN =\
+ LIBERO_SETTING_CFG_DFI_PHYUPD_EN;
+ DDRCFG->DFI.INIT_DFI_LP_DATA_REQ.INIT_DFI_LP_DATA_REQ =\
+ LIBERO_SETTING_INIT_DFI_LP_DATA_REQ;
+ DDRCFG->DFI.INIT_DFI_LP_CTRL_REQ.INIT_DFI_LP_CTRL_REQ =\
+ LIBERO_SETTING_INIT_DFI_LP_CTRL_REQ;
+ DDRCFG->DFI.INIT_DFI_LP_WAKEUP.INIT_DFI_LP_WAKEUP =\
+ LIBERO_SETTING_INIT_DFI_LP_WAKEUP;
+ DDRCFG->DFI.INIT_DFI_DRAM_CLK_DISABLE.INIT_DFI_DRAM_CLK_DISABLE =\
+ LIBERO_SETTING_INIT_DFI_DRAM_CLK_DISABLE;
+ DDRCFG->DFI.CFG_DFI_DATA_BYTE_DISABLE.CFG_DFI_DATA_BYTE_DISABLE =\
+ LIBERO_SETTING_CFG_DFI_DATA_BYTE_DISABLE;
+ DDRCFG->DFI.CFG_DFI_LVL_SEL.CFG_DFI_LVL_SEL =\
+ LIBERO_SETTING_CFG_DFI_LVL_SEL;
+ DDRCFG->DFI.CFG_DFI_LVL_PERIODIC.CFG_DFI_LVL_PERIODIC =\
+ LIBERO_SETTING_CFG_DFI_LVL_PERIODIC;
+ DDRCFG->DFI.CFG_DFI_LVL_PATTERN.CFG_DFI_LVL_PATTERN =\
+ LIBERO_SETTING_CFG_DFI_LVL_PATTERN;
+ DDRCFG->DFI.PHY_DFI_INIT_START.PHY_DFI_INIT_START =\
+ LIBERO_SETTING_PHY_DFI_INIT_START;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI1_0.CFG_AXI_START_ADDRESS_AXI1_0 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_0;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI1_1.CFG_AXI_START_ADDRESS_AXI1_1 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI1_1;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI2_0.CFG_AXI_START_ADDRESS_AXI2_0 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_0;
+ DDRCFG->AXI_IF.CFG_AXI_START_ADDRESS_AXI2_1.CFG_AXI_START_ADDRESS_AXI2_1 =\
+ LIBERO_SETTING_CFG_AXI_START_ADDRESS_AXI2_1;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI1_0.CFG_AXI_END_ADDRESS_AXI1_0 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_0;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI1_1.CFG_AXI_END_ADDRESS_AXI1_1 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_1;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI2_0.CFG_AXI_END_ADDRESS_AXI2_0 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0;
+ DDRCFG->AXI_IF.CFG_AXI_END_ADDRESS_AXI2_1.CFG_AXI_END_ADDRESS_AXI2_1 =\
+ LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI1_0.CFG_MEM_START_ADDRESS_AXI1_0 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_0;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI1_1.CFG_MEM_START_ADDRESS_AXI1_1 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI1_1;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI2_0.CFG_MEM_START_ADDRESS_AXI2_0 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_0;
+ DDRCFG->AXI_IF.CFG_MEM_START_ADDRESS_AXI2_1.CFG_MEM_START_ADDRESS_AXI2_1 =\
+ LIBERO_SETTING_CFG_MEM_START_ADDRESS_AXI2_1;
+ DDRCFG->AXI_IF.CFG_ENABLE_BUS_HOLD_AXI1.CFG_ENABLE_BUS_HOLD_AXI1 =\
+ LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI1;
+ DDRCFG->AXI_IF.CFG_ENABLE_BUS_HOLD_AXI2.CFG_ENABLE_BUS_HOLD_AXI2 =\
+ LIBERO_SETTING_CFG_ENABLE_BUS_HOLD_AXI2;
+ DDRCFG->AXI_IF.CFG_AXI_AUTO_PCH.CFG_AXI_AUTO_PCH =\
+ LIBERO_SETTING_CFG_AXI_AUTO_PCH;
+ DDRCFG->csr_custom.PHY_RESET_CONTROL.PHY_RESET_CONTROL =\
+ LIBERO_SETTING_PHY_RESET_CONTROL;
+ DDRCFG->csr_custom.PHY_RESET_CONTROL.PHY_RESET_CONTROL =\
+ (LIBERO_SETTING_PHY_RESET_CONTROL & ~0x8000UL);
+ DDRCFG->csr_custom.PHY_PC_RANK.PHY_PC_RANK = LIBERO_SETTING_PHY_PC_RANK;
+ DDRCFG->csr_custom.PHY_RANKS_TO_TRAIN.PHY_RANKS_TO_TRAIN =\
+ LIBERO_SETTING_PHY_RANKS_TO_TRAIN;
+ DDRCFG->csr_custom.PHY_WRITE_REQUEST.PHY_WRITE_REQUEST =\
+ LIBERO_SETTING_PHY_WRITE_REQUEST;
+ DDRCFG->csr_custom.PHY_READ_REQUEST.PHY_READ_REQUEST =\
+ LIBERO_SETTING_PHY_READ_REQUEST;
+ DDRCFG->csr_custom.PHY_WRITE_LEVEL_DELAY.PHY_WRITE_LEVEL_DELAY =\
+ LIBERO_SETTING_PHY_WRITE_LEVEL_DELAY;
+ DDRCFG->csr_custom.PHY_GATE_TRAIN_DELAY.PHY_GATE_TRAIN_DELAY =\
+ LIBERO_SETTING_PHY_GATE_TRAIN_DELAY;
+ DDRCFG->csr_custom.PHY_EYE_TRAIN_DELAY.PHY_EYE_TRAIN_DELAY =\
+ LIBERO_SETTING_PHY_EYE_TRAIN_DELAY;
+ DDRCFG->csr_custom.PHY_EYE_PAT.PHY_EYE_PAT = LIBERO_SETTING_PHY_EYE_PAT;
+ DDRCFG->csr_custom.PHY_START_RECAL.PHY_START_RECAL =\
+ LIBERO_SETTING_PHY_START_RECAL;
+ DDRCFG->csr_custom.PHY_CLR_DFI_LVL_PERIODIC.PHY_CLR_DFI_LVL_PERIODIC =\
+ LIBERO_SETTING_PHY_CLR_DFI_LVL_PERIODIC;
+ DDRCFG->csr_custom.PHY_TRAIN_STEP_ENABLE.PHY_TRAIN_STEP_ENABLE =\
+ LIBERO_SETTING_PHY_TRAIN_STEP_ENABLE;
+ DDRCFG->csr_custom.PHY_LPDDR_DQ_CAL_PAT.PHY_LPDDR_DQ_CAL_PAT =\
+ LIBERO_SETTING_PHY_LPDDR_DQ_CAL_PAT;
+ DDRCFG->csr_custom.PHY_INDPNDT_TRAINING.PHY_INDPNDT_TRAINING =\
+ LIBERO_SETTING_PHY_INDPNDT_TRAINING;
+ DDRCFG->csr_custom.PHY_ENCODED_QUAD_CS.PHY_ENCODED_QUAD_CS =\
+ LIBERO_SETTING_PHY_ENCODED_QUAD_CS;
+ DDRCFG->csr_custom.PHY_HALF_CLK_DLY_ENABLE.PHY_HALF_CLK_DLY_ENABLE =\
+ LIBERO_SETTING_PHY_HALF_CLK_DLY_ENABLE;
+
+}
+
+
+/**
+ * setup_ddr_segments(void)
+ * setup segment registers- translated DDR address as user requires
+ */
+void setup_ddr_segments(SEG_SETUP option)
+{
+ if(option == DEFAULT_SEG_SETUP)
+ {
+ SEG[0].u[0].raw = (INIT_SETTING_SEG0_0 & 0x7FFFUL);
+ SEG[0].u[1].raw = (INIT_SETTING_SEG0_1 & 0x7FFFUL);
+ SEG[1].u[2].raw = (INIT_SETTING_SEG1_2 & 0x7FFFUL);
+ SEG[1].u[3].raw = (INIT_SETTING_SEG1_3 & 0x7FFFUL);
+ SEG[1].u[4].raw = (INIT_SETTING_SEG1_4 & 0x7FFFUL);
+ SEG[1].u[5].raw = (INIT_SETTING_SEG1_5 & 0x7FFFUL);
+ }
+ else
+ {
+ SEG[0].u[0].raw = (LIBERO_SETTING_SEG0_0 & 0x7FFFUL);
+ SEG[0].u[1].raw = (LIBERO_SETTING_SEG0_1 & 0x7FFFUL);
+ SEG[1].u[2].raw = (LIBERO_SETTING_SEG1_2 & 0x7FFFUL);
+ SEG[1].u[3].raw = (LIBERO_SETTING_SEG1_3 & 0x7FFFUL);
+ SEG[1].u[4].raw = (LIBERO_SETTING_SEG1_4 & 0x7FFFUL);
+ SEG[1].u[5].raw = (LIBERO_SETTING_SEG1_5 & 0x7FFFUL);
+ }
+ /*
+ * disable ddr blocker
+ * Is cleared at reset. When written to '1' disables the blocker function
+ * allowing the L2 cache controller to access the DDRC. Once written to '1'
+ * the register cannot be written to 0, only an MSS reset will clear the
+ * register
+ */
+ SEG[0].u[7].raw = 0x01U;
+}
+
+/**
+ * use_software_bclk_sclk_training()
+ * @param ddr_type
+ * @return returns 1U if required, otherwise 0U
+ */
+static uint8_t use_software_bclk_sclk_training(DDR_TYPE ddr_type)
+{
+ uint8_t result = 0U;
+ switch (ddr_type)
+ {
+ default:
+ case DDR_OFF_MODE:
+ break;
+ case DDR3L:
+ result = 1U;
+ break;
+ case DDR3:
+ result = 1U;
+ break;
+ case DDR4:
+ result = 1U;
+ break;
+ case LPDDR3:
+ result = 1U;
+ break;
+ case LPDDR4:
+ result = 1U;
+ break;
+ }
+ return(result);
+}
+
+/**
+ * config_ddr_io_pull_up_downs_rpc_bits()
+ *
+ * This function overrides the RPC bits related to weak pull up and
+ * weak pull downs. It also sets the override bit if the I/O is disabled.
+ * The settings come fro m Libero
+ *
+ * Note: If LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9 is not present, indicates older
+ * Libero core (pre 2.0.109)
+ * Post 2.0.109 version of Libero MSS core, weak pull up and pull down
+ * settings come from Libero, along with setting unused MSS DDR I/O to
+ * override.
+ *
+ */
+static void config_ddr_io_pull_up_downs_rpc_bits(DDR_TYPE ddr_type)
+{
+ if(ddr_type == LPDDR4) /* we will add other variants here once verified */
+ {
+#ifdef LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9
+ /* set over-rides (associated bit set to 1 if I/O not being used */
+ CFG_DDR_SGMII_PHY->ovrt9.ovrt9 = LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9;
+ CFG_DDR_SGMII_PHY->ovrt10.ovrt10 = LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10;
+ CFG_DDR_SGMII_PHY->ovrt11.ovrt11 = LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11;
+ CFG_DDR_SGMII_PHY->ovrt12.ovrt12 = LIBERO_SETTING_RPC_EN_DATA0_OVRT12;
+ CFG_DDR_SGMII_PHY->ovrt13.ovrt13 = LIBERO_SETTING_RPC_EN_DATA1_OVRT13;
+ CFG_DDR_SGMII_PHY->ovrt14.ovrt14 = LIBERO_SETTING_RPC_EN_DATA2_OVRT14;
+ CFG_DDR_SGMII_PHY->ovrt15.ovrt15 = LIBERO_SETTING_RPC_EN_DATA3_OVRT15;
+ CFG_DDR_SGMII_PHY->ovrt16.ovrt16 = LIBERO_SETTING_RPC_EN_ECC_OVRT16;
+ /* set the required wpu state- note: associated I/O bit 1=> off, 0=> on */
+ CFG_DDR_SGMII_PHY->rpc235.rpc235 = LIBERO_SETTING_RPC235_WPD_ADD_CMD0;
+ CFG_DDR_SGMII_PHY->rpc236.rpc236 = LIBERO_SETTING_RPC236_WPD_ADD_CMD1;
+ CFG_DDR_SGMII_PHY->rpc237.rpc237 = LIBERO_SETTING_RPC237_WPD_ADD_CMD2;
+ CFG_DDR_SGMII_PHY->rpc238.rpc238 = LIBERO_SETTING_RPC238_WPD_DATA0;
+ CFG_DDR_SGMII_PHY->rpc239.rpc239 = LIBERO_SETTING_RPC239_WPD_DATA1;
+ CFG_DDR_SGMII_PHY->rpc240.rpc240 = LIBERO_SETTING_RPC240_WPD_DATA2;
+ CFG_DDR_SGMII_PHY->rpc241.rpc241 = LIBERO_SETTING_RPC241_WPD_DATA3;
+ CFG_DDR_SGMII_PHY->rpc242.rpc242 = LIBERO_SETTING_RPC242_WPD_ECC;
+ /* set the required wpd state- note: associated I/O bit 1=> off, 0=> on */
+ CFG_DDR_SGMII_PHY->rpc243.rpc243 = LIBERO_SETTING_RPC243_WPU_ADD_CMD0;
+ CFG_DDR_SGMII_PHY->rpc244.rpc244 = LIBERO_SETTING_RPC244_WPU_ADD_CMD1;
+ CFG_DDR_SGMII_PHY->rpc245.rpc245 = LIBERO_SETTING_RPC245_WPU_ADD_CMD2;
+ CFG_DDR_SGMII_PHY->rpc246.rpc246 = LIBERO_SETTING_RPC246_WPU_DATA0;
+ CFG_DDR_SGMII_PHY->rpc247.rpc247 = LIBERO_SETTING_RPC247_WPU_DATA1;
+ CFG_DDR_SGMII_PHY->rpc248.rpc248 = LIBERO_SETTING_RPC248_WPU_DATA2;
+ CFG_DDR_SGMII_PHY->rpc249.rpc249 = LIBERO_SETTING_RPC249_WPU_DATA3;
+ CFG_DDR_SGMII_PHY->rpc250.rpc250 = LIBERO_SETTING_RPC250_WPU_ECC;
+#endif
+ }
+}
+
+
+/**
+ * get the best sweep value
+ * @param good_index
+ * @return
+ */
+#ifdef SWEEP_ENABLED
+static uint8_t get_best_sweep(sweep_index *good_index)
+{
+#ifdef EXTRACT_SWEEP_RESULT
+ uint8_t cmd_index;
+ uint8_t bclk_sclk_index;
+ uint8_t dpc_vgen_index;
+ uint8_t dpc_vgen_h_index;
+ uint8_t dpc_vgen_vs_index;
+ uint8_t good_in_row;
+
+ for (dpc_vgen_vs_index=0U; dpc_vgen_vs_index < MAX_NUMBER_DPC_VS_GEN_SWEEPS; dpc_vgen_vs_index++)
+ {
+ for (dpc_vgen_h_index=0U; dpc_vgen_h_index < MAX_NUMBER_DPC_H_GEN_SWEEPS; dpc_vgen_h_index++)
+ {
+ for (dpc_vgen_index=0U; dpc_vgen_index < MAX_NUMBER_DPC_V_GEN_SWEEPS; dpc_vgen_index++)
+ {
+ for (bclk_sclk_index=0U; bclk_sclk_index < MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS; bclk_sclk_index++)
+ {
+ good_in_row = 0U;
+ for (cmd_index=0U; cmd_index < MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS; cmd_index++)
+ {
+ if (sweep_results[dpc_vgen_vs_index][dpc_vgen_h_index][dpc_vgen_index][bclk_sclk_index][cmd_index]\
+ == CALIBRATION_PASSED)
+ {
+ good_in_row++;
+ /*
+ * look for 3 in a row,in x and y direction and pick the
+ * middle one
+ * */
+ if((good_in_row > 2U)&&(bclk_sclk_index>1)&&(bclk_sclk_indexdpc_vgen_vs_index = dpc_vgen_vs_index;
+ good_index->dpc_vgen_h_index = dpc_vgen_h_index;
+ good_index->bclk_sclk_index = bclk_sclk_index;
+ good_index->dpc_vgen_index = dpc_vgen_index;
+ good_index->cmd_index = cmd_index - 1U;
+ return(0U);
+ }
+ }
+ }
+ else
+ {
+ good_in_row = 0U;
+ }
+ }
+ }
+ }
+ }
+ }
+ return(1U);
+#else /* EXTRACT_SWEEP_RESULT */
+ good_index->dpc_vgen_vs_index = 0U;
+ good_index->dpc_vgen_h_index = 0U;
+ good_index->bclk_sclk_index = 0U;
+ good_index->dpc_vgen_index = 0U;
+ good_index->cmd_index = 0U;
+ return(0U);
+#endif
+}
+#endif /* SWEEP_ENABLED */
+
+
+#ifdef DDR_DIAGNOSTICS /* todo: add support for diagnostics below during board bring-up */
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_DDR_status() function is used to return status information to the
+ user.
+
+ TODO: Define number of request inputs
+
+ @param option
+ This option chooses status data we wish returned
+
+ @param return_data
+ Returned data here. This must be within a defined range.
+ todo:Detail on the sharing of data will be system dependent.
+ AMP/SMU detail to be finalized at time of writing
+
+ @return
+ Returns 0 on success.
+ TODO: Define error codes.
+
+ Example:
+ The call to MSS_DDR_status(DDR_TYPE, return_data) will return 0 if
+ successful and the DDR type in the first four bytes of the ret_mem area.
+ @code
+ MSS_DDR_status( DDR_TYPE, ret_mem );
+ @endcode
+ */
+uint8_t
+MSS_DDR_status
+(
+ uint8_t option, uint32_t *return_data
+)
+{
+ uint8_t error = 0U;
+
+ switch (option)
+ {
+ case USR_OPTION_tip_register_dump:
+ /* todo: WIP
+ * add commands here */
+ break;
+
+ default:
+
+ break;
+ }
+
+ return error;
+}
+
+
+/*-------------------------------------------------------------------------*//**
+ * MSS_DDR_user_commands commands from the user
+ *
+ * @param command
+ * User command
+ * @param extra_command_data
+ * extra data from user for particular command
+ * @param return_data
+ * data returned via supplied pointer
+ * @return
+ * status 0 => success
+ *
+ * Example:
+ The call to
+ MSS_DDR_user_commands(USR_CMD_INC_DELAY_LINE, 0x01 , return_data)
+ will return 0 id successful and the
+ DDR type in the first four bytes of the ret_mem area.
+ @code
+ MSS_DDR_user_commands(USR_CMD_INC_DELAY_LINE, 0x01 , return_data);
+ @endcode
+ */
+uint8_t
+MSS_DDR_user_commands
+(
+ uint8_t command, uint32_t *extra_command_data, uint32_t *return_data, \
+ uint32_t return_size
+)
+{
+ uint8_t error = 0U;
+ uint32_t *reg_address;
+
+ switch (command)
+ {
+ case USR_CMD_GET_DDR_STATUS:
+ break;
+ case USR_CMD_GET_MODE_SETTING:
+ break;
+ case USR_CMD_GET_W_CALIBRATION:
+ config_copy(return_data, &calib_data, sizeof(calib_data));
+ break;
+ case USR_CMD_GET_GREEN_ZONE:
+ /* READ DQ WINDOW MEASUREMENT */
+ /* READ DQS WINDOW MEASUREMENT */
+ /* READ VREF WINDOW MAX MEASUREMENT */
+
+ break;
+
+ case USR_CMD_GET_REG:
+ /*
+ * First check if address valid
+ */
+ config_copy(reg_address, extra_command_data, 4U);
+ reg_address = (uint32_t *)((uint32_t)reg_address &\
+ (uint32_t)(0xFFFFFFFCUL));
+ if ((reg_address >=\
+ &CFG_DDR_SGMII_PHY->SOFT_RESET_DDR_PHY.SOFT_RESET_DDR_PHY)\
+ && (reg_address < &CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT))
+ {
+ config_copy(return_data, reg_address, sizeof(uint32_t));
+ }
+ else
+ {
+ error = 1U;
+ }
+ break;
+
+ /*
+ * And set commands
+ */
+ case USR_CMD_SET_GREEN_ZONE_DQ:
+ /* READ DQ WINDOW MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & DQ delayline controls, to
+ * measure the maximum DQ offset before failure.
+ */
+ break;
+ case USR_CMD_SET_GREEN_ZONE_DQS:
+ /* READ DQS WINDOW MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & DQS delayline controls, to
+ * measure the maximum DQS offset before failure.
+ */
+ break;
+ case USR_CMD_SET_GREEN_ZONE_VREF_MAX:
+ /* READ VREF WINDOW MAX MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & VREF controller delayline
+ * controls, to measure the max VREF level.
+ */
+ break;
+ case USR_CMD_SET_GREEN_ZONE_VREF_MIN:
+ /* READ VREF WINDOW MIN MEASUREMENT */
+ /*
+ * This procedure is uses reads/writes & VREF controller delayline
+ * controls, to measure the minimum VREF level.
+ */
+ break;
+ case USR_CMD_SET_RETRAIN:
+ /* Incremental, In-System Retraining Procedures */
+ /*
+ * This procedure adjusts the read window to re-center clock and
+ * data.
+ * It should be triggered when the DLL code value passes a certain
+ * threshold, during a refresh cycle.
+ * Added here to allow the user to trigger.
+ */
+ break;
+ case USR_CMD_SET_REG:
+ break;
+
+ default:
+ error = 1U;
+ break;
+ }
+ return error;
+}
+#endif
+
+#ifdef DEBUG_DDR_INIT
+#ifdef DEBUG_DDR_DDRCFG
+void debug_read_ddrcfg(void)
+{
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->ADDR_MAP,\
+ (sizeof(DDRCFG->ADDR_MAP)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MC_BASE3,\
+ (sizeof(DDRCFG->MC_BASE3)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MC_BASE1,\
+ (sizeof(DDRCFG->MC_BASE1)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MC_BASE2,\
+ (sizeof(DDRCFG->MC_BASE2)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MPFE,\
+ (sizeof(DDRCFG->MPFE)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->REORDER,\
+ (sizeof(DDRCFG->REORDER)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->RMW,\
+ (sizeof(DDRCFG->RMW)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->ECC,\
+ (sizeof(DDRCFG->ECC)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->READ_CAPT,\
+ (sizeof(DDRCFG->READ_CAPT)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->MTA,\
+ (sizeof(DDRCFG->MTA)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->DYN_WIDTH_ADJ,\
+ (sizeof(DDRCFG->DYN_WIDTH_ADJ)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->CA_PAR_ERR,\
+ (sizeof(DDRCFG->CA_PAR_ERR)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->DFI,\
+ (sizeof(DDRCFG->DFI)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->AXI_IF,\
+ (sizeof(DDRCFG->AXI_IF)/4U));
+ (void)print_reg_array(g_debug_uart ,
+ (uint32_t *)&DDRCFG->csr_custom,\
+ (sizeof(DDRCFG->csr_custom)/4U));
+ return;
+}
+#endif
+#endif
+
+
+const uint8_t REFCLK_OFFSETS[][5U] = {
+ {LIBERO_SETTING_REFCLK_DDR3_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR3L_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR4_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_3},
+
+ {LIBERO_SETTING_REFCLK_DDR3_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR3L_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_DDR4_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_3},
+ {
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_NUM_OFFSETS,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_0,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_1,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_2,
+ LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_3},
+};
+
+/**
+ * ddr_manual_addcmd_refclk_offset This function determines current
+ * sweep offset based on DDR type
+ * @param ddr_type
+ * @param refclk_sweep_index
+ * @return
+ */
+#ifdef MANUAL_ADDCMD_TRAINIG
+static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index)
+{
+ uint8_t refclk_offset;
+ uint8_t type_array_index;
+
+ type_array_index = (uint8_t)ddr_type;
+ if(LIBERO_SETTING_DDR_CLK == DDR_1333_MHZ)
+ {
+ type_array_index = type_array_index + (uint8_t)LPDDR4;
+ }
+
+ if (*refclk_sweep_index >= REFCLK_OFFSETS[type_array_index][0U])
+ {
+ *refclk_sweep_index = 0U;
+ }
+
+ refclk_offset = REFCLK_OFFSETS[type_array_index][*refclk_sweep_index + 1U];
+
+ *refclk_sweep_index = (*refclk_sweep_index + 1U);
+
+ return refclk_offset;
+}
+#endif
+
+
+#endif /* DDR_SUPPORT */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr.h
new file mode 100644
index 00000000..da8cc8d9
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr.h
@@ -0,0 +1,1133 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief DDR related defines
+ *
+ */
+
+/*=========================================================================*//**
+ @page DDR setup and monitoring
+ ==============================================================================
+ @section intro_sec Introduction
+ ==============================================================================
+ The MPFS microcontroller subsystem (MSS) includes a number of hard core
+ components physically located in the north west corner of the MSS on the die.
+ This includes the DDR Phy.
+
+ ==============================================================================
+ @section Items located in the north west corner
+ ==============================================================================
+ - MSS PLL
+ - SGMII
+ - DDR phy
+ - MSSIO
+
+ ==============================================================================
+ @section Overview of DDR related hardware
+ ==============================================================================
+
+ Simplified IP diagram
+
+
+ +--+
+ +--++ +-----+ +---v--+ |o |
+ |H0 | |H1-H4+--------> AXI | |t |
+ ++--+ +-+---+ |switch<---+h |
+ | | | | |e |
+ | | +--+---+ |r |
+ +v------v-------+ | | |
+ |L2 cache | non-cache |m |
+ +------------+--+ | |a |
+ +---v----+ +---v---+ |s |
+ |seg 0 | | seg 1 | |t |
+ +----^---+ +---^---+ |e |
+ | | |r |
+ +-----------+------+----v---------v---+ |s |
+ |Training IP|MTC |DDR controller | +--+
+ +-----------+------+--------+---------+
+ |DFI
+ |
+ +---------v--------+
+ | DDR Phy |
+ +------------------+
+ | Bank 6 I/O |
+ +-------+----------+
+ |
+ +----------v---------------+
+ | +--+ +--+ +--+ +--+ +--+ |
+ | |D | |D | |R | | | | | |
+ | +--+ +--+ +--+ +--+ +--+ |
+ +--------------------------+
+
+
+ -----------
+ Hart0 E51
+ -----------
+ In most systems, the E51 will will setup and monitor the DDR
+
+ -----------
+ L2 Cache
+ -----------
+ Specific address range is used to access DDR via cache
+
+ -----------
+ AXI switch
+ -----------
+ DDR access via AXI switch for non-cached read/write
+
+ -----------
+ SEG regs
+ -----------
+ Used to map internal DDR address range to external fixed mapping.
+ Note: DDR address ranges are at 32 bit and 64 bits
+
+ -----------
+ DDR controller
+ -----------
+ Manages DDR, refresh rates etc
+
+ -----------
+ DDR Training IP
+ -----------
+ Used to carry out training using IP state machines
+ - BCLKSCLK_TIP_TRAINING .
+ - addcmd_TIP_TRAINING
+ - wrlvl_TIP_TRAINING
+ - rdgate_TIP_TRAINING
+ - dq_dqs_opt_TIP_TRAINING
+
+ -----------
+ DDR MTC - Memory test controller
+ -----------
+ Sends/receives test patterns to DDR. More efficient than using software.
+ Used during write calibration and in DDR test routines.
+
+ -----------
+ DFI
+ -----------
+ Industry standard interface between phy, DDRC
+
+ -----------
+ DDR phy
+ -----------
+ PolarFire-SoC DDR phy manges data paath between pins and DFI
+
+ ==============================================================================
+ @section Overview of DDR embedded software
+ ==============================================================================
+
+ -----------
+ Setup
+ -----------
+ - phy and IO
+ - DDRC
+
+ -----------
+ Use Training IP
+ -----------
+ - kick-off RTL training IP state machine
+ - Verify all training complete
+ - BCLKSCLK_TIP_TRAINING .
+ - addcmd_TIP_TRAINING
+ This is a coarse training that moves the DDRCLK with PLL phase
+ rotations in relation to the Address/Command bits to achieve the
+ desired offset on the FPGA side.
+ - wrlvl_TIP_TRAINING
+ - rdgate_TIP_TRAINING
+ - dq_dqs_opt_TIP_TRAINING
+
+ Test this reg to determine training status:
+ DDRCFG->DFI.STAT_DFI_TRAINING_COMPLETE.STAT_DFI_TRAINING_COMPLETE;
+
+ -----------
+ Write Calibration
+ -----------
+ The Memory Test Core plugged in to the front end of the DDR controller is used
+ to perform lane-based writes and read backs and increment write calibration
+ offset for each lane until data match occurs. The settings are recorded by the
+ driver and available to be read using by an API function call.
+
+ -----------
+ VREF Calibration (optional)
+ -----------
+ VREF (DDR4 + LPDDR4 only) Set Remote VREF via mode register writes (MRW).
+ In DDR4 and LPDDR4, VREF training may be done by writing to Mode Register 6 as
+ defined by the JEDEC spec and, for example, Micron's datasheet for its 4Gb
+ DDR4 RAM's:
+
+ MR6 register definition from DDR4 datasheet
+
+ | Mode Reg | Description |
+ | ------------- |:---------------------------------------------------:|
+ | 13,9,8 | DQ RX EQ must be 000 |
+ | 7 | Vref calib enable = => disables, 1 ==> enabled |
+ | 6 | Vref Calibration range 0 = Range 0, 1 - Range 2 |
+ | 5:0 | Vref Calibration value |
+
+ This step is not implemented in the current driver. It can be implemented in
+ the same way as write Calibration and will be added during board verification.
+
+ -----------
+ FPGA VREF (Local VREF training) (optional)
+ -----------
+ In addition to memory VREFDQ training, or remote training, it is possible to
+ train the VREFDQ on the FPGA device. WE refer to this training as local VREF
+ training.
+ Train FPGA VREF using the vrgen_h and vrgen_v registers
+ To manipulate the FPGA VREF value, firmware must write to the DPC_BITS
+ register, located at physical address 0x2000 7184.
+ CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_h;
+ CFG_DDR_SGMII_PHY->DPC_BITS.bitfield.dpc_vrgen_v;
+ Like memory VREFDQ training, FPGA VREFDQ training seeks to find an average/
+ optimal VREF value by sweeping across the full range and finding a left edge
+ and a right edge.
+ This step is not implemented in the current driver. It can be implemented in
+ the same way as write Calibration and will be added during board verification.
+
+ -----------
+ DQ Write Offset
+ -----------
+ (LPDDR4 only) ), there must be an offset at the input to the LPDDR4 memory
+ device between DQ and DQS. Unlike other flavors of DDR, which match DQ and DQS
+ at the SDRAM, for LPDDR4 this relationship must be trained, because it will
+ vary between 200ps and 600ps, which, depending on the data rate, could be as
+ much as one whole bit period.
+ This training is integrated with write calibration, because it, too, is done
+ on a per-lane basis. That is, each lane is trained separately by sweeping the
+ DQ output delay to find a valid range and of DQ output delays and center it.
+ DQ output delays are swept using the expert_dlycnt_move_reg0 register located
+ in the MSS DDR TIP.
+
+
+ -----------
+ Overview Flow diagram of Embedded software setup
+ -----------
+
+ +--------------------------------------------+
+ | Some Preconditions |
+ | DCE, CORE_UP, FLASH VALID, MSS_IO_EN |
+ | MSS PLL setup, Clks to MSS setup |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Check if in off mode, ret if so |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | set ddr mode and VS bits |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | soft reset I/O decoders |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Set RPC registers that need manual setup |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Soft reset IP- to load RPC ->SCB regs |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Calibrate I/O - as they are now setup |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Configure the DDR PLL - Using SCB writes |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Setup the SEG regs - NB May move this down|
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Set-up the DDRC - Using Libero values |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Reset training IP |
+ +--------------------+-----------------------+
+ |
+ +----------------- --v-----------------------+
+ | Rotate BCLK by programmed amount (degrees)|
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Set training parameters |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Assert traing reset |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Wait until traing complete |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Write calibrate |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | If LPDDR4, calibrate DQ |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Sanity check training |
+ +--------------------+-----------------------+
+ |
+ +--------------------v-----------------------+
+ | Return 0 if all went OK |
+ +--------------------------------------------+
+
+ *//*=========================================================================*/
+
+
+#ifndef __MSS_DDRC_H_
+#define __MSS_DDRC_H_ 1
+
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_TYPE_
+{
+
+ DDR3 = 0x00, /*!< 0 DDR3 */
+ DDR3L = 0x01, /*!< 1 DDR3L */
+ DDR4 = 0x02, /*!< 2 DDR4 */
+ LPDDR3 = 0x03, /*!< 3 LPDDR3 */
+ LPDDR4 = 0x04, /*!< 4 LPDDR4 */
+ DDR_OFF_MODE = 0x07 /*!< 4 LPDDR4 */
+} DDR_TYPE;
+
+typedef enum DDR_MEMORY_ACCESS_
+{
+ DDR_NC_256MB,
+ DDR_NC_WCB_256MB,
+ DDR_NC_2GB,
+ DDR_NC_WCB_2GB,
+} DDR_MEMORY_ACCESS;
+
+/* this is a fixed value, currently only 5 supported in the TIP */
+#define MAX_POSSIBLE_TIP_TRAININGS 0x05U
+
+/* LIBERO_SETTING_TIP_CFG_PARAMS
+ * ADDCMD_OFFSET [0:3] RW value */
+#define ADDRESS_CMD_OFFSETT_MASK (0x7U<<0U)
+
+#define BCLK_SCLK_OFFSET_SHIFT (3U)
+#define BCLK_SCLK_OFFSET_MASK (0x7U<<3U)
+
+#define BCLK_DPC_VRGEN_V_SHIFT (12U)
+#define BCLK_DPC_VRGEN_V_MASK (0x3FU<<12U)
+
+#define BCLK_DPC_VRGEN_H_SHIFT (4U)
+#define BCLK_DPC_VRGEN_H_MASK (0xFU<<4U)
+
+#define BCLK_DPC_VRGEN_VS_SHIFT (0U)
+#define BCLK_DPC_VRGEN_VS_MASK (0xFU<<0U)
+
+
+/* masks and associated values used with DDRPHY_MODE register */
+#define DDRPHY_MODE_MASK 0x7U
+/* ECC */
+#define DDRPHY_MODE_ECC_MASK (0x1U<<3U)
+#define DDRPHY_MODE_ECC_ON (0x1U<<3U)
+/* Bus width */
+#define DDRPHY_MODE_BUS_WIDTH_4_LANE (0x1U<<5U)
+#define DDRPHY_MODE_BUS_WIDTH_MASK (0x7U<<5U)
+/* Number of ranks, 1 or 2 supported */
+#define DDRPHY_MODE_RANK_MASK (0x1U<<26U)
+#define DDRPHY_MODE_ONE_RANK (0x0U<<26U)
+#define DDRPHY_MODE_TWO_RANKS (0x1U<<26U)
+
+#define DMI_DBI_MASK (~(0x1U<<8U))
+
+/* Write latency min/max settings If write calibration fails
+ * For Libero setting, we iterate through these values looking for a
+ * Calibration pass */
+#define MIN_LATENCY 0UL
+#define MAX_LATENCY 3UL //ML fixme- agree this value with Alister
+
+#define MTC_TIMEOUT_ERROR 0x02U
+
+#define DDR_MODE_REG_VREF 0xCU
+
+#define CALIBRATION_PASSED 0xFF
+#define CALIBRATION_FAILED 0xFE
+#define CALIBRATION_SUCCESS 0xFC
+
+/*
+ * Some settings that are only used during testing in new DDR setup
+ */
+/* #define LANE_ALIGNMENT_RESET_REQUIRED leave commented, not required */
+#define ABNORMAL_RETRAIN_CA_DECREASE_COUNT 2U
+#define ABNORMAL_RETRAIN_CA_DLY_DECREASE_COUNT 2U
+#define DQ_DQS_NUM_TAPS 5U
+
+#if !defined (LIBERO_SETTING_MAX_MANUAL_REF_CLK_PHASE_OFFSET)
+#define LIBERO_SETTING_MAX_MANUAL_REF_CLK_PHASE_OFFSET 4U
+#endif
+#if !defined (LIBERO_SETTING_MIN_MANUAL_REF_CLK_PHASE_OFFSET)
+#define LIBERO_SETTING_MIN_MANUAL_REF_CLK_PHASE_OFFSET 2U
+#endif
+#if !defined (LIBERO_SETTING_MANUAL_REF_CLK_PHASE_OFFSET)
+/* If skipping add/cmd training, this value is used */
+/* The value used may be trained. The value here should be determined */
+/* for the board design by performing a manual sweep. */
+#define LIBERO_SETTING_MANUAL_REF_CLK_PHASE_OFFSET 0x00000006UL
+ /* CA_BUS_RX_OFF_POST_TRAINING [0:1] RW value= 0x1 */
+#endif
+
+/*
+ * We currently need at least one retrain, otherwise driver can get stuck in
+ * sanity check state
+ */
+#if !defined (EN_RETRY_ON_FIRST_TRAIN_PASS)
+#define EN_RETRY_ON_FIRST_TRAIN_PASS 0
+#endif
+
+#if !defined (DDR_FULL_32BIT_NC_CHECK_EN)
+#define DDR_FULL_32BIT_NC_CHECK_EN 1
+#endif
+
+#if !defined (DDR_FULL_32BIT_CACHED_CHECK_EN)
+#define DDR_FULL_32BIT_CACHED_CHECK_EN 0
+#endif
+
+#if !defined (NO_PATTERN_IN_CACHE_READS)
+#define NO_PATTERN_IN_CACHE_READS 1
+#endif
+
+#if !defined (SIZE_OF_PATTERN_TEST)
+#define SIZE_OF_PATTERN_TEST 0x02000000UL
+#endif
+
+#if !defined (SIZE_OF_PATTERN_OFFSET)
+#define SIZE_OF_PATTERN_OFFSET 12U
+#endif
+
+#if !defined (DEFAULT_RPC_166_VALUE)
+#define DEFAULT_RPC_166_VALUE 2UL
+#endif
+
+/* set to 0 if you want to turn off tuning */
+#if !defined (TUNE_RPC_166_VALUE)
+#define TUNE_RPC_166_VALUE 1
+#endif
+
+#if !defined (MIN_RPC_166_VALUE)
+#define MIN_RPC_166_VALUE 2UL
+#endif
+
+#if !defined (MAX_RPC_166_VALUE)
+#define MAX_RPC_166_VALUE 4UL
+#endif
+
+#define NUM_RPC_166_VALUES (MAX_RPC_166_VALUE - MIN_RPC_166_VALUE)
+
+/* This is a fixed setting, will move into driver in next commit */
+#if !defined (SW_TRAING_BCLK_SCLK_OFFSET)
+#define SW_TRAING_BCLK_SCLK_OFFSET 0x00000000UL
+#endif
+/*
+ * 0x6DU => setting vref_ca to 40%
+ * This (0x6DU) is the default setting.
+ * Currently not being used, here for possible future use.
+ * */
+#if !defined (DDR_MODE_REG_VREF_VALUE)
+#define DDR_MODE_REG_VREF_VALUE 0x6DU
+#endif
+
+/* number of test writes to perform */
+#if !defined (SW_CFG_NUM_READS_WRITES)
+#define SW_CFG_NUM_READS_WRITES 0x20000U
+#endif
+/*
+ * what test patterns to write/read on start-up
+ * */
+#if !defined (SW_CONFIG_PATTERN)
+#define SW_CONFIG_PATTERN (PATTERN_INCREMENTAL|\
+ PATTERN_WALKING_ONE|\
+ PATTERN_WALKING_ZERO|\
+ PATTERN_RANDOM|\
+ PATTERN_0xCCCCCCCC|\
+ PATTERN_0x55555555)
+#endif
+
+/*
+ * Sweep offsets
+ * They currently are not coming from MSS Configurator (v12.7 and earlier)
+ * They may at some point
+ *
+ * Determined ( 5th Feb 2021 )
+ * DDR3@1066 = 3,2,1
+ * DDR4@1600 = 7,0,1
+ * LPDDR3@1066 = 7,0,1
+ * LPDDR4@1600 = 5,4,6,3
+ *
+ * DDR3@1333 = 1,7,0,2
+ * DDR4@1333 = 0,7,1
+ * LPDDR3@1333 = 7,0,6
+ * LPDDR4@1333 = 1,2,3
+ *
+ */
+#if !defined (VREF_TRAINING_MIN)
+#define VREF_TRAINING_MIN 5U
+#endif
+#if !defined (VREF_TRAINING_MAX)
+#define VREF_TRAINING_MAX 30U
+#endif
+#if !defined (CA_SWEEP_START)
+#define CA_SWEEP_START 0U
+#endif
+#if !defined (CA_SWEEP_END)
+#define CA_SWEEP_END 30U
+#endif
+#if !defined (CA_SWEEP_INCREMENT)
+#define CA_SWEEP_INCREMENT 5U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_NUM_OFFSETS 4U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_NUM_OFFSETS 4U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_NUM_OFFSETS 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_NUM_OFFSETS)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_NUM_OFFSETS 3U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_0 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_1 2U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3_1600_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_0 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_1 2U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3L_1600_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_0 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_1 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR4_1600_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_0 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_1 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1600_OFFSET_3 0U
+#endif
+//LPDDR4@1600 = 5,4,6,3 changed to 5,4,6,2 16th Feb Alister
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_0 5U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_1 4U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_2 6U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1600_OFFSET_3 3U
+#endif
+
+/*
+ * 1333 offset
+ */
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_0 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_1 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_2 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3_1333_OFFSET_3 2U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_0 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_1 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_2 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR3L_1333_OFFSET_3 2U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_0 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_1 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_2 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_DDR4_1333_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_0 7U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_1 0U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_2 6U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR3_1333_OFFSET_3 0U
+#endif
+
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_0)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_0 1U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_1)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_1 2U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_2)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_2 3U
+#endif
+#if !defined (LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_3)
+#define LIBERO_SETTING_REFCLK_LPDDR4_1333_OFFSET_3 0U
+#endif
+
+/* Bit1 == 0 => 1600Mhz Bit1 == 1 => 1333Mhz */
+#if !defined (LIBERO_SETTING_DDR_CLK)
+#define LIBERO_SETTING_DDR_CLK 1600000000
+#endif
+
+#define DDR_1333_MHZ 1333333333
+#define DDR_1600_MHZ 1600000000
+
+#ifndef NOT_A_FULL_RETRAIN
+#define NOT_A_FULL_RETRAIN
+#endif
+
+#if !defined (RPC_OVERRIDE_166_LANE_FIFO)
+#define RPC_OVERRIDE_166_LANE_FIFO 0
+#endif
+
+#define ONE_GB_MTC 30U
+#define HALF_GB_MTC 29U
+#define ONE_MB_MTC 20U
+
+
+/*Cached access at 0x00_8000_0000 (-0x80+0x00) */
+#define INIT_SETTING_SEG0_0 0x00007F80UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7F80 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Cached access at 0x10_0000_000 */
+#define INIT_SETTING_SEG0_1 0x00007000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7000 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_2 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_3 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_4 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_5 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:6] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_6 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG0_7 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG1_0 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG1_1 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached access at 0x00_c000_0000 */
+#define INIT_SETTING_SEG1_2 0x00007F40UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7F40 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached access at 0x14_0000_0000 */
+#define INIT_SETTING_SEG1_3 0x00006C00UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x6C00 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached WCB access at 0x00_d000_0000 */
+#define INIT_SETTING_SEG1_4 0x00007F30UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x7F30 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Non-Cached WCB 0x18_0000_0000 */
+#define INIT_SETTING_SEG1_5 0x00006800UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x6800 */
+ /* RESERVED [15:6] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*Trace - Trace not in use here so can be left as 0 */
+#define INIT_SETTING_SEG1_6 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+/*not used */
+#define INIT_SETTING_SEG1_7 0x00000000UL
+ /* ADDRESS_OFFSET [0:15] RW value= 0x0 */
+ /* RESERVED [15:16] RW value= 0x0 */
+ /* LOCKED [31:1] RW value= 0x0 */
+
+/***************************************************************************//**
+
+ */
+typedef enum MTC_PATTERN_
+{
+ MTC_COUNTING_PATTERN = 0x00, /*!< */
+ MTC_WALKING_ONE = 0x01, /*!< */
+ MTC_PSEUDO_RANDOM = 0x02, /*!< */
+ MTC_NO_REPEATING_PSEUDO_RANDOM = 0x03, /*!< */
+ MTC_ALT_ONES_ZEROS = 0x04, /*!< */
+ MTC_ALT_5_A = 0x05, /*!< */
+ MTC_USER = 0x06, /*!< */
+ MTC_PSEUDO_RANDOM_16BIT = 0x07, /*!< */
+ MTC_PSEUDO_RANDOM_8BIT = 0x08, /*!< */
+} MTC_PATTERN;
+
+
+
+typedef enum MTC_ADD_PATTERN_
+{
+ MTC_ADD_SEQUENTIAL = 0x00, /*!< */
+ MTC_ADD_RANDOM = 0x01, /*!< */
+} MTC_ADD_PATTERN;
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_SM_STATES_
+{
+
+ DDR_STATE_INIT = 0x00, /*!< 0 DDR_STATE_INIT*/
+ DDR_STATE_MONITOR = 0x01, /*!< 1 DDR_STATE_MONITOR */
+ DDR_STATE_TRAINING = 0x02, /*!< 2 DDR_STATE_TRAINING */
+ DDR_STATE_VERIFY = 0x03, /*!< 3 DDR_STATE_VERIFY */
+} DDR_SM_STATES;
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_SS_COMMAND_
+{
+
+ DDR_SS__INIT = 0x00, /*!< 0 DDR_SS__INIT */
+ DDR_SS_MONITOR = 0x01, /*!< 1 DDR_SS_MONITOR */
+} DDR_SS_COMMAND;
+
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_SS_STATUS_
+{
+
+ DDR_SETUP_DONE = 0x01, /*!< 0 DDR_SETUP_DONE */
+ DDR_SETUP_FAIL = 0x02, /*!< 1 DDR_SETUP_FAIL */
+ DDR_SETUP_SUCCESS = 0x04, /*!< 2 DDR_SETUP_SUCCESS */
+ DDR_SETUP_OFF_MODE = 0x08, /*!< 4 DDR_SETUP_OFF_MODE */
+} DDR_SS_STATUS;
+
+
+/***************************************************************************//**
+
+ */
+typedef enum DDR_TRAINING_SM_
+{
+
+ DDR_TRAINING_INIT, /*!< DDR_TRAINING_INIT */
+ DDR_TRAINING_FAIL,
+ DDR_CHECK_TRAINING_SWEEP,
+ DDR_TRAINING_SWEEP,
+ DDR_TRAINING_CHECK_FOR_OFFMODE, /*!< DDR_TRAINING_OFFMODE */
+ DDR_TRAINING_SET_MODE_VS_BITS,
+ DDR_TRAINING_FLASH_REGS,
+ DDR_TRAINING_CORRECT_RPC,
+ DDR_TRAINING_SOFT_RESET,
+ DDR_TRAINING_CALIBRATE_IO,
+ DDR_TRAINING_CONFIG_PLL,
+ DDR_TRAINING_SETUP_SEGS,
+ DDR_TRAINING_VERIFY_PLL_LOCK,
+ DDR_TRAINING_SETUP_DDRC,
+ DDR_TRAINING_RESET,
+ DDR_TRAINING_ROTATE_CLK,
+ DDR_TRAINING_SET_TRAINING_PARAMETERS,
+ DDR_TRAINING_IP_SM_BCLKSCLK_SW,
+ DDR_MANUAL_ADDCMD_TRAINING_SW,
+ DDR_TRAINING_IP_SM_START,
+ DDR_TRAINING_IP_SM_START_CHECK,
+ DDR_TRAINING_IP_SM_BCLKSCLK,
+ DDR_TRAINING_IP_SM_ADDCMD,
+ DDR_TRAINING_IP_SM_WRLVL,
+ DDR_TRAINING_IP_SM_RDGATE,
+ DDR_TRAINING_IP_SM_DQ_DQS,
+ DDR_TRAINING_IP_SM_VERIFY,
+ DDR_TRAINING_SET_FINAL_MODE,
+ DDR_TRAINING_WRITE_CALIBRATION,
+ DDR_TRAINING_WRITE_CALIBRATION_RETRY, /*!< Retry on calibration fail */
+ DDR_SWEEP_CHECK,
+ DDR_SANITY_CHECKS,
+ DDR_FULL_MTC_CHECK,
+ DDR_FULL_32BIT_NC_CHECK,
+ DDR_FULL_32BIT_CACHE_CHECK,
+ DDR_LOAD_PATTERN_TO_CACHE,
+ DDR_VERIFY_PATTERN_IN_CACHE,
+ DDR_FULL_32BIT_WRC_CHECK,
+ DDR_FULL_64BIT_NC_CHECK,
+ DDR_FULL_64BIT_CACHE_CHECK,
+ DDR_FULL_64BIT_WRC_CHECK,
+ DDR_TRAINING_VREFDQ_CALIB,
+ DDR_TRAINING_FPGA_VREFDQ_CALIB,
+ DDR_TRAINING_FINISH_CHECK,
+ DDR_TRAINING_FINISHED,
+ DDR_TRAINING_FAIL_SM2_VERIFY,
+ DDR_TRAINING_FAIL_SM_VERIFY,
+ DDR_TRAINING_FAIL_SM_DQ_DQS,
+ DDR_TRAINING_FAIL_SM_RDGATE,
+ DDR_TRAINING_FAIL_SM_WRLVL,
+ DDR_TRAINING_FAIL_SM_ADDCMD,
+ DDR_TRAINING_FAIL_SM_BCLKSCLK,
+ DDR_TRAINING_FAIL_BCLKSCLK_SW,
+ DDR_TRAINING_FAIL_FULL_32BIT_NC_CHECK,
+ DDR_TRAINING_FAIL_32BIT_CACHE_CHECK,
+ DDR_TRAINING_FAIL_MIN_LATENCY,
+ DDR_TRAINING_FAIL_START_CHECK,
+ DDR_TRAINING_FAIL_PLL_LOCK,
+ DDR_TRAINING_FAIL_DDR_SANITY_CHECKS,
+ DDR_SWEEP_AGAIN
+} DDR_TRAINING_SM;
+
+
+/***************************************************************************//**
+
+ */
+typedef enum {
+
+ USR_CMD_GET_DDR_STATUS = 0x00, //!< USR_CMD_GET_DDR_STATUS
+ USR_CMD_GET_MODE_SETTING = 0x01, //!< USR_CMD_GET_MODE_SETTING
+ USR_CMD_GET_W_CALIBRATION = 0x02, //!< USR_CMD_GET_W_CALIBRATION
+ USR_CMD_GET_GREEN_ZONE = 0x03, //!< USR_CMD_GET_GREEN_ZONE
+ USR_CMD_GET_REG = 0x04 //!< USR_CMD_GET_REG
+} DDR_USER_GET_COMMANDS_t;
+
+/***************************************************************************//**
+
+ */
+typedef enum {
+ USR_CMD_SET_GREEN_ZONE_DQ = 0x80, //!< USR_CMD_SET_GREEN_ZONE_DQ
+ USR_CMD_SET_GREEN_ZONE_DQS = 0x81, //!< USR_CMD_SET_GREEN_ZONE_DQS
+ USR_CMD_SET_GREEN_ZONE_VREF_MAX = 0x82, //!< USR_CMD_SET_GREEN_ZONE_VREF
+ USR_CMD_SET_GREEN_ZONE_VREF_MIN = 0x83, //!< USR_CMD_SET_GREEN_ZONE_VREF
+ USR_CMD_SET_RETRAIN = 0x84, //!< USR_CMD_SET_RETRAIN
+ USR_CMD_SET_REG = 0x85 //!< USR_CMD_SET_REG
+} DDR_USER_SET_COMMANDS_t;
+
+/***************************************************************************//**
+
+ */
+typedef enum SWEEP_STATES_{
+ INIT_SWEEP, //!< start the sweep
+ ADDR_CMD_OFFSET_SWEEP, //!< sweep address command
+ BCLK_SCLK_OFFSET_SWEEP, //!< sweep bclk sclk
+ DPC_VRGEN_V_SWEEP, //!< sweep vgen_v
+ DPC_VRGEN_H_SWEEP, //!< sweep vgen_h
+ DPC_VRGEN_VS_SWEEP, //!< VS sweep
+ FINISHED_SWEEP, //!< finished sweep
+} SWEEP_STATES;
+
+/***************************************************************************//**
+
+ */
+typedef enum {
+ USR_OPTION_tip_register_dump = 0x00 //!< USR_OPTION_tip_register_dump
+} USR_STATUS_OPTION_t;
+
+
+#define MAX_LANES 5
+
+/***************************************************************************//**
+
+ */
+typedef enum SEG_SETUP_{
+ DEFAULT_SEG_SETUP = 0x00,
+ LIBERO_SEG_SETUP
+} SEG_SETUP;
+
+
+
+/***************************************************************************//**
+
+ */
+typedef struct mss_ddr_fpga_vref_{
+ uint32_t status_lower;
+ uint32_t status_upper;
+ uint32_t lower;
+ uint32_t upper;
+ uint32_t vref_result;
+} mss_ddr_vref;
+
+/**
+ * \brief dll sgmii SCB regs
+ */
+typedef struct IOSCB_BANKCONT_DDR_ {
+ /* bit0 - This when asserted resets all the non-volatile register bits e.g. RW-P bits, the bit self clears i.e. is similar to a W1P bit */
+ /* bit1 - This when asserted resets all the register bits apart from the non-volatile registers, the bit self clears. i.e. is similar to a W1P bit */
+ __IO uint32_t soft_reset; /* bit8 - This asserts the functional reset of the block. It is asserted at power up. When written is stays asserted until written to 0. */
+
+ __IO uint32_t dpc_bits; /* bit 3:0: dpc_vs bank voltage select for pvt calibration */
+ /* : dpc_vrgen_h */
+ /* : dpc_vrgen_en_h */
+ /* : dpc_move_en_h */
+ /* : dpc_vrgen_v */
+ /* : dpc_vrgen_en_v */
+ /* : dpc_move_en_v */
+ __IO uint32_t bank_status; /* bit 0: Bank power on complete (active low for polling) */
+ /* bit 1: Bank calibration complete (active low for polling) */
+} IOSCB_BANKCONT_DDR_STRUCT;
+
+
+#define IOSCB_BANKCONT_DDR_BASE 0x3E020000UL
+#define IOSCB_BANKCONT_DDR ((volatile IOSCB_BANKCONT_DDR_STRUCT *) IOSCB_BANKCONT_DDR_BASE)
+
+/***************************************************************************//**
+
+ */
+typedef struct mss_ddr_write_calibration_{
+ uint32_t status_lower;
+ uint32_t lower[MAX_LANES];
+ uint32_t lane_calib_result;
+} mss_ddr_write_calibration;
+
+/***************************************************************************//**
+
+ */
+typedef struct mss_lpddr4_dq_calibration_{
+ uint32_t lower[MAX_LANES];
+ uint32_t upper[MAX_LANES];
+ uint32_t calibration_found[MAX_LANES];
+} mss_lpddr4_dq_calibration;
+
+
+/***************************************************************************//**
+ Calibration settings derived during write training
+ */
+typedef struct mss_ddr_calibration_{
+ /* CMSIS related defines identifying the UART hardware. */
+ mss_ddr_write_calibration write_cal;
+ mss_lpddr4_dq_calibration dq_cal;
+ mss_ddr_vref fpga_vref;
+ mss_ddr_vref mem_vref;
+} mss_ddr_calibration;
+
+/***************************************************************************//**
+ sweep index's
+ */
+typedef struct sweep_index_{
+ uint8_t cmd_index;
+ uint8_t bclk_sclk_index;
+ uint8_t dpc_vgen_index;
+ uint8_t dpc_vgen_h_index;
+ uint8_t dpc_vgen_vs_index;
+} sweep_index;
+
+/***************************************************************************//**
+
+ */
+uint8_t
+MSS_DDR_init_simulation
+(
+ void
+);
+
+/***************************************************************************//**
+
+ */
+uint8_t
+MSS_DDR_training
+(
+ uint8_t ddr_type
+);
+
+
+/***************************************************************************//**
+ The ddr_state_machine() function runs a state machine which initializes and
+ monitors the DDR
+
+ @return
+ This function returns status, see DDR_SS_STATUS enum
+
+ Example:
+ @code
+
+ uint32_t ddr_status;
+ ddr_status = ddr_state_machine(DDR_SS__INIT);
+
+ while((ddr_status & DDR_SETUP_DONE) != DDR_SETUP_DONE)
+ {
+ ddr_status = ddr_state_machine(DDR_SS_MONITOR);
+ }
+ if ((ddr_status & DDR_SETUP_FAIL) != DDR_SETUP_FAIL)
+ {
+ error |= (0x1U << 2U);
+ }
+
+ @endcode
+
+ */
+uint32_t
+ddr_state_machine
+(
+ DDR_SS_COMMAND command
+);
+
+/***************************************************************************//**
+ The debug_read_ddrcfg() prints out the ddrcfg register values
+
+ @return
+ This function returns status, see DDR_SS_STATUS enum
+
+ Example:
+ @code
+
+ debug_read_ddrcfg();
+
+ @endcode
+
+ */
+void
+debug_read_ddrcfg
+(
+ void
+);
+
+/***************************************************************************//**
+ The setup_ddr_segments() sets up seg regs
+
+ @return
+ none
+
+ Example:
+ @code
+
+ setup_ddr_segments(DEFAULT_SEG_SETUP);
+
+ @endcode
+
+ */
+void
+setup_ddr_segments
+(
+ SEG_SETUP option
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_DDRC_H_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c
new file mode 100644
index 00000000..0c8951a1
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c
@@ -0,0 +1,923 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_debug.h
+ * @author Microchip FPGA Embedded Systems Solutions
+ * @brief DDR write and read test functions
+ *
+ */
+
+#include
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+/*******************************************************************************
+ * Local Defines
+ */
+#define DDR_BASE 0x80000000u
+#define DDR_SIZE 0x40000000u
+
+#define PDMA_CHANNEL0_BASE_ADDRESS 0x3000000ULL
+#define PDMA_CHANNEL1_BASE_ADDRESS 0x3001000ULL
+#define PDMA_CHANNEL2_BASE_ADDRESS 0x3002000ULL
+#define PDMA_CHANNEL3_BASE_ADDRESS 0x3003000ULL
+
+const char *progress[3] = {"|\r", "/\r", "-\r"};
+typedef void(*pattern_fct_t)(void);
+static uint32_t g_test_buffer_cached[765];
+static uint32_t g_test_buffer_not_cached[765];
+
+/*******************************************************************************
+ * External Defines
+ */
+#ifdef DEBUG_DDR_INIT
+#ifdef SWEEP_ENABLED
+extern uint8_t sweep_results[MAX_NUMBER_DPC_VS_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_H_GEN_SWEEPS]\
+ [MAX_NUMBER_DPC_V_GEN_SWEEPS]\
+ [MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS]\
+ [MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS];
+#endif
+#endif
+extern const uint32_t ddr_test_pattern[768];
+
+/*******************************************************************************
+ * External function declarations
+ */
+extern void delay(uint32_t n);
+extern void pdma_transfer(uint64_t destination, uint64_t source, uint64_t size_in_bytes, uint64_t base_address);
+extern void pdma_transfer_complete( uint64_t base_address);
+
+/*******************************************************************************
+ * Local data declarations
+ */
+#ifdef DEBUG_DDR_INIT
+mss_uart_instance_t *g_debug_uart;
+#endif
+
+uint64_t ddr_test;
+
+/*******************************************************************************
+ * Local function declarations
+ */
+static uint32_t ddr_write ( volatile uint64_t *DDR_word_ptr,\
+ uint32_t no_of_access, uint8_t data_ptrn, DDR_ACCESS_SIZE data_size );
+static uint32_t ddr_read ( volatile uint64_t *DDR_word_ptr,\
+ uint32_t no_of_access, uint8_t data_ptrn, DDR_ACCESS_SIZE data_size );
+
+#ifdef DEBUG_DDR_INIT
+/***************************************************************************//**
+ * Setup serial port if DDR debug required during start-up
+ * @param uart Ref to uart you want to use
+ * @return
+ */
+
+__attribute__((weak))\
+ uint32_t setup_ddr_debug_port(mss_uart_instance_t * uart)
+{
+#ifdef DEBUG_DDR_INIT
+ /* Turn on UART0 clock */
+ SYSREG->SUBBLK_CLOCK_CR |= (SUBBLK_CLOCK_CR_MMUART0_MASK);
+ /* Remove soft reset */
+ SYSREG->SOFT_RESET_CR &= (uint32_t)(~SUBBLK_CLOCK_CR_MMUART0_MASK);
+ MSS_UART_init( uart,
+ MSS_UART_115200_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+ return(0U);
+#endif
+}
+
+
+/***************************************************************************//**
+ * Print in number hex format
+ * @param uart
+ * @param b
+ */
+
+static void dumpbyte(mss_uart_instance_t * uart, uint8_t b)
+{
+#ifdef DEBUG_DDR_INIT
+ const uint8_t hexchrs[] = { '0','1','2','3','4','5','6','7','8','9','A','B',\
+ 'C','D','E','F' };
+ MSS_UART_polled_tx(uart, &hexchrs[b >> 4u] , 1);
+ MSS_UART_polled_tx(uart, &hexchrs[b & 0x0fu] , 1);
+#endif
+}
+
+/***************************************************************************//**
+ *
+ * @param uart
+ * @param msg
+ * @param d
+ */
+__attribute__((weak))\
+ void uprint32(mss_uart_instance_t * uart, const char* msg, uint32_t d)
+{
+ MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
+ for (unsigned i=0; i < 4; i++)
+ {
+ dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
+ }
+}
+
+/***************************************************************************//**
+ *
+ * @param uart
+ * @param msg
+ * @param d
+ */
+__attribute__((weak))\
+ void uprint64(mss_uart_instance_t * uart, const char* msg, uint64_t d)
+{
+ MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
+ for (unsigned i=4; i < 8; i++)
+ {
+ dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
+ }
+ for (unsigned i=0; i < 4; i++)
+ {
+ dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
+ }
+}
+
+/***************************************************************************//**
+ *
+ * @param uart
+ * @param msg
+ */
+__attribute__((weak))\
+ void uprint(mss_uart_instance_t * uart, const char* msg)
+{
+ MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
+}
+
+/***************************************************************************//**
+ * dump a number of 32bit contiguous registers
+ * @param uart
+ * @param reg_pointer
+ * @param no_of_regs
+ */
+void print_reg_array(mss_uart_instance_t * uart, uint32_t *reg_pointer,\
+ uint32_t no_of_regs)
+{
+#ifdef DEBUG_DDR_INIT
+ while(no_of_regs > 0U)
+ {
+ uprint64(uart, "\n\rRegister, 0x", (uint64_t)reg_pointer);
+ uprint32(uart, " ,Value, 0x", *reg_pointer);
+ reg_pointer++;
+ no_of_regs--;
+ }
+#endif
+}
+
+#endif
+
+/***************************************************************************//**
+ * Write data to DDR
+ * @param DDR_word_ptr
+ * @param no_of_access
+ * @param data_ptrn
+ * @return
+ */
+static uint32_t ddr_write
+(
+ volatile uint64_t *DDR_word_ptr,
+ uint32_t no_of_access,
+ uint8_t data_ptrn,
+ DDR_ACCESS_SIZE data_size
+)
+{
+ uint32_t i;
+ uint64_t DATA;
+ uint32_t error_count = 0U;
+
+ uint32_t *DDR_32_ptr = (uint32_t *)DDR_word_ptr;
+ uint16_t *DDR_16_ptr = (uint16_t *)DDR_word_ptr;
+ uint8_t *DDR_8_ptr = (uint8_t *)DDR_word_ptr;
+
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = 0x00000000; break;
+ case PATTERN_WALKING_ONE : DATA = 0x00000001; break;
+ case PATTERN_WALKING_ZERO : DATA = 0x01;
+ DATA = ~ DATA; break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ DATA = 0x00000000;
+ break;
+ }
+
+ for( i = 0; i< (no_of_access); i++)
+ {
+ switch(data_size)
+ {
+ case DDR_8_BIT:
+ DATA &= 0xFFUL;
+ *DDR_8_ptr = (uint8_t)DATA;
+ DDR_8_ptr = DDR_8_ptr + 1;
+ break;
+ case DDR_16_BIT:
+ DATA &= 0xFFFFUL;
+ *DDR_16_ptr = (uint16_t)DATA;
+ DDR_16_ptr = DDR_16_ptr + 1;
+ break;
+ case DDR_32_BIT:
+ DATA &= 0xFFFFFFFFUL;
+ *DDR_32_ptr = (uint32_t)DATA;
+ DDR_32_ptr = DDR_32_ptr + 1;
+ break;
+ default:
+ case DDR_64_BIT:
+ *DDR_word_ptr = DATA;
+ DDR_word_ptr = DDR_word_ptr + 1;
+ break;
+ }
+
+#ifdef DEBUG_DDR_INIT
+ if((i%0x1000000UL) ==0UL)
+ {
+ MSS_UART_polled_tx(g_debug_uart, (const uint8_t*)"w", (uint32_t)1UL);
+ }
+#endif
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = DATA + 0x00000001; break;
+ case PATTERN_WALKING_ONE :
+ if (DATA == 0x80000000)
+ DATA = 0x00000001;
+ else
+ DATA = (DATA << 1);
+ break;
+ case PATTERN_WALKING_ZERO :
+ DATA = ~DATA;
+ if (DATA == 0x80000000)
+ DATA = 0x00000001;
+ else
+ {
+ DATA = (DATA << 1);
+ }
+ DATA = ~DATA;
+ break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ break;
+ }
+ }
+ return error_count;
+}
+
+/***************************************************************************//**
+ * Reads and compares with what was written
+ * @param DDR_word_ptr
+ * @param no_of_access
+ * @param data_ptrn
+ * @return 0 => read backs all expected value, otherwise error count
+ */
+uint32_t ddr_read
+(
+ volatile uint64_t *DDR_word_ptr,
+ uint32_t no_of_access,
+ uint8_t data_ptrn,
+ DDR_ACCESS_SIZE data_size
+)
+{
+ uint32_t i;
+ uint64_t DATA;
+ uint32_t err_cnt;
+ volatile uint64_t ddr_data;
+ volatile uint64_t *DDR_word_pt_t, *first_DDR_word_pt_t;
+ uint32_t rand_addr_offset;
+ uint8_t *DDR_8_pt_t;
+ uint16_t *DDR_16_pt_t;
+ uint32_t *DDR_32_pt_t;
+
+ err_cnt = 0U;
+ first_DDR_word_pt_t = DDR_word_ptr;
+ DDR_8_pt_t = (uint8_t *)DDR_word_ptr;
+ DDR_16_pt_t = (uint16_t *)DDR_word_ptr;
+ DDR_32_pt_t = (uint32_t *)DDR_word_ptr;
+
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = 0x00000000; break;
+ case PATTERN_WALKING_ONE : DATA = 0x00000001; break;
+ case PATTERN_WALKING_ZERO : DATA = 0x01;
+ DATA = ~ DATA; break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ *DDR_word_ptr = DATA;
+ *DDR_8_pt_t = (uint8_t)DATA;
+ *DDR_16_pt_t = (uint16_t)DATA;
+ *DDR_32_pt_t = (uint32_t)DATA;
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ DATA = 0x00000000;
+ break;
+ }
+ if (data_ptrn == '4')
+ {
+ delay(10);
+ }
+ for( i = 0; i< (no_of_access); i++)
+ {
+ switch(data_size)
+ {
+ case DDR_8_BIT:
+ DATA &= 0xFFUL;
+ ddr_data = *DDR_8_pt_t;
+ break;
+ case DDR_16_BIT:
+ DATA &= 0xFFFFUL;
+ ddr_data = *DDR_16_pt_t;
+ break;
+ case DDR_32_BIT:
+ DATA &= 0xFFFFFFFFUL;
+ ddr_data = *DDR_32_pt_t;
+ break;
+ default:
+ case DDR_64_BIT:
+ DDR_word_pt_t = DDR_word_ptr;
+ ddr_data = *DDR_word_pt_t;
+ break;
+ }
+
+#ifdef DEBUG_DDR_INIT
+ if((i%0x1000000UL) ==0UL)
+ {
+ MSS_UART_polled_tx(g_debug_uart, (const uint8_t*)"r", (uint32_t)1UL);
+ }
+#endif
+
+ if (ddr_data != DATA)
+ {
+#ifdef DEBUG_DDR_INIT
+#ifdef DEBUG_DDR_RD_RW_FAIL
+ if (err_cnt <=0xF)
+ {
+ uprint64(g_debug_uart,\
+ "\n\r READ/ WRITE ACCESS FAILED AT ADDR: 0x ",\
+ (uintptr_t)DDR_word_ptr);
+ uprint64(g_debug_uart,"\t Expected Data 0x ", DATA);
+ uprint64(g_debug_uart,"\t READ DATA: 0x ", ddr_data);
+ uprint64(g_debug_uart,"\t READ DATA: 0x ", *DDR_word_ptr);
+ uprint64(g_debug_uart,"\t READ DATA: 0x ", *DDR_word_ptr);
+ }
+#endif
+#endif
+ err_cnt++;
+ }
+ else
+ {
+#ifdef DEBUG_DDR_RD_RW_PASS
+ //printf("\n\r READ/ WRITE ACCESS passED AT ADDR: 0x%x expected data = 0x%x, Data read 0x%x",DDR_word_ptr, DATA, *DDR_word_ptr);
+ uprint64(g_debug_uart, "\n\r READ/ WRITE ACCESS PASSED AT ADDR: 0x"\
+ , (uintptr_t)DDR_word_ptr);
+ uprint64(g_debug_uart,"\t READ DATA: 0x", *DDR_word_ptr);
+#endif
+ }
+ DDR_word_ptr = DDR_word_ptr + 1U;
+ DDR_8_pt_t = DDR_8_pt_t +1U;
+ DDR_16_pt_t = DDR_16_pt_t +1U;
+ DDR_32_pt_t = DDR_32_pt_t +1U;
+ switch (data_ptrn)
+ {
+ case PATTERN_INCREMENTAL : DATA = DATA + 0x01; break;
+ case PATTERN_WALKING_ONE :
+ if (DATA == 0x80000000)
+ DATA = 0x00000001;
+ else
+ DATA = (DATA << 1);
+ break;
+ case PATTERN_WALKING_ZERO :
+ DATA = ~DATA;
+ if (DATA == 0x80000000)
+ {
+ DATA = 0x00000001;
+ }
+ else
+ {
+ DATA = (DATA << 1);
+ }
+ DATA = ~DATA;
+ break;
+ case PATTERN_RANDOM :
+ DATA = (uint64_t)rand ( );
+ rand_addr_offset = (uint32_t)(rand() & 0xFFFFCUL);
+ DDR_word_ptr = first_DDR_word_pt_t + rand_addr_offset;
+ DDR_8_pt_t = (uint8_t *)(first_DDR_word_pt_t + rand_addr_offset);
+ DDR_16_pt_t = (uint16_t *)(first_DDR_word_pt_t + rand_addr_offset);
+ DDR_32_pt_t = (uint32_t *)(first_DDR_word_pt_t + rand_addr_offset);
+ *DDR_word_ptr = DATA;
+ *DDR_8_pt_t = (uint8_t)DATA;
+ *DDR_16_pt_t = (uint16_t)DATA;
+ *DDR_32_pt_t = (uint32_t)DATA;
+ break;
+ case PATTERN_0xCCCCCCCC :
+ DATA = 0xCCCCCCCCCCCCCCCC;
+ break;
+ case PATTERN_0x55555555 :
+ DATA = 0x5555555555555555;
+ break;
+ case PATTERN_ZEROS :
+ DATA = 0x00000000;
+ break;
+ default :
+ break;
+ }
+ }
+ return (err_cnt);
+}
+
+/***************************************************************************//**
+ *
+ * @param DDR_word_ptr Address
+ * @param no_access Number of addresses
+ * @param pattern bit mask with patterns you want to test against
+ * @return
+ */
+uint32_t ddr_read_write_fn (uint64_t* DDR_word_ptr, uint32_t no_access,\
+ uint32_t pattern)
+{
+ uint32_t error_cnt = 0U;
+ uint8_t pattern_mask;
+ for (unsigned i=0; i < 1; i++)
+ {
+ for (uint32_t pattern_shift=0U; pattern_shift < MAX_NO_PATTERNS;\
+ pattern_shift++)
+ {
+ pattern_mask = (uint8_t)(0x01U << pattern_shift);
+ if(pattern & pattern_mask)
+ {
+#ifdef DEBUG_DDR_INIT
+ uprint32(g_debug_uart,"\n\r\t Pattern: 0x", pattern_shift);
+#endif
+
+#if TEST_64BIT_ACCESS == 1
+ /* write the pattern */
+ error_cnt += ddr_write ((uint64_t *)DDR_word_ptr,\
+ no_access, pattern_mask, DDR_64_BIT);
+ /* read back and verifies */
+ error_cnt += ddr_read ((uint64_t *)DDR_word_ptr, \
+ no_access, pattern_mask, DDR_64_BIT);
+#endif
+
+#if TEST_32BIT_ACCESS == 1
+ /* write the pattern */
+ error_cnt += ddr_write ((uint64_t *)DDR_word_ptr,\
+ no_access, pattern_mask, DDR_32_BIT);
+ /* read back and verifies */
+ error_cnt += ddr_read ((uint64_t *)DDR_word_ptr, \
+ no_access, pattern_mask, DDR_32_BIT);
+#endif
+ }
+ }
+ DDR_word_ptr++; /* increment the address */
+ }
+ return error_cnt;
+}
+
+
+/***************************************************************************//**
+ *
+ * @param error
+ * @return
+ */
+#ifdef DEBUG_DDR_INIT
+uint32_t error_status(mss_uart_instance_t *g_mss_uart_debug_pt, uint32_t error)
+{
+ uprint32(g_mss_uart_debug_pt, "\n\r ERROR_RESULT: ", error);
+ return (0U);
+}
+#endif
+
+/***************************************************************************//**
+ * Calibration status
+ * @return
+ */
+#ifdef DEBUG_DDR_INIT
+uint32_t wrcalib_status(mss_uart_instance_t *g_mss_uart_debug_pt)
+{
+ uprint32(g_mss_uart_debug_pt, "\n\r WRCALIB_RESULT: ",\
+ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib);
+ return (0U);
+}
+#endif
+
+#ifdef DEBUG_DDR_INIT
+/***************************************************************************//**
+ * Prints out DDR status
+ * @return
+ */
+uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt)
+{
+
+ uint32_t t_status = 0U;
+ uint32_t MSS_DDR_APB_ADDR;
+ uint32_t ddr_lane_sel;
+ uint32_t dq0_dly = 0U;
+ uint32_t dq1_dly = 0U;
+ uint32_t dq2_dly = 0U;
+ uint32_t dq3_dly = 0U;
+ uint32_t dq4_dly = 0U;
+ uint32_t dq5_dly = 0U;
+
+ /* MSS_UART_polled_tx_string(g_mss_uart_debug_pt, "\n\n\r TIP register status \n");
+ delay(1000);*/
+ uprint32(g_mss_uart_debug_pt, "\n\r\n\r training status = ",\
+ CFG_DDR_SGMII_PHY->training_status.training_status);
+ uprint32(g_mss_uart_debug_pt, "\n\r PCODE = ",\
+ (CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2 & 0x7F));
+ uprint32(g_mss_uart_debug_pt, "\n\r NCODE = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2) >> 7) & 0x7F));
+ uprint32(g_mss_uart_debug_pt, "\n\r WRCALIB_RESULT: "\
+ , CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib);
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_ref_slewr = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 0) & 0x3F));
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_ref_slewf = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 6) & 0xFFF));
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_slewr = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 18) & 0x3F));
+ uprint32(g_mss_uart_debug_pt, "\n\r sro_slewf = ",\
+ (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 24) & 0x3F));
+
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt, \
+ (const uint8_t*)"\n\n\r lane_select \t gt_err_comb \t gt_txdly \t gt_steps_180 \t gt_state \t wl_delay_0 \t dqdqs_err_done \t dqdqs_state \t delta0 \t delta1");
+
+ for (ddr_lane_sel=0U; ddr_lane_sel < LIBERO_SETTING_DATA_LANES_USED; ddr_lane_sel++)
+ {
+ CFG_DDR_SGMII_PHY->lane_select.lane_select = ddr_lane_sel;
+ uprint32(g_mss_uart_debug_pt, "\n\r ",\
+ CFG_DDR_SGMII_PHY->lane_select.lane_select);
+ delay(1000);
+ MSS_DDR_APB_ADDR = CFG_DDR_SGMII_PHY->gt_err_comb.gt_err_comb;
+ uprint32(g_mss_uart_debug_pt, "\t ", MSS_DDR_APB_ADDR);
+ t_status = t_status | MSS_DDR_APB_ADDR;
+
+ MSS_DDR_APB_ADDR = CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly;
+ uprint32(g_mss_uart_debug_pt, "\t ", MSS_DDR_APB_ADDR);
+
+ if((MSS_DDR_APB_ADDR & 0xFF) == 0) t_status = 1;
+ if((MSS_DDR_APB_ADDR & 0xFF00) == 0) t_status = 1;
+ if((MSS_DDR_APB_ADDR & 0xFF0000) == 0) t_status = 1;
+ if((MSS_DDR_APB_ADDR & 0xFF000000) == 0) t_status = 1;
+
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->gt_steps_180.gt_steps_180);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->gt_state.gt_state);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->wl_delay_0.wl_delay_0);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->dq_dqs_err_done.dq_dqs_err_done);
+ t_status = t_status | (MSS_DDR_APB_ADDR != 8);
+
+ uprint32(g_mss_uart_debug_pt, "\t\t ",\
+ CFG_DDR_SGMII_PHY->dqdqs_state.dqdqs_state);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->delta0.delta0);
+ dq0_dly = (MSS_DDR_APB_ADDR & 0xFF);
+ dq1_dly = (MSS_DDR_APB_ADDR & 0xFF00) >> 8;
+ dq2_dly = (MSS_DDR_APB_ADDR & 0xFF0000) >> 16;
+ dq3_dly = (MSS_DDR_APB_ADDR & 0xFF000000) >> 24;
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->delta1.delta1);
+ dq4_dly = (MSS_DDR_APB_ADDR & 0xFF);
+ dq5_dly = (MSS_DDR_APB_ADDR & 0xFF00) >> 8;
+ dq2_dly = (MSS_DDR_APB_ADDR & 0xFF0000) >> 16;
+ dq3_dly = (MSS_DDR_APB_ADDR & 0xFF000000) >> 24;
+ }
+
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt, (const uint8_t*)"\n\r\n\r lane_select\t rdqdqs_status2\t addcmd_status0\t addcmd_status1\t addcmd_answer1\t dqdqs_status1\n\r");
+ for (ddr_lane_sel=0U; ddr_lane_sel < LIBERO_SETTING_DATA_LANES_USED;\
+ ddr_lane_sel++)
+ {
+ CFG_DDR_SGMII_PHY->lane_select.lane_select = ddr_lane_sel;
+ uprint32(g_mss_uart_debug_pt, "\n\r ",\
+ CFG_DDR_SGMII_PHY->lane_select.lane_select);
+ delay(1000);
+
+ if(dq0_dly > 20) t_status = 1;
+ if(dq1_dly > 20) t_status = 1;
+ if(dq2_dly > 20) t_status = 1;
+ if(dq3_dly > 20) t_status = 1;
+ if(dq4_dly > 20) t_status = 1;
+ if(dq5_dly > 20) t_status = 1;
+
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->dqdqs_status2.dqdqs_status2);
+
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->addcmd_answer.addcmd_answer);
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ CFG_DDR_SGMII_PHY->dqdqs_status1.dqdqs_status1);
+
+ }
+ return(t_status);
+}
+#endif
+
+/***************************************************************************//**
+ * display sweep results
+ *
+ * @param g_mss_uart_debug_pt
+ */
+#ifdef DEBUG_DDR_INIT
+#ifdef SWEEP_ENABLED
+void sweep_status (mss_uart_instance_t *g_mss_uart_debug_pt)
+{
+
+ uint32_t t_status;
+ uint8_t cmd_index;
+ uint8_t bclk_sclk_index;
+ uint8_t dpc_vgen_index;
+ uint8_t dpc_vgen_h_index;
+ uint8_t dpc_vgen_vs_index;
+
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
+ "\n\n\r dpc_vgen_vs dpc_vgen_h \t dpc_vgen_v \t bclk_sclk");
+ for (cmd_index=0U; cmd_index < MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS; \
+ cmd_index++)
+ {
+ uprint32(g_mss_uart_debug_pt, "\t ",\
+ cmd_index + LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET);
+ }
+ MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
+ "\n\r--------------------------------------------------------------------");
+
+ for (dpc_vgen_vs_index=0U; dpc_vgen_vs_index 1000)
+ {
+ alive = 0;
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)".");
+#endif
+ }
+ }
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r\nFinished loading test pattern\r\n");
+#endif
+
+ pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL2_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL3_BASE_ADDRESS);
+
+}
+
+/**
+ * Run from address
+ * @param start_addr address to run from.
+ */
+void execute_ddr_pattern(uint64_t start_addr)
+{
+ pattern_fct_t p_pattern_fct = (pattern_fct_t)start_addr;
+
+ (*p_pattern_fct)();
+}
+
+/**
+ * Loads DDR with a pattern that triggers read issues if not enough margin.
+ * Used to verify training is successful.
+ * @param p_cached_ddr
+ * @param p_not_cached_ddr
+ * @param length
+ */
+void load_test_buffers(uint32_t * p_cached_ddr, uint32_t * p_not_cached_ddr, uint64_t length)
+{
+ (void)length;
+
+ pdma_transfer((uint64_t)g_test_buffer_cached, (uint64_t)p_cached_ddr, length, PDMA_CHANNEL0_BASE_ADDRESS);
+ pdma_transfer((uint64_t)g_test_buffer_not_cached, (uint64_t)p_not_cached_ddr, length, PDMA_CHANNEL1_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS);
+ pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS);
+}
+
+/**
+ * test_ddr reads from cached and non cached DDR and compares
+ * @param no_of_iterations
+ * @param size
+ * @return returns 1 if compare fails
+ */
+uint32_t test_ddr(uint32_t no_of_iterations, uint32_t size)
+{
+ uint32_t pattern_length = sizeof(ddr_test_pattern) - (3 * sizeof(uint32_t));
+ uint32_t * p_ddr_cached = (uint32_t *)0x80000000;
+ uint32_t * p_ddr_noncached = (uint32_t *)0x1400000000;
+ uint32_t word_offset;
+ uint32_t alive = 0;
+ uint32_t alive_idx = 0U;
+ uint32_t iteration = 0U;
+ uint32_t error = 0U;
+
+
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r\nStarting ddr test\r\n");
+#endif
+ while(iteration < no_of_iterations)
+ {
+ int different = 0;
+
+ load_test_buffers(p_ddr_cached, p_ddr_noncached, pattern_length);
+
+ different = memcmp(g_test_buffer_cached, g_test_buffer_not_cached, pattern_length);
+
+ if(different != 0)
+ {
+ for(word_offset = 0; word_offset < (pattern_length / sizeof(uint32_t)); word_offset++)
+ {
+ if(g_test_buffer_cached[word_offset] != g_test_buffer_not_cached[word_offset])
+ {
+#ifdef DEBUG_DDR_INIT
+ uprint64(g_debug_uart, " Mismatch, 0x", (uint64_t)p_ddr_cached);
+ uprint32(g_debug_uart, " offset:, 0x", (uint64_t)word_offset);
+ uprint32(g_debug_uart, " address: 0x", (uint64_t)(p_ddr_cached + word_offset));
+ uprint32(g_debug_uart, " expected (non-cached): 0x", g_test_buffer_not_cached[word_offset]);
+ uprint32(g_debug_uart, " found (cached): 0x", (uint64_t)g_test_buffer_cached[word_offset]);
+ uprint32(g_debug_uart, " direct cached read: 0x", (uint32_t)*(p_ddr_cached + word_offset));
+ uprint32(g_debug_uart, " direct non-cached read: 0x", (uint32_t)*(p_ddr_noncached + word_offset));
+#endif
+ break;
+ }
+ }
+ error = 1U;
+ return error;
+ }
+
+ if (((uint64_t)p_ddr_cached + ( 2 * pattern_length)) < (LIBERO_SETTING_DDR_32_CACHE + size))
+ {
+ p_ddr_cached += (pattern_length / sizeof(uint32_t));
+ p_ddr_noncached += (pattern_length / sizeof(uint32_t));
+ }
+ else
+ {
+ p_ddr_cached = (uint32_t *)0x80000000;
+ p_ddr_noncached = (uint32_t *)0x1400000000;
+ iteration++;
+#ifdef DEBUG_DDR_INIT
+ uprint32(g_debug_uart, " Iteration ", (uint64_t)(unsigned int)iteration);
+#endif
+ }
+
+ alive++;
+ if(alive > 10000U)
+ {
+ alive = 0;
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r");
+ uprint(g_debug_uart, (const char*)progress[alive_idx]);
+#endif
+ alive_idx++;
+ if(alive_idx >= 3U)
+ {
+ alive_idx = 0;
+ }
+ if(ddr_test == 2U)
+ {
+#ifdef DEBUG_DDR_INIT
+ uprint(g_debug_uart, (const char*)"\r\nEnding ddr test. Press 0 to display the menu\r\n");
+#endif
+ return error;
+ }
+ }
+ }
+ return error;
+}
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h
new file mode 100644
index 00000000..20c3c111
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_debug.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief mss_ddr_debug related defines
+ *
+ */
+
+/*=========================================================================*//**
+ @page DDR setup and monitoring
+ ==============================================================================
+ @section intro_sec Introduction
+ ==============================================================================
+ DDR debug helper functions
+
+ ==============================================================================
+ @section Items located in the north west corner
+ ==============================================================================
+ -
+
+ ==============================================================================
+ @section Overview of DDR related hardware
+ ==============================================================================
+
+ *//*=========================================================================*/
+
+#include
+#include
+
+
+#ifndef __MSS_DDr_DEBUG_H_
+#define __MSS_DDr_DEBUG_H_ 1
+
+#ifdef DEBUG_DDR_INIT
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TEST_64BIT_ACCESS
+#define TEST_64BIT_ACCESS 1
+#endif
+
+#ifndef TEST_32BIT_ACCESS
+#define TEST_32BIT_ACCESS 1
+#endif
+
+typedef enum DDR_ACCESS_SIZE_
+{
+ DDR_8_BIT,
+ DDR_16_BIT,
+ DDR_32_BIT,
+ DDR_64_BIT
+} DDR_ACCESS_SIZE;
+
+
+/***************************************************************************//**
+ The ddr_read_write_fn function is used to write/read test patterns to the DDR
+
+ @return
+ This function returns 0 if successful, number of errors if not.
+
+ Example:
+ @code
+
+ if (ddr_read_write_fn() != 0U)
+ {
+ .. warn the user, increment error count , wait for watchdog reset
+ }
+
+ @endcode
+ */
+uint32_t
+ddr_read_write_fn
+(
+uint64_t* DDR_word_ptr,
+uint32_t no_access,
+uint32_t pattern
+);
+
+#ifdef DEBUG_DDR_INIT
+/***************************************************************************//**
+ The uprint32() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)uprint32(g_debug_uart, "\n\r DDR_TRAINING_FAIL: ", error);
+
+ @endcode
+ */
+void
+uprint32
+(
+mss_uart_instance_t * uart,
+const char* msg,
+uint32_t d
+);
+
+/***************************************************************************//**
+ The uprint64() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)uprint64(g_debug_uart, "\n\r DDR_TRAINING_FAIL: ", error);
+
+ @endcode
+ */
+void
+uprint64
+(
+mss_uart_instance_t * uart,
+const char* msg,
+uint64_t d
+);
+
+/***************************************************************************//**
+ The error_status() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)error_status(g_debug_uart, "\n\r DDR_TRAINING_FAIL: ", error);
+
+ @endcode
+ */
+uint32_t error_status(mss_uart_instance_t *g_mss_uart_debug_pt, uint32_t error);
+
+/***************************************************************************//**
+ The wrcalib_status() function is used to print to the designated debug port
+
+ Example:
+ @code
+
+ (void)wrcalib_status(mss_uart_instance_t *g_mss_uart_debug_pt);
+
+ @endcode
+ */
+uint32_t wrcalib_status(mss_uart_instance_t *g_mss_uart_debug_pt);
+
+/***************************************************************************//**
+ The tip_register_status() function is used to print ddr TIP status to the
+ designated debug port
+
+ Example:
+ @code
+
+ (void)tip_register_status(mss_uart_instance_t *g_mss_uart_debug_pt);
+
+ @endcode
+ */
+uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt);
+
+/***************************************************************************//**
+ The setup_ddr_debug_port() function is used to setup a serial port dedicated
+ to printing information on the DDR start-up.
+
+ @return
+ This function returns 0 if successful
+
+ Example:
+ @code
+
+ if (ddr_setup() != 0U)
+ {
+ .. warn the user, increment error count , wait for watchdog reset
+ }
+
+ @endcode
+ */
+uint32_t
+setup_ddr_debug_port
+(
+mss_uart_instance_t * uart
+);
+
+/***************************************************************************//**
+ *
+ */
+void
+sweep_status
+(
+mss_uart_instance_t *g_mss_uart_debug_pt
+);
+
+/***************************************************************************//**
+ *
+ */
+void
+print_reg_array
+(
+mss_uart_instance_t * uart,
+uint32_t *reg_pointer,
+uint32_t no_of_regs
+);
+#endif
+
+/***************************************************************************//**
+ *
+ */
+void
+load_ddr_pattern
+(
+uint64_t base,
+uint32_t size,
+uint8_t pattern_offset
+);
+
+/***************************************************************************//**
+ *
+ */
+uint32_t
+test_ddr
+(
+uint32_t no_of_iterations,
+uint32_t size
+);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_DDRC_H_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h
new file mode 100644
index 00000000..355eb551
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_defs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief mss_ddr_debug related defines
+ *
+ */
+
+#ifndef SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_
+#define SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_
+
+#define PATTERN_INCREMENTAL (0x01U << 0U)
+#define PATTERN_WALKING_ONE (0x01U << 1U)
+#define PATTERN_WALKING_ZERO (0x01U << 2U)
+#define PATTERN_RANDOM (0x01U << 3U)
+#define PATTERN_0xCCCCCCCC (0x01U << 4U)
+#define PATTERN_0x55555555 (0x01U << 5U)
+#define PATTERN_ZEROS (0x01U << 6U)
+#define MAX_NO_PATTERNS 7U
+
+/* Training types status offsets */
+#define BCLK_SCLK_BIT (0x1U<<0U)
+#define ADDCMD_BIT (0x1U<<1U)
+#define WRLVL_BIT (0x1U<<2U)
+#define RDGATE_BIT (0x1U<<3U)
+#define DQ_DQS_BIT (0x1U<<4U)
+
+/* The first five bits represent the currently supported training in the TIP */
+/* This value will not change unless more training possibilities are added to
+ * the TIP */
+#define TRAINING_MASK (BCLK_SCLK_BIT|\
+ ADDCMD_BIT|\
+ WRLVL_BIT|\
+ RDGATE_BIT|\
+ DQ_DQS_BIT)
+
+#endif /* SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_phy_defs.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_phy_defs.h
new file mode 100644
index 00000000..74a12396
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_phy_defs.h
@@ -0,0 +1,4692 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_ddr_sgmii_phy_defs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Register bit offsets and masks definitions for MPFS MSS DDR
+ * This was generated directly from the RTL
+ *
+ */
+
+#ifndef MSS_DDR_SGMII_PHY_DEFS_H_
+#define MSS_DDR_SGMII_PHY_DEFS_H_
+
+
+#include "mpfs_hal/mss_hal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __I
+#define __I const volatile
+#endif
+#ifndef __IO
+#define __IO volatile
+#endif
+#ifndef __O
+#define __O volatile
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------- DDR -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+
+/*============================== CFG_DDR_SGMII_PHY definitions ===========================*/
+
+typedef enum { /*!< SOFT_RESET_DDR_PHY.PERIPH_DDR_PHY bitfield definition*/
+ scb_periph_not_in_soft_reset_ddr_phy = 0,
+ scb_periph_reset_ddr_phy = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_PERIPH_DDR_PHY_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DDR_PHY.V_MAP_DDR_PHY bitfield definition*/
+ scb_v_regs_not_in_soft_reset_ddr_phy = 0,
+ scb_v_regs_reset_ddr_phy = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_V_MAP_DDR_PHY_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DDR_PHY.NV_MAP_DDR_PHY bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_ddr_phy = 0,
+ scb_nv_regs_reset_ddr_phy = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_NV_MAP_DDR_PHY_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.BLOCKID_MAIN_PLL bitfield definition*/
+ block_address_main_pll = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_BLOCKID_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.PERIPH_MAIN_PLL bitfield definition*/
+ scb_periph_not_in_soft_reset_main_pll = 0,
+ scb_periph_reset_main_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_PERIPH_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.V_MAP_MAIN_PLL bitfield definition*/
+ scb_v_regs_not_in_soft_reset_main_pll = 0,
+ scb_v_regs_reset_main_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_V_MAP_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_MAIN_PLL.NV_MAP_MAIN_PLL bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_main_pll = 0,
+ scb_nv_regs_reset_main_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_NV_MAP_MAIN_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.BLOCKID_IOSCB_PLL bitfield definition*/
+ block_address_ioscb_pll = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_BLOCKID_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.PERIPH_IOSCB_PLL bitfield definition*/
+ scb_periph_not_in_soft_reset_ioscb_pll = 0,
+ scb_periph_reset_ioscb_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_PERIPH_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.V_MAP_IOSCB_PLL bitfield definition*/
+ scb_v_regs_not_in_soft_reset_ioscb_pll = 0,
+ scb_v_regs_reset_ioscb_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_V_MAP_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOSCB_PLL.NV_MAP_IOSCB_PLL bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_ioscb_pll = 0,
+ scb_nv_regs_reset_ioscb_pll = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_NV_MAP_IOSCB_PLL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.BLOCKID_BANK_CTRL bitfield definition*/
+ block_address_bank_ctrl = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_BLOCKID_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.PERIPH_BANK_CTRL bitfield definition*/
+ scb_periph_not_in_soft_reset_bank_ctrl = 0,
+ scb_periph_reset_bank_ctrl = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_PERIPH_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.V_MAP_BANK_CTRL bitfield definition*/
+ scb_v_regs_not_in_soft_reset_bank_ctrl = 0,
+ scb_v_regs_reset_bank_ctrl = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_V_MAP_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_BANK_CTRL.NV_MAP_BANK_CTRL bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_bank_ctrl = 0,
+ scb_nv_regs_reset_bank_ctrl = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_NV_MAP_BANK_CTRL_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.BLOCKID_IOCALIB bitfield definition*/
+ block_address_iocalib = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_BLOCKID_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.PERIPH_IOCALIB bitfield definition*/
+ scb_periph_not_in_soft_reset_iocalib = 0,
+ scb_periph_reset_iocalib = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_PERIPH_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.V_MAP_IOCALIB bitfield definition*/
+ scb_v_regs_not_in_soft_reset_iocalib = 0,
+ scb_v_regs_reset_iocalib = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_V_MAP_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_IOCALIB.NV_MAP_IOCALIB bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_iocalib = 0,
+ scb_nv_regs_reset_iocalib = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_NV_MAP_IOCALIB_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.BLOCKID_CFM bitfield definition*/
+ block_address_cfm = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_BLOCKID_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.PERIPH_CFM bitfield definition*/
+ scb_periph_not_in_soft_reset_cfm = 0,
+ scb_periph_reset_cfm = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_PERIPH_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.V_MAP_CFM bitfield definition*/
+ scb_v_regs_not_in_soft_reset_cfm = 0,
+ scb_v_regs_reset_cfm = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_V_MAP_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_CFM.NV_MAP_CFM bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_cfm = 0,
+ scb_nv_regs_reset_cfm = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_NV_MAP_CFM_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.BLOCKID_DECODER_DRIVER bitfield definition*/
+ block_address_decoder_driver = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_BLOCKID_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.PERIPH_DECODER_DRIVER bitfield definition*/
+ scb_periph_not_in_soft_reset_decoder_driver = 0,
+ scb_periph_reset_decoder_driver = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_PERIPH_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.V_MAP_DECODER_DRIVER bitfield definition*/
+ scb_v_regs_not_in_soft_reset_decoder_driver = 0,
+ scb_v_regs_reset_decoder_driver = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_V_MAP_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_DRIVER.NV_MAP_DECODER_DRIVER bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_decoder_driver = 0,
+ scb_nv_regs_reset_decoder_driver = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_NV_MAP_DECODER_DRIVER_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.BLOCKID_DECODER_ODT bitfield definition*/
+ block_address_decoder_odt = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_BLOCKID_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.PERIPH_DECODER_ODT bitfield definition*/
+ scb_periph_not_in_soft_reset_decoder_odt = 0,
+ scb_periph_reset_decoder_odt = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_PERIPH_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.V_MAP_DECODER_ODT bitfield definition*/
+ scb_v_regs_not_in_soft_reset_decoder_odt = 0,
+ scb_v_regs_reset_decoder_odt = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_V_MAP_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_ODT.NV_MAP_DECODER_ODT bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_decoder_odt = 0,
+ scb_nv_regs_reset_decoder_odt = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_NV_MAP_DECODER_ODT_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.BLOCKID_DECODER_IO bitfield definition*/
+ block_address_decoder_io = 0
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_BLOCKID_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.PERIPH_DECODER_IO bitfield definition*/
+ scb_periph_not_in_soft_reset_decoder_io = 0,
+ scb_periph_reset_decoder_io = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_PERIPH_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.V_MAP_DECODER_IO bitfield definition*/
+ scb_v_regs_not_in_soft_reset_decoder_io = 0,
+ scb_v_regs_reset_decoder_io = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_V_MAP_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_DECODER_IO.NV_MAP_DECODER_IO bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_decoder_io = 0,
+ scb_nv_regs_reset_decoder_io = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_NV_MAP_DECODER_IO_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_TIP.PERIPH_TIP bitfield definition*/
+ scb_periph_not_in_soft_reset_ddr_tip = 0,
+ scb_periph_reset_ddr_tip = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_PERIPH_TIP_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_TIP.V_MAP_TIP bitfield definition*/
+ scb_v_regs_not_in_soft_reset_ddr_tip = 0,
+ scb_v_regs_reset_ddr_tip = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_V_MAP_TIP_TypeDef;
+
+typedef enum { /*!< SOFT_RESET_TIP.NV_MAP_TIP bitfield definition*/
+ scb_nv_regs_not_in_soft_reset_ddr_tip = 0,
+ scb_nv_regs_reset_ddr_tip = 1
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_NV_MAP_TIP_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DDR_PHY register definition*/
+ __IO uint32_t SOFT_RESET_DDR_PHY;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_NV_MAP_DDR_PHY_TypeDef NV_MAP_DDR_PHY :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_V_MAP_DDR_PHY_TypeDef V_MAP_DDR_PHY :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_PERIPH_DDR_PHY_TypeDef PERIPH_DDR_PHY :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t BLOCKID_DDR_PHY :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_TypeDef;
+
+typedef union{ /*!< DDRPHY_MODE register definition*/
+ __IO uint32_t DDRPHY_MODE;
+ struct
+ {
+ __IO uint32_t DDRMODE :3;
+ __IO uint32_t ECC :1;
+ __IO uint32_t CRC :1;
+ __IO uint32_t Bus_width :3;
+ __IO uint32_t DMI_DBI :1;
+ __IO uint32_t DQ_drive :2;
+ __IO uint32_t DQS_drive :2;
+ __IO uint32_t ADD_CMD_drive :2;
+ __IO uint32_t Clock_out_drive :2;
+ __IO uint32_t DQ_termination :2;
+ __IO uint32_t DQS_termination :2;
+ __IO uint32_t ADD_CMD_input_pin_termination :2;
+ __IO uint32_t preset_odt_clk :2;
+ __IO uint32_t Power_down :1;
+ __IO uint32_t rank :1;
+ __IO uint32_t Command_Address_Pipe :2;
+ __I uint32_t Reserved :3;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DDRPHY_MODE_TypeDef;
+
+typedef union{ /*!< DDRPHY_STARTUP register definition*/
+ __IO uint32_t DDRPHY_STARTUP;
+ struct
+ {
+ __IO uint32_t ADD_CMD_Lockdn :1;
+ __IO uint32_t DATA_Lockdn :1;
+ __IO uint32_t PERSIST_ADD_CMD :1;
+ __IO uint32_t Persist_CLKOUT :1;
+ __IO uint32_t Persist_DATA :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t DYNEN_SCB_PLL0 :1;
+ __IO uint32_t DYNEN_SCB_PLL1 :1;
+ __IO uint32_t DYNEN_SCB_CFM :1;
+ __IO uint32_t DYNEN_SCB_IO_CALIB :1;
+ __IO uint32_t DYNEN_SCB_BANKCNTL :1;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t DYNEN_APB_PLL0 :1;
+ __IO uint32_t DYNEN_APB_PLL1 :1;
+ __IO uint32_t DYNEN_APB_CFM :1;
+ __IO uint32_t DYNEN_APB_IO_CALIB :1;
+ __IO uint32_t DYNEN_APB_BANKCNTL :1;
+ __IO uint32_t DYNEN_APB_DECODER_PRESETS :1;
+ __IO uint32_t reserved3 :10;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DDRPHY_STARTUP_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_MAIN_PLL register definition*/
+ __IO uint32_t SOFT_RESET_MAIN_PLL;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_NV_MAP_MAIN_PLL_TypeDef NV_MAP_MAIN_PLL :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_V_MAP_MAIN_PLL_TypeDef V_MAP_MAIN_PLL :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_PERIPH_MAIN_PLL_TypeDef PERIPH_MAIN_PLL :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_BLOCKID_MAIN_PLL_TypeDef BLOCKID_MAIN_PLL :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_TypeDef;
+
+typedef union{ /*!< PLL_CTRL_MAIN register definition*/
+ __IO uint32_t PLL_CTRL_MAIN;
+ struct
+ {
+ __IO uint32_t REG_POWERDOWN_B :1;
+ __IO uint32_t REG_RFDIV_EN :1;
+ __IO uint32_t REG_DIVQ0_EN :1;
+ __IO uint32_t REG_DIVQ1_EN :1;
+ __IO uint32_t REG_DIVQ2_EN :1;
+ __IO uint32_t REG_DIVQ3_EN :1;
+ __IO uint32_t REG_RFCLK_SEL :1;
+ __I uint32_t RESETONLOCK :1;
+ __I uint32_t BYPCK_SEL :4;
+ __I uint32_t REG_BYPASS_GO_B :1;
+ __I uint32_t reserve10 :3;
+ __I uint32_t REG_BYPASSPRE :4;
+ __I uint32_t REG_BYPASSPOST :4;
+ __IO uint32_t LP_REQUIRES_LOCK :1;
+ __I uint32_t LOCK :1;
+ __I uint32_t LOCK_INT_EN :1;
+ __I uint32_t UNLOCK_INT_EN :1;
+ __I uint32_t LOCK_INT :1;
+ __I uint32_t UNLOCK_INT :1;
+ __I uint32_t reserve11 :1;
+ __I uint32_t LOCK_B :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_REF_FB_MAIN register definition*/
+ __IO uint32_t PLL_REF_FB_MAIN;
+ struct
+ {
+ __I uint32_t FSE_B :1;
+ __I uint32_t FBCK_SEL :2;
+ __I uint32_t FOUTFB_SELMUX_EN :1;
+ __I uint32_t reserve12 :4;
+ __IO uint32_t RFDIV :6;
+ __I uint32_t reserve13 :2;
+ __I uint32_t reserve14 :12;
+ __I uint32_t reserve15 :4;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_REF_FB_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_FRACN_MAIN register definition*/
+ __IO uint32_t PLL_FRACN_MAIN;
+ struct
+ {
+ __I uint32_t FRACN_EN :1;
+ __I uint32_t FRACN_DAC_EN :1;
+ __I uint32_t reserve16 :6;
+ __I uint32_t reserve17 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_FRACN_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_DIV_0_1_MAIN register definition*/
+ __IO uint32_t PLL_DIV_0_1_MAIN;
+ struct
+ {
+ __I uint32_t VCO0PH_SEL :3;
+ __I uint32_t DIV0_START :3;
+ __I uint32_t reserve18 :2;
+ __IO uint32_t POST0DIV :7;
+ __I uint32_t reserve19 :1;
+ __I uint32_t VCO1PH_SEL :3;
+ __I uint32_t DIV1_START :3;
+ __I uint32_t reserve20 :2;
+ __IO uint32_t POST1DIV :7;
+ __I uint32_t reserve21 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_0_1_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_DIV_2_3_MAIN register definition*/
+ __IO uint32_t PLL_DIV_2_3_MAIN;
+ struct
+ {
+ __I uint32_t VCO2PH_SEL :3;
+ __I uint32_t DIV2_START :3;
+ __I uint32_t reserve22 :2;
+ __IO uint32_t POST2DIV :7;
+ __I uint32_t reserve23 :1;
+ __I uint32_t VCO3PH_SEL :3;
+ __I uint32_t DIV3_START :3;
+ __I uint32_t reserve24 :2;
+ __IO uint32_t POST3DIV :7;
+ __I uint32_t CKPOST3_SEL :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_2_3_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_CTRL2_MAIN register definition*/
+ __IO uint32_t PLL_CTRL2_MAIN;
+ struct
+ {
+ __IO uint32_t BWI :2;
+ __IO uint32_t BWP :2;
+ __I uint32_t IREF_EN :1;
+ __I uint32_t IREF_TOGGLE :1;
+ __I uint32_t reserve25 :3;
+ __I uint32_t LOCKCNT :4;
+ __I uint32_t reserve26 :4;
+ __I uint32_t ATEST_EN :1;
+ __I uint32_t ATEST_SEL :3;
+ __I uint32_t reserve27 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL2_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_CAL_MAIN register definition*/
+ __I uint32_t PLL_CAL_MAIN;
+ struct
+ {
+ __I uint32_t DSKEWCALCNT :3;
+ __I uint32_t DSKEWCAL_EN :1;
+ __I uint32_t DSKEWCALBYP :1;
+ __I uint32_t reserve28 :3;
+ __I uint32_t DSKEWCALIN :7;
+ __I uint32_t reserve29 :1;
+ __I uint32_t DSKEWCALOUT :7;
+ __I uint32_t reserve30 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CAL_MAIN_TypeDef;
+
+typedef union{ /*!< PLL_PHADJ_MAIN register definition*/
+ __IO uint32_t PLL_PHADJ_MAIN;
+ struct
+ {
+ __I uint32_t PLL_REG_SYNCREFDIV_EN :1;
+ __I uint32_t PLL_REG_ENABLE_SYNCREFDIV :1;
+ __IO uint32_t REG_OUT0_PHSINIT :3;
+ __IO uint32_t REG_OUT1_PHSINIT :3;
+ __IO uint32_t REG_OUT2_PHSINIT :3;
+ __IO uint32_t REG_OUT3_PHSINIT :3;
+ __IO uint32_t REG_LOADPHS_B :1;
+ __I uint32_t reserve31 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_PHADJ_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_0_MAIN register definition*/
+ __IO uint32_t SSCG_REG_0_MAIN; /* todo: verify should be r/w, it is not in source file from Duolog */
+ struct
+ {
+ __I uint32_t DIVVAL :6;
+ __I uint32_t FRACIN :24;
+ __I uint32_t reserve00 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_0_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_1_MAIN register definition*/
+ __I uint32_t SSCG_REG_1_MAIN;
+ struct
+ {
+ __I uint32_t DOWNSPREAD :1;
+ __I uint32_t SSMD :5;
+ __I uint32_t FRACMOD :24;
+ __I uint32_t reserve01 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_1_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_2_MAIN register definition*/
+ __IO uint32_t SSCG_REG_2_MAIN;
+ struct
+ {
+ __IO uint32_t INTIN :12;
+ __I uint32_t INTMOD :12;
+ __I uint32_t reserve02 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_2_MAIN_TypeDef;
+
+typedef union{ /*!< SSCG_REG_3_MAIN register definition*/
+ __IO uint32_t SSCG_REG_3_MAIN; /* todo: verify if should be __IO */
+ struct
+ {
+ __I uint32_t SSE_B :1;
+ __I uint32_t SEL_EXTWAVE :2;
+ __I uint32_t EXT_MAXADDR :8;
+ __I uint32_t TBLADDR :8;
+ __I uint32_t RANDOM_FILTER :1;
+ __I uint32_t RANDOM_SEL :2;
+ __I uint32_t reserve03 :1;
+ __I uint32_t reserve04 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_3_MAIN_TypeDef;
+
+typedef union{ /*!< RPC_RESET_MAIN_PLL register definition*/
+ __IO uint32_t RPC_RESET_MAIN_PLL;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_MAIN_PLL :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_MAIN_PLL_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_IOSCB_PLL register definition*/
+ __IO uint32_t SOFT_RESET_IOSCB_PLL;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_NV_MAP_IOSCB_PLL_TypeDef NV_MAP_IOSCB_PLL :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_V_MAP_IOSCB_PLL_TypeDef V_MAP_IOSCB_PLL :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_PERIPH_IOSCB_PLL_TypeDef PERIPH_IOSCB_PLL :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_BLOCKID_IOSCB_PLL_TypeDef BLOCKID_IOSCB_PLL :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_TypeDef;
+
+typedef union{ /*!< PLL_CTRL_IOSCB register definition*/
+ __IO uint32_t PLL_CTRL_IOSCB;
+ struct
+ {
+ __IO uint32_t REG_POWERDOWN_B :1;
+ __IO uint32_t REG_RFDIV_EN :1;
+ __IO uint32_t REG_DIVQ0_EN :1;
+ __IO uint32_t REG_DIVQ1_EN :1;
+ __IO uint32_t REG_DIVQ2_EN :1;
+ __IO uint32_t REG_DIVQ3_EN :1;
+ __IO uint32_t REG_RFCLK_SEL :1;
+ __I uint32_t RESETONLOCK :1;
+ __I uint32_t BYPCK_SEL :4;
+ __I uint32_t REG_BYPASS_GO_B :1;
+ __I uint32_t reserve10 :3;
+ __I uint32_t REG_BYPASSPRE :4;
+ __I uint32_t REG_BYPASSPOST :4;
+ __IO uint32_t LP_REQUIRES_LOCK :1;
+ __I uint32_t LOCK :1;
+ __I uint32_t LOCK_INT_EN :1;
+ __I uint32_t UNLOCK_INT_EN :1;
+ __I uint32_t LOCK_INT :1;
+ __I uint32_t UNLOCK_INT :1;
+ __I uint32_t reserve11 :1;
+ __I uint32_t LOCK_B :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_REF_FB_IOSCB register definition*/
+ __IO uint32_t PLL_REF_FB_IOSCB;
+ struct
+ {
+ __I uint32_t FSE_B :1;
+ __I uint32_t FBCK_SEL :2;
+ __I uint32_t FOUTFB_SELMUX_EN :1;
+ __I uint32_t reserve12 :4;
+ __IO uint32_t RFDIV :6;
+ __I uint32_t reserve13 :2;
+ __I uint32_t reserve14 :12;
+ __I uint32_t reserve15 :4;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_REF_FB_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_FRACN_IOSCB register definition*/
+ __I uint32_t PLL_FRACN_IOSCB;
+ struct
+ {
+ __I uint32_t FRACN_EN :1;
+ __I uint32_t FRACN_DAC_EN :1;
+ __I uint32_t reserve16 :6;
+ __I uint32_t reserve17 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_FRACN_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_DIV_0_1_IOSCB register definition*/
+ __IO uint32_t PLL_DIV_0_1_IOSCB;
+ struct
+ {
+ __I uint32_t VCO0PH_SEL :3;
+ __I uint32_t DIV0_START :3;
+ __I uint32_t reserve18 :2;
+ __IO uint32_t POST0DIV :7;
+ __I uint32_t reserve19 :1;
+ __I uint32_t VCO1PH_SEL :3;
+ __I uint32_t DIV1_START :3;
+ __I uint32_t reserve20 :2;
+ __IO uint32_t POST1DIV :7;
+ __I uint32_t reserve21 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_0_1_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_DIV_2_3_IOSCB register definition*/
+ __IO uint32_t PLL_DIV_2_3_IOSCB;
+ struct
+ {
+ __I uint32_t VCO2PH_SEL :3;
+ __I uint32_t DIV2_START :3;
+ __I uint32_t reserve22 :2;
+ __IO uint32_t POST2DIV :7;
+ __I uint32_t reserve23 :1;
+ __I uint32_t VCO3PH_SEL :3;
+ __I uint32_t DIV3_START :3;
+ __I uint32_t reserve24 :2;
+ __IO uint32_t POST3DIV :7;
+ __I uint32_t CKPOST3_SEL :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_DIV_2_3_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_CTRL2_IOSCB register definition*/
+ __IO uint32_t PLL_CTRL2_IOSCB;
+ struct
+ {
+ __IO uint32_t BWI :2;
+ __IO uint32_t BWP :2;
+ __I uint32_t IREF_EN :1;
+ __I uint32_t IREF_TOGGLE :1;
+ __I uint32_t reserve25 :3;
+ __I uint32_t LOCKCNT :4;
+ __I uint32_t reserve26 :4;
+ __I uint32_t ATEST_EN :1;
+ __I uint32_t ATEST_SEL :3;
+ __I uint32_t reserve27 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CTRL2_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_CAL_IOSCB register definition*/
+ __I uint32_t PLL_CAL_IOSCB;
+ struct
+ {
+ __I uint32_t DSKEWCALCNT :3;
+ __I uint32_t DSKEWCAL_EN :1;
+ __I uint32_t DSKEWCALBYP :1;
+ __I uint32_t reserve28 :3;
+ __I uint32_t DSKEWCALIN :7;
+ __I uint32_t reserve29 :1;
+ __I uint32_t DSKEWCALOUT :7;
+ __I uint32_t reserve30 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CAL_IOSCB_TypeDef;
+
+typedef union{ /*!< PLL_PHADJ_IOSCB register definition*/
+ __IO uint32_t PLL_PHADJ_IOSCB;
+ struct
+ {
+ __I uint32_t PLL_REG_SYNCREFDIV_EN :1;
+ __I uint32_t PLL_REG_ENABLE_SYNCREFDIV :1;
+ __IO uint32_t REG_OUT0_PHSINIT :3;
+ __IO uint32_t REG_OUT1_PHSINIT :3;
+ __IO uint32_t REG_OUT2_PHSINIT :3;
+ __IO uint32_t REG_OUT3_PHSINIT :3;
+ __IO uint32_t REG_LOADPHS_B :1;
+ __I uint32_t reserve31 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_PHADJ_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_0_IOSCB register definition*/
+ __I uint32_t SSCG_REG_0_IOSCB;
+ struct
+ {
+ __I uint32_t DIVVAL :6;
+ __I uint32_t FRACIN :24;
+ __I uint32_t reserve00 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_0_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_1_IOSCB register definition*/
+ __I uint32_t SSCG_REG_1_IOSCB;
+ struct
+ {
+ __I uint32_t DOWNSPREAD :1;
+ __I uint32_t SSMD :5;
+ __I uint32_t FRACMOD :24;
+ __I uint32_t reserve01 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_1_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_2_IOSCB register definition*/
+ __IO uint32_t SSCG_REG_2_IOSCB;
+ struct
+ {
+ __IO uint32_t INTIN :12;
+ __I uint32_t INTMOD :12;
+ __I uint32_t reserve02 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_2_IOSCB_TypeDef;
+
+typedef union{ /*!< SSCG_REG_3_IOSCB register definition*/
+ __I uint32_t SSCG_REG_3_IOSCB;
+ struct
+ {
+ __I uint32_t SSE_B :1;
+ __I uint32_t SEL_EXTWAVE :2;
+ __I uint32_t EXT_MAXADDR :8;
+ __I uint32_t TBLADDR :8;
+ __I uint32_t RANDOM_FILTER :1;
+ __I uint32_t RANDOM_SEL :2;
+ __I uint32_t reserve03 :1;
+ __I uint32_t reserve04 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SSCG_REG_3_IOSCB_TypeDef;
+
+typedef union{ /*!< RPC_RESET_IOSCB register definition*/
+ __IO uint32_t RPC_RESET_IOSCB;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_IOSCB :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_IOSCB_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_BANK_CTRL register definition*/
+ __IO uint32_t SOFT_RESET_BANK_CTRL;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_NV_MAP_BANK_CTRL_TypeDef NV_MAP_BANK_CTRL :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_V_MAP_BANK_CTRL_TypeDef V_MAP_BANK_CTRL :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_PERIPH_BANK_CTRL_TypeDef PERIPH_BANK_CTRL :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_BLOCKID_BANK_CTRL_TypeDef BLOCKID_BANK_CTRL :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_TypeDef;
+
+typedef union{ /*!< DPC_BITS register definition*/
+ __IO uint32_t DPC_BITS;
+ struct
+ {
+ __IO uint32_t dpc_vs :4;
+ __IO uint32_t dpc_vrgen_h :6;
+ __IO uint32_t dpc_vrgen_en_h :1;
+ __IO uint32_t dpc_move_en_h :1;
+ __IO uint32_t dpc_vrgen_v :6;
+ __IO uint32_t dpc_vrgen_en_v :1;
+ __IO uint32_t dpc_move_en_v :1;
+ __I uint32_t reserve01 :12;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DPC_BITS_TypeDef;
+
+typedef union{ /*!< BANK_STATUS register definition*/
+ __I uint32_t BANK_STATUS;
+ struct
+ {
+ __I uint32_t sro_calib_status_b :1;
+ __I uint32_t sro_ioen_bnk_b :1;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_BANK_STATUS_TypeDef;
+
+typedef union{ /*!< RPC_RESET_BANK_CTRL register definition*/
+ __IO uint32_t RPC_RESET_BANK_CTRL;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_BANK_CTRL :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_BANK_CTRL_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_IOCALIB register definition*/
+ __IO uint32_t SOFT_RESET_IOCALIB;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_NV_MAP_IOCALIB_TypeDef NV_MAP_IOCALIB :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_V_MAP_IOCALIB_TypeDef V_MAP_IOCALIB :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_PERIPH_IOCALIB_TypeDef PERIPH_IOCALIB :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_BLOCKID_IOCALIB_TypeDef BLOCKID_IOCALIB :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_TypeDef;
+
+typedef union{ /*!< IOC_REG0 register definition*/
+ __IO uint32_t IOC_REG0;
+ struct
+ {
+ __IO uint32_t reg_pcode :6;
+ __IO uint32_t reg_ncode :6;
+ __I uint32_t reg_calib_trim :1;
+ __IO uint32_t reg_calib_start :1;
+ __IO uint32_t reg_calib_lock :1;
+ __I uint32_t reg_calib_load :1;
+ __I uint32_t reg_calib_direction :1;
+ __I uint32_t reg_calib_move_pcode :1;
+ __I uint32_t reg_calib_move_ncode :1;
+ __I uint32_t reserve01 :13;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG0_TypeDef;
+
+typedef union{ /*!< IOC_REG1 register definition*/
+ __I uint32_t IOC_REG1;
+ struct
+ {
+ __I uint32_t sro_code_done_p :1;
+ __I uint32_t sro_code_done_n :1;
+ __I uint32_t sro_calib_status :1;
+ __I uint32_t sro_calib_intrpt :1;
+ __I uint32_t sro_ioen_out :1;
+ __I uint32_t sro_power_on :1;
+ __I uint32_t sro_comp_sel :1;
+ __I uint32_t sro_comp_en :1;
+ __I uint32_t reserve02 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG1_TypeDef;
+
+typedef union{ /*!< IOC_REG2 register definition*/
+ __I uint32_t IOC_REG2;
+ struct
+ {
+ __I uint32_t sro_pcode :7;
+ __I uint32_t sro_ncode :7;
+ __I uint32_t sro_ref_pcode :7;
+ __I uint32_t sro_ref_ncode :7;
+ __I uint32_t sro_comp_out :1;
+ __I uint32_t reserve03 :3;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG2_TypeDef;
+
+typedef union{ /*!< IOC_REG3 register definition*/
+ __I uint32_t IOC_REG3;
+ struct
+ {
+ __I uint32_t reserve04 :5;
+ __I uint32_t reg_calib_poffset :6;
+ __I uint32_t reg_calib_poffset_dir :1;
+ __I uint32_t reg_calib_noffset :6;
+ __I uint32_t reg_calib_noffset_dir :1;
+ __I uint32_t reg_calib_move_slewr :1;
+ __I uint32_t reg_calib_move_slewf :1;
+ __I uint32_t reg_calib_roffset_dir :1;
+ __I uint32_t reg_calib_foffset_dir :1;
+ __I uint32_t reserve05 :9;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG3_TypeDef;
+
+typedef union{ /*!< IOC_REG4 register definition*/
+ __I uint32_t IOC_REG4;
+ struct
+ {
+ __I uint32_t reg_roffset :6;
+ __I uint32_t reg_foffset :6;
+ __I uint32_t reg_slewr :6;
+ __I uint32_t reg_slewf :6;
+ __I uint32_t sro_slew_intrpt :1;
+ __I uint32_t sro_slew_status :1;
+ __I uint32_t sro_slew_comp_out :1;
+ __I uint32_t sro_slew_comp_en :1;
+ __I uint32_t sro_slew_comp_sel :1;
+ __I uint32_t sro_slew_ioen_out :1;
+ __I uint32_t sro_slew_power_on :1;
+ __I uint32_t reserve06 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG4_TypeDef;
+
+typedef union{ /*!< IOC_REG5 register definition*/
+ __I uint32_t IOC_REG5;
+ struct
+ {
+ __I uint32_t sro_ref_slewr :6;
+ __I uint32_t sro_ref_slewf :12;
+ __I uint32_t sro_slewr :6;
+ __I uint32_t sro_slewf :6;
+ __I uint32_t reserve07 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG5_TypeDef;
+
+typedef union{ /*!< IOC_REG6 register definition*/
+ __IO uint32_t IOC_REG6;
+ struct
+ {
+ __IO uint32_t reg_calib_reset :1;
+ __IO uint32_t reg_calib_clkdiv :2;
+ __I uint32_t reserve08 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_IOC_REG6_TypeDef;
+
+typedef union{ /*!< RPC_RESET_IOCALIB register definition*/
+ __IO uint32_t RPC_RESET_IOCALIB;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_IOCALIB :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_IOCALIB_TypeDef;
+
+typedef union{ /*!< rpc_calib register definition*/
+ __IO uint32_t rpc_calib;
+ struct
+ {
+ __IO uint32_t start_pvt :1;
+ __IO uint32_t lock_pvt :1;
+ __I uint32_t Reserved :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc_calib_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_CFM register definition*/
+ __IO uint32_t SOFT_RESET_CFM;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_NV_MAP_CFM_TypeDef NV_MAP_CFM :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_V_MAP_CFM_TypeDef V_MAP_CFM :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_PERIPH_CFM_TypeDef PERIPH_CFM :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_BLOCKID_CFM_TypeDef BLOCKID_CFM :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_TypeDef;
+
+typedef union{ /*!< BCLKMUX register definition*/
+ __IO uint32_t BCLKMUX;
+ struct
+ {
+ __IO uint32_t bclk0_sel :5;
+ __IO uint32_t bclk1_sel :5;
+ __IO uint32_t bclk2_sel :5;
+ __IO uint32_t bclk3_sel :5;
+ __IO uint32_t bclk4_sel :5;
+ __IO uint32_t bclk5_sel :5;
+ __I uint32_t reserve0 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_BCLKMUX_TypeDef;
+
+typedef union{ /*!< PLL_CKMUX register definition*/
+ __IO uint32_t PLL_CKMUX;
+ struct
+ {
+ __IO uint32_t clk_in_mac_tsu :2;
+ __IO uint32_t pll0_rfclk0_sel :2;
+ __IO uint32_t pll0_rfclk1_sel :2;
+ __IO uint32_t pll1_rfclk0_sel :2;
+ __IO uint32_t pll1_rfclk1_sel :2;
+ __IO uint32_t pll1_fdr_sel :5;
+ __I uint32_t reserve1 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CKMUX_TypeDef;
+
+typedef union{ /*!< MSSCLKMUX register definition*/
+ __IO uint32_t MSSCLKMUX;
+ struct
+ {
+ __IO uint32_t mssclk_mux_sel :2;
+ __IO uint32_t mssclk_mux_md :2;
+ __IO uint32_t clk_standby_sel :1;
+ __I uint32_t reserve2 :27;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_MSSCLKMUX_TypeDef;
+
+typedef union{ /*!< SPARE0 register definition*/
+ __IO uint32_t SPARE0;
+ struct
+ {
+ __IO uint32_t spare0 :32;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SPARE0_TypeDef;
+
+typedef union{ /*!< FMETER_ADDR register definition*/
+ __I uint32_t FMETER_ADDR;
+ struct
+ {
+ __I uint32_t addr10 :2;
+ __I uint32_t addr :4;
+ __I uint32_t reserve3 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_FMETER_ADDR_TypeDef;
+
+typedef union{ /*!< FMETER_DATAW register definition*/
+ __I uint32_t FMETER_DATAW;
+ struct
+ {
+ __I uint32_t data :24;
+ __I uint32_t strobe :1;
+ __I uint32_t reserve4 :7;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_FMETER_DATAW_TypeDef;
+
+typedef union{ /*!< FMETER_DATAR register definition*/
+ __I uint32_t FMETER_DATAR;
+ struct
+ {
+ __I uint32_t data :24;
+ __I uint32_t reserve5 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_FMETER_DATAR_TypeDef;
+
+typedef union{ /*!< TEST_CTRL register definition*/
+ __I uint32_t TEST_CTRL;
+ struct
+ {
+ __I uint32_t atest_en :1;
+ __I uint32_t atest_sel :5;
+ __I uint32_t dtest_en :1;
+ __I uint32_t dtest_sel :5;
+ __I uint32_t reserve6 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_TEST_CTRL_TypeDef;
+
+typedef union{ /*!< RPC_RESET_CFM register definition*/
+ __IO uint32_t RPC_RESET_CFM;
+ struct
+ {
+ __IO uint32_t soft_reset_periph_CFM :1;
+ __I uint32_t Reserved :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RPC_RESET_CFM_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DECODER_DRIVER register definition*/
+ __IO uint32_t SOFT_RESET_DECODER_DRIVER;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_NV_MAP_DECODER_DRIVER_TypeDef NV_MAP_DECODER_DRIVER :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_V_MAP_DECODER_DRIVER_TypeDef V_MAP_DECODER_DRIVER :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_PERIPH_DECODER_DRIVER_TypeDef PERIPH_DECODER_DRIVER :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_BLOCKID_DECODER_DRIVER_TypeDef BLOCKID_DECODER_DRIVER :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_TypeDef;
+
+typedef union{ /*!< rpc1_DRV register definition*/
+ __IO uint32_t rpc1_DRV;
+ struct
+ {
+ __IO uint32_t drv_addcmd :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc1_DRV_TypeDef;
+
+typedef union{ /*!< rpc2_DRV register definition*/
+ __IO uint32_t rpc2_DRV;
+ struct
+ {
+ __IO uint32_t drv_clk :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc2_DRV_TypeDef;
+
+typedef union{ /*!< rpc3_DRV register definition*/
+ __IO uint32_t rpc3_DRV;
+ struct
+ {
+ __IO uint32_t drv_dq :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc3_DRV_TypeDef;
+
+typedef union{ /*!< rpc4_DRV register definition*/
+ __IO uint32_t rpc4_DRV;
+ struct
+ {
+ __IO uint32_t drv_dqs :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc4_DRV_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DECODER_ODT register definition*/
+ __IO uint32_t SOFT_RESET_DECODER_ODT;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_NV_MAP_DECODER_ODT_TypeDef NV_MAP_DECODER_ODT :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_V_MAP_DECODER_ODT_TypeDef V_MAP_DECODER_ODT :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_PERIPH_DECODER_ODT_TypeDef PERIPH_DECODER_ODT :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_BLOCKID_DECODER_ODT_TypeDef BLOCKID_DECODER_ODT :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_TypeDef;
+
+typedef union{ /*!< rpc1_ODT register definition*/
+ __IO uint32_t rpc1_ODT;
+ struct
+ {
+ __IO uint32_t odt_addcmd :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc1_ODT_TypeDef;
+
+typedef union{ /*!< rpc2_ODT register definition*/
+ __IO uint32_t rpc2_ODT;
+ struct
+ {
+ __IO uint32_t odt_clk :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc2_ODT_TypeDef;
+
+typedef union{ /*!< rpc3_ODT register definition*/
+ __IO uint32_t rpc3_ODT;
+ struct
+ {
+ __IO uint32_t odt_dq :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc3_ODT_TypeDef;
+
+typedef union{ /*!< rpc4_ODT register definition*/
+ __IO uint32_t rpc4_ODT;
+ struct
+ {
+ __IO uint32_t odt_dqs :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc4_ODT_TypeDef;
+
+typedef union{ /*!< rpc5_ODT register definition*/
+ __IO uint32_t rpc5_ODT;
+ struct
+ {
+ __IO uint32_t odt_dyn_sel_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc5_ODT_TypeDef;
+
+typedef union{ /*!< rpc6_ODT register definition*/
+ __IO uint32_t rpc6_ODT;
+ struct
+ {
+ __IO uint32_t odt_dyn_sel_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc6_ODT_TypeDef;
+
+typedef union{ /*!< rpc7_ODT register definition*/
+ __IO uint32_t rpc7_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc7_ODT_TypeDef;
+
+typedef union{ /*!< rpc8_ODT register definition*/
+ __IO uint32_t rpc8_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc8_ODT_TypeDef;
+
+typedef union{ /*!< rpc9_ODT register definition*/
+ __IO uint32_t rpc9_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc9_ODT_TypeDef;
+
+typedef union{ /*!< rpc10_ODT register definition*/
+ __IO uint32_t rpc10_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc10_ODT_TypeDef;
+
+typedef union{ /*!< rpc11_ODT register definition*/
+ __IO uint32_t rpc11_ODT;
+ struct
+ {
+ __IO uint32_t odt_static_dqs :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc11_ODT_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_DECODER_IO register definition*/
+ __IO uint32_t SOFT_RESET_DECODER_IO;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_NV_MAP_DECODER_IO_TypeDef NV_MAP_DECODER_IO :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_V_MAP_DECODER_IO_TypeDef V_MAP_DECODER_IO :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_PERIPH_DECODER_IO_TypeDef PERIPH_DECODER_IO :1;
+ __I uint32_t reserved_02 :7;
+ __I CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_BLOCKID_DECODER_IO_TypeDef BLOCKID_DECODER_IO :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_TypeDef;
+
+typedef union{ /*!< ovrt1 register definition*/
+ __IO uint32_t ovrt1;
+ struct
+ {
+ __IO uint32_t drv_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt1_TypeDef;
+
+typedef union{ /*!< ovrt2 register definition*/
+ __IO uint32_t ovrt2;
+ struct
+ {
+ __IO uint32_t drv_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt2_TypeDef;
+
+typedef union{ /*!< ovrt3 register definition*/
+ __IO uint32_t ovrt3;
+ struct
+ {
+ __IO uint32_t drv_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt3_TypeDef;
+
+typedef union{ /*!< ovrt4 register definition*/
+ __IO uint32_t ovrt4;
+ struct
+ {
+ __IO uint32_t drv_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt4_TypeDef;
+
+typedef union{ /*!< ovrt5 register definition*/
+ __IO uint32_t ovrt5;
+ struct
+ {
+ __IO uint32_t drv_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt5_TypeDef;
+
+typedef union{ /*!< ovrt6 register definition*/
+ __IO uint32_t ovrt6;
+ struct
+ {
+ __IO uint32_t drv_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt6_TypeDef;
+
+typedef union{ /*!< ovrt7 register definition*/
+ __IO uint32_t ovrt7;
+ struct
+ {
+ __IO uint32_t drv_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt7_TypeDef;
+
+typedef union{ /*!< ovrt8 register definition*/
+ __IO uint32_t ovrt8;
+ struct
+ {
+ __IO uint32_t drv_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt8_TypeDef;
+
+typedef union{ /*!< ovrt9 register definition*/
+ __IO uint32_t ovrt9;
+ struct
+ {
+ __IO uint32_t en_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt9_TypeDef;
+
+typedef union{ /*!< ovrt10 register definition*/
+ __IO uint32_t ovrt10;
+ struct
+ {
+ __IO uint32_t en_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt10_TypeDef;
+
+typedef union{ /*!< ovrt11 register definition*/
+ __IO uint32_t ovrt11;
+ struct
+ {
+ __IO uint32_t en_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt11_TypeDef;
+
+typedef union{ /*!< ovrt12 register definition*/
+ __IO uint32_t ovrt12;
+ struct
+ {
+ __IO uint32_t en_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt12_TypeDef;
+
+typedef union{ /*!< ovrt13 register definition*/
+ __IO uint32_t ovrt13;
+ struct
+ {
+ __IO uint32_t en_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt13_TypeDef;
+
+typedef union{ /*!< ovrt14 register definition*/
+ __IO uint32_t ovrt14;
+ struct
+ {
+ __IO uint32_t en_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt14_TypeDef;
+
+typedef union{ /*!< ovrt15 register definition*/
+ __IO uint32_t ovrt15;
+ struct
+ {
+ __IO uint32_t en_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt15_TypeDef;
+
+typedef union{ /*!< ovrt16 register definition*/
+ __IO uint32_t ovrt16;
+ struct
+ {
+ __IO uint32_t en_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_ovrt16_TypeDef;
+
+typedef union{ /*!< rpc17 register definition*/
+ __IO uint32_t rpc17;
+ struct
+ {
+ __IO uint32_t bclk_sel_ac :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc17_TypeDef;
+
+typedef union{ /*!< rpc18 register definition*/
+ __IO uint32_t rpc18;
+ struct
+ {
+ __IO uint32_t bclk_sel_addcmd :9;
+ __I uint32_t reserved_01 :23;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc18_TypeDef;
+
+typedef union{ /*!< rpc19 register definition*/
+ __IO uint32_t rpc19;
+ struct
+ {
+ __IO uint32_t bclk_sel_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc19_TypeDef;
+
+typedef union{ /*!< rpc20 register definition*/
+ __IO uint32_t rpc20;
+ struct
+ {
+ __IO uint32_t bclk_sel_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc20_TypeDef;
+
+typedef union{ /*!< rpc21 register definition*/
+ __IO uint32_t rpc21;
+ struct
+ {
+ __IO uint32_t bclk_sel_data :9;
+ __I uint32_t reserved_01 :23;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc21_TypeDef;
+
+typedef union{ /*!< rpc22 register definition*/
+ __IO uint32_t rpc22;
+ struct
+ {
+ __IO uint32_t bclk_sel_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc22_TypeDef;
+
+typedef union{ /*!< rpc23 register definition*/
+ __IO uint32_t rpc23;
+ struct
+ {
+ __IO uint32_t bclk_sel_dqsn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc23_TypeDef;
+
+typedef union{ /*!< rpc24 register definition*/
+ __IO uint32_t rpc24;
+ struct
+ {
+ __IO uint32_t bclk_sel_dqsp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc24_TypeDef;
+
+typedef union{ /*!< rpc25 register definition*/
+ __IO uint32_t rpc25;
+ struct
+ {
+ __IO uint32_t cdr_md_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc25_TypeDef;
+
+typedef union{ /*!< rpc26 register definition*/
+ __IO uint32_t rpc26;
+ struct
+ {
+ __IO uint32_t cdr_md_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc26_TypeDef;
+
+typedef union{ /*!< rpc27 register definition*/
+ __IO uint32_t rpc27;
+ struct
+ {
+ __IO uint32_t clk_md_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc27_TypeDef;
+
+typedef union{ /*!< rpc28 register definition*/
+ __IO uint32_t rpc28;
+ struct
+ {
+ __IO uint32_t clk_sel_addcmd :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc28_TypeDef;
+
+typedef union{ /*!< rpc29 register definition*/
+ __IO uint32_t rpc29;
+ struct
+ {
+ __IO uint32_t clk_sel_data :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc29_TypeDef;
+
+typedef union{ /*!< rpc30 register definition*/
+ __IO uint32_t rpc30;
+ struct
+ {
+ __IO uint32_t code_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc30_TypeDef;
+
+typedef union{ /*!< rpc31 register definition*/
+ __IO uint32_t rpc31;
+ struct
+ {
+ __IO uint32_t code_sel_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc31_TypeDef;
+
+typedef union{ /*!< rpc32 register definition*/
+ __IO uint32_t rpc32;
+ struct
+ {
+ __IO uint32_t comp_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc32_TypeDef;
+
+typedef union{ /*!< rpc33 register definition*/
+ __IO uint32_t rpc33;
+ struct
+ {
+ __IO uint32_t comp_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc33_TypeDef;
+
+typedef union{ /*!< rpc34 register definition*/
+ __IO uint32_t rpc34;
+ struct
+ {
+ __IO uint32_t comp_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc34_TypeDef;
+
+typedef union{ /*!< rpc35 register definition*/
+ __IO uint32_t rpc35;
+ struct
+ {
+ __IO uint32_t comp_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc35_TypeDef;
+
+typedef union{ /*!< rpc36 register definition*/
+ __IO uint32_t rpc36;
+ struct
+ {
+ __IO uint32_t comp_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc36_TypeDef;
+
+typedef union{ /*!< rpc37 register definition*/
+ __IO uint32_t rpc37;
+ struct
+ {
+ __IO uint32_t comp_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc37_TypeDef;
+
+typedef union{ /*!< rpc38 register definition*/
+ __IO uint32_t rpc38;
+ struct
+ {
+ __IO uint32_t divclk_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc38_TypeDef;
+
+typedef union{ /*!< rpc39 register definition*/
+ __IO uint32_t rpc39;
+ struct
+ {
+ __IO uint32_t divclk_sel_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc39_TypeDef;
+
+typedef union{ /*!< rpc40 register definition*/
+ __IO uint32_t rpc40;
+ struct
+ {
+ __IO uint32_t div_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc40_TypeDef;
+
+typedef union{ /*!< rpc41 register definition*/
+ __IO uint32_t rpc41;
+ struct
+ {
+ __IO uint32_t div_data :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc41_TypeDef;
+
+typedef union{ /*!< rpc42 register definition*/
+ __IO uint32_t rpc42;
+ struct
+ {
+ __IO uint32_t dly_md_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc42_TypeDef;
+
+typedef union{ /*!< rpc43 register definition*/
+ __IO uint32_t rpc43;
+ struct
+ {
+ __IO uint32_t dly_md_clkn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc43_TypeDef;
+
+typedef union{ /*!< rpc44 register definition*/
+ __IO uint32_t rpc44;
+ struct
+ {
+ __IO uint32_t dly_md_clkp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc44_TypeDef;
+
+typedef union{ /*!< rpc45 register definition*/
+ __IO uint32_t rpc45;
+ struct
+ {
+ __IO uint32_t dly_md_dq :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc45_TypeDef;
+
+typedef union{ /*!< rpc46 register definition*/
+ __IO uint32_t rpc46;
+ struct
+ {
+ __IO uint32_t dly_md_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc46_TypeDef;
+
+typedef union{ /*!< rpc47 register definition*/
+ __IO uint32_t rpc47;
+ struct
+ {
+ __IO uint32_t dly_md_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc47_TypeDef;
+
+typedef union{ /*!< rpc48 register definition*/
+ __IO uint32_t rpc48;
+ struct
+ {
+ __IO uint32_t dqs_md_data :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc48_TypeDef;
+
+typedef union{ /*!< rpc49 register definition*/
+ __IO uint32_t rpc49;
+ struct
+ {
+ __IO uint32_t dynen_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc49_TypeDef;
+
+typedef union{ /*!< rpc50 register definition*/
+ __IO uint32_t rpc50;
+ struct
+ {
+ __IO uint32_t dynen_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc50_TypeDef;
+
+typedef union{ /*!< rpc51 register definition*/
+ __IO uint32_t rpc51;
+ struct
+ {
+ __IO uint32_t dynen_soft_reset_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc51_TypeDef;
+
+typedef union{ /*!< rpc52 register definition*/
+ __IO uint32_t rpc52;
+ struct
+ {
+ __IO uint32_t dynen_soft_reset_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc52_TypeDef;
+
+typedef union{ /*!< rpc53 register definition*/
+ __IO uint32_t rpc53;
+ struct
+ {
+ __IO uint32_t edgedet_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc53_TypeDef;
+
+typedef union{ /*!< rpc54 register definition*/
+ __IO uint32_t rpc54;
+ struct
+ {
+ __IO uint32_t edgedet_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc54_TypeDef;
+
+typedef union{ /*!< rpc55 register definition*/
+ __IO uint32_t rpc55;
+ struct
+ {
+ __IO uint32_t edgedet_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc55_TypeDef;
+
+typedef union{ /*!< rpc56 register definition*/
+ __IO uint32_t rpc56;
+ struct
+ {
+ __IO uint32_t edgedet_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc56_TypeDef;
+
+typedef union{ /*!< rpc57 register definition*/
+ __IO uint32_t rpc57;
+ struct
+ {
+ __IO uint32_t edgedet_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc57_TypeDef;
+
+typedef union{ /*!< rpc58 register definition*/
+ __IO uint32_t rpc58;
+ struct
+ {
+ __IO uint32_t edgedet_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc58_TypeDef;
+
+typedef union{ /*!< rpc59 register definition*/
+ __IO uint32_t rpc59;
+ struct
+ {
+ __IO uint32_t eyewidth_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc59_TypeDef;
+
+typedef union{ /*!< rpc60 register definition*/
+ __IO uint32_t rpc60;
+ struct
+ {
+ __IO uint32_t eyewidth_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc60_TypeDef;
+
+typedef union{ /*!< rpc61 register definition*/
+ __IO uint32_t rpc61;
+ struct
+ {
+ __IO uint32_t eyewidth_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc61_TypeDef;
+
+typedef union{ /*!< rpc62 register definition*/
+ __IO uint32_t rpc62;
+ struct
+ {
+ __IO uint32_t eyewidth_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc62_TypeDef;
+
+typedef union{ /*!< rpc63 register definition*/
+ __IO uint32_t rpc63;
+ struct
+ {
+ __IO uint32_t eyewidth_dqsn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc63_TypeDef;
+
+typedef union{ /*!< rpc64 register definition*/
+ __IO uint32_t rpc64;
+ struct
+ {
+ __IO uint32_t eyewidth_dqsp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc64_TypeDef;
+
+typedef union{ /*!< rpc65 register definition*/
+ __IO uint32_t rpc65;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc65_TypeDef;
+
+typedef union{ /*!< rpc66 register definition*/
+ __IO uint32_t rpc66;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc66_TypeDef;
+
+typedef union{ /*!< rpc67 register definition*/
+ __IO uint32_t rpc67;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc67_TypeDef;
+
+typedef union{ /*!< rpc68 register definition*/
+ __IO uint32_t rpc68;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc68_TypeDef;
+
+typedef union{ /*!< rpc69 register definition*/
+ __IO uint32_t rpc69;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc69_TypeDef;
+
+typedef union{ /*!< rpc70 register definition*/
+ __IO uint32_t rpc70;
+ struct
+ {
+ __IO uint32_t eyewidth_sel_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc70_TypeDef;
+
+typedef union{ /*!< rpc71 register definition*/
+ __IO uint32_t rpc71;
+ struct
+ {
+ __IO uint32_t eye_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc71_TypeDef;
+
+typedef union{ /*!< rpc72 register definition*/
+ __IO uint32_t rpc72;
+ struct
+ {
+ __IO uint32_t eye_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc72_TypeDef;
+
+typedef union{ /*!< rpc73 register definition*/
+ __IO uint32_t rpc73;
+ struct
+ {
+ __IO uint32_t eye_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc73_TypeDef;
+
+typedef union{ /*!< rpc74 register definition*/
+ __IO uint32_t rpc74;
+ struct
+ {
+ __IO uint32_t eye_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc74_TypeDef;
+
+typedef union{ /*!< rpc75 register definition*/
+ __IO uint32_t rpc75;
+ struct
+ {
+ __IO uint32_t eye_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc75_TypeDef;
+
+typedef union{ /*!< rpc76 register definition*/
+ __IO uint32_t rpc76;
+ struct
+ {
+ __IO uint32_t eye_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc76_TypeDef;
+
+typedef union{ /*!< rpc77 register definition*/
+ __IO uint32_t rpc77;
+ struct
+ {
+ __IO uint32_t eye_sdr_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc77_TypeDef;
+
+typedef union{ /*!< rpc78 register definition*/
+ __IO uint32_t rpc78;
+ struct
+ {
+ __IO uint32_t eye_sdr_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc78_TypeDef;
+
+typedef union{ /*!< rpc79 register definition*/
+ __IO uint32_t rpc79;
+ struct
+ {
+ __IO uint32_t eye_sdr_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc79_TypeDef;
+
+typedef union{ /*!< rpc80 register definition*/
+ __IO uint32_t rpc80;
+ struct
+ {
+ __IO uint32_t eye_sdr_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc80_TypeDef;
+
+typedef union{ /*!< rpc81 register definition*/
+ __IO uint32_t rpc81;
+ struct
+ {
+ __IO uint32_t eye_sdr_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc81_TypeDef;
+
+typedef union{ /*!< rpc82 register definition*/
+ __IO uint32_t rpc82;
+ struct
+ {
+ __IO uint32_t eye_sdr_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc82_TypeDef;
+
+typedef union{ /*!< rpc83 register definition*/
+ __IO uint32_t rpc83;
+ struct
+ {
+ __IO uint32_t fifowe_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc83_TypeDef;
+
+typedef union{ /*!< rpc84 register definition*/
+ __IO uint32_t rpc84;
+ struct
+ {
+ __IO uint32_t fifowe_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc84_TypeDef;
+
+typedef union{ /*!< rpc85 register definition*/
+ __IO uint32_t rpc85;
+ struct
+ {
+ __IO uint32_t fifowe_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc85_TypeDef;
+
+typedef union{ /*!< rpc86 register definition*/
+ __IO uint32_t rpc86;
+ struct
+ {
+ __IO uint32_t fifowe_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc86_TypeDef;
+
+typedef union{ /*!< rpc87 register definition*/
+ __IO uint32_t rpc87;
+ struct
+ {
+ __IO uint32_t fifowe_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc87_TypeDef;
+
+typedef union{ /*!< rpc88 register definition*/
+ __IO uint32_t rpc88;
+ struct
+ {
+ __IO uint32_t fifowe_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc88_TypeDef;
+
+typedef union{ /*!< rpc89 register definition*/
+ __IO uint32_t rpc89;
+ struct
+ {
+ __IO uint32_t fifo_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc89_TypeDef;
+
+typedef union{ /*!< rpc90 register definition*/
+ __IO uint32_t rpc90;
+ struct
+ {
+ __IO uint32_t fifo_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc90_TypeDef;
+
+typedef union{ /*!< rpc91 register definition*/
+ __IO uint32_t rpc91;
+ struct
+ {
+ __IO uint32_t fifo_run_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc91_TypeDef;
+
+typedef union{ /*!< rpc92 register definition*/
+ __IO uint32_t rpc92;
+ struct
+ {
+ __IO uint32_t fifo_run_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc92_TypeDef;
+
+typedef union{ /*!< rpc93 register definition*/
+ __IO uint32_t rpc93;
+ struct
+ {
+ __IO uint32_t gsr_disable_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc93_TypeDef;
+
+typedef union{ /*!< rpc94 register definition*/
+ __IO uint32_t rpc94;
+ struct
+ {
+ __IO uint32_t gsr_disable_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc94_TypeDef;
+
+typedef union{ /*!< rpc95 register definition*/
+ __IO uint32_t rpc95;
+ struct
+ {
+ __IO uint32_t ibufmd_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc95_TypeDef;
+
+typedef union{ /*!< rpc96 register definition*/
+ __IO uint32_t rpc96;
+ struct
+ {
+ __IO uint32_t ibufmd_clk :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc96_TypeDef;
+
+typedef union{ /*!< rpc97 register definition*/
+ __IO uint32_t rpc97;
+ struct
+ {
+ __IO uint32_t ibufmd_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc97_TypeDef;
+
+typedef union{ /*!< rpc98 register definition*/
+ __IO uint32_t rpc98;
+ struct
+ {
+ __IO uint32_t ibufmd_dqs :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc98_TypeDef;
+
+typedef union{ /*!< rpc99 register definition*/
+ __IO uint32_t rpc99;
+ struct
+ {
+ __IO uint32_t indly_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc99_TypeDef;
+
+typedef union{ /*!< rpc100 register definition*/
+ __IO uint32_t rpc100;
+ struct
+ {
+ __IO uint32_t indly_sel_clkn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc100_TypeDef;
+
+typedef union{ /*!< rpc101 register definition*/
+ __IO uint32_t rpc101;
+ struct
+ {
+ __IO uint32_t indly_sel_clkp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc101_TypeDef;
+
+typedef union{ /*!< rpc102 register definition*/
+ __IO uint32_t rpc102;
+ struct
+ {
+ __IO uint32_t indly_sel_dq :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc102_TypeDef;
+
+typedef union{ /*!< rpc103 register definition*/
+ __IO uint32_t rpc103;
+ struct
+ {
+ __IO uint32_t indly_sel_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc103_TypeDef;
+
+typedef union{ /*!< rpc104 register definition*/
+ __IO uint32_t rpc104;
+ struct
+ {
+ __IO uint32_t indly_sel_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc104_TypeDef;
+
+typedef union{ /*!< rpc105 register definition*/
+ __IO uint32_t rpc105;
+ struct
+ {
+ __IO uint32_t lane_pvt_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc105_TypeDef;
+
+typedef union{ /*!< rpc106 register definition*/
+ __IO uint32_t rpc106;
+ struct
+ {
+ __IO uint32_t lane_pvt_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc106_TypeDef;
+
+typedef union{ /*!< rpc107 register definition*/
+ __IO uint32_t rpc107;
+ struct
+ {
+ __IO uint32_t lsr_disable_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc107_TypeDef;
+
+typedef union{ /*!< rpc108 register definition*/
+ __IO uint32_t rpc108;
+ struct
+ {
+ __IO uint32_t lsr_disable_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc108_TypeDef;
+
+typedef union{ /*!< rpc109 register definition*/
+ __IO uint32_t rpc109;
+ struct
+ {
+ __IO uint32_t lsr_disable_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc109_TypeDef;
+
+typedef union{ /*!< rpc110 register definition*/
+ __IO uint32_t rpc110;
+ struct
+ {
+ __IO uint32_t lsr_disable_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc110_TypeDef;
+
+typedef union{ /*!< rpc111 register definition*/
+ __IO uint32_t rpc111;
+ struct
+ {
+ __IO uint32_t lsr_disable_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc111_TypeDef;
+
+typedef union{ /*!< rpc112 register definition*/
+ __IO uint32_t rpc112;
+ struct
+ {
+ __IO uint32_t lsr_disable_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc112_TypeDef;
+
+typedef union{ /*!< rpc113 register definition*/
+ __IO uint32_t rpc113;
+ struct
+ {
+ __IO uint32_t mvdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc113_TypeDef;
+
+typedef union{ /*!< rpc114 register definition*/
+ __IO uint32_t rpc114;
+ struct
+ {
+ __IO uint32_t mvdly_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc114_TypeDef;
+
+typedef union{ /*!< rpc115 register definition*/
+ __IO uint32_t rpc115;
+ struct
+ {
+ __IO uint32_t mvdly_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc115_TypeDef;
+
+typedef union{ /*!< rpc116 register definition*/
+ __IO uint32_t rpc116;
+ struct
+ {
+ __IO uint32_t mvdly_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc116_TypeDef;
+
+typedef union{ /*!< rpc117 register definition*/
+ __IO uint32_t rpc117;
+ struct
+ {
+ __IO uint32_t mvdly_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc117_TypeDef;
+
+typedef union{ /*!< rpc118 register definition*/
+ __IO uint32_t rpc118;
+ struct
+ {
+ __IO uint32_t mvdly_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc118_TypeDef;
+
+typedef union{ /*!< rpc119 register definition*/
+ __IO uint32_t rpc119;
+ struct
+ {
+ __IO uint32_t oeclk_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc119_TypeDef;
+
+typedef union{ /*!< rpc120 register definition*/
+ __IO uint32_t rpc120;
+ struct
+ {
+ __IO uint32_t oeclk_inv_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc120_TypeDef;
+
+typedef union{ /*!< rpc121 register definition*/
+ __IO uint32_t rpc121;
+ struct
+ {
+ __IO uint32_t oeclk_inv_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc121_TypeDef;
+
+typedef union{ /*!< rpc122 register definition*/
+ __IO uint32_t rpc122;
+ struct
+ {
+ __IO uint32_t oeclk_inv_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc122_TypeDef;
+
+typedef union{ /*!< rpc123 register definition*/
+ __IO uint32_t rpc123;
+ struct
+ {
+ __IO uint32_t oeclk_inv_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc123_TypeDef;
+
+typedef union{ /*!< rpc124 register definition*/
+ __IO uint32_t rpc124;
+ struct
+ {
+ __IO uint32_t oeclk_inv_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc124_TypeDef;
+
+typedef union{ /*!< rpc125 register definition*/
+ __IO uint32_t rpc125;
+ struct
+ {
+ __IO uint32_t oe_md_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc125_TypeDef;
+
+typedef union{ /*!< rpc126 register definition*/
+ __IO uint32_t rpc126;
+ struct
+ {
+ __IO uint32_t oe_md_clkn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc126_TypeDef;
+
+typedef union{ /*!< rpc127 register definition*/
+ __IO uint32_t rpc127;
+ struct
+ {
+ __IO uint32_t oe_md_clkp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc127_TypeDef;
+
+typedef union{ /*!< rpc128 register definition*/
+ __IO uint32_t rpc128;
+ struct
+ {
+ __IO uint32_t oe_md_dq :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc128_TypeDef;
+
+typedef union{ /*!< rpc129 register definition*/
+ __IO uint32_t rpc129;
+ struct
+ {
+ __IO uint32_t oe_md_dqsn :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc129_TypeDef;
+
+typedef union{ /*!< rpc130 register definition*/
+ __IO uint32_t rpc130;
+ struct
+ {
+ __IO uint32_t oe_md_dqsp :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc130_TypeDef;
+
+typedef union{ /*!< rpc131 register definition*/
+ __IO uint32_t rpc131;
+ struct
+ {
+ __IO uint32_t pause_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc131_TypeDef;
+
+typedef union{ /*!< rpc132 register definition*/
+ __IO uint32_t rpc132;
+ struct
+ {
+ __IO uint32_t pause_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc132_TypeDef;
+
+typedef union{ /*!< rpc133 register definition*/
+ __IO uint32_t rpc133;
+ struct
+ {
+ __IO uint32_t qdr_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc133_TypeDef;
+
+typedef union{ /*!< rpc134 register definition*/
+ __IO uint32_t rpc134;
+ struct
+ {
+ __IO uint32_t qdr_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc134_TypeDef;
+
+typedef union{ /*!< rpc135 register definition*/
+ __IO uint32_t rpc135;
+ struct
+ {
+ __IO uint32_t qdr_md_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc135_TypeDef;
+
+typedef union{ /*!< rpc136 register definition*/
+ __IO uint32_t rpc136;
+ struct
+ {
+ __IO uint32_t qdr_md_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc136_TypeDef;
+
+typedef union{ /*!< rpc137 register definition*/
+ __IO uint32_t rpc137;
+ struct
+ {
+ __IO uint32_t qdr_md_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc137_TypeDef;
+
+typedef union{ /*!< rpc138 register definition*/
+ __IO uint32_t rpc138;
+ struct
+ {
+ __IO uint32_t qdr_md_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc138_TypeDef;
+
+typedef union{ /*!< rpc139 register definition*/
+ __IO uint32_t rpc139;
+ struct
+ {
+ __IO uint32_t qdr_md_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc139_TypeDef;
+
+typedef union{ /*!< rpc140 register definition*/
+ __IO uint32_t rpc140;
+ struct
+ {
+ __IO uint32_t qdr_md_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc140_TypeDef;
+
+typedef union{ /*!< rpc141 register definition*/
+ __IO uint32_t rpc141;
+ struct
+ {
+ __IO uint32_t rank2_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc141_TypeDef;
+
+typedef union{ /*!< rpc142 register definition*/
+ __IO uint32_t rpc142;
+ struct
+ {
+ __IO uint32_t rank2_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc142_TypeDef;
+
+typedef union{ /*!< rpc143 register definition*/
+ __IO uint32_t rpc143;
+ struct
+ {
+ __IO uint32_t rst_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc143_TypeDef;
+
+typedef union{ /*!< rpc144 register definition*/
+ __IO uint32_t rpc144;
+ struct
+ {
+ __IO uint32_t rst_inv_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc144_TypeDef;
+
+typedef union{ /*!< rpc145 register definition*/
+ __IO uint32_t rpc145;
+ struct
+ {
+ __IO uint32_t rxdly_addcmd :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc145_TypeDef;
+
+typedef union{ /*!< rpc146 register definition*/
+ __IO uint32_t rpc146;
+ struct
+ {
+ __IO uint32_t rxdly_clkn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc146_TypeDef;
+
+typedef union{ /*!< rpc147 register definition*/
+ __IO uint32_t rpc147;
+ struct
+ {
+ __IO uint32_t rxdly_clkp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc147_TypeDef;
+
+typedef union{ /*!< rpc148 register definition*/
+ __IO uint32_t rpc148;
+ struct
+ {
+ __IO uint32_t rxdly_dir_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc148_TypeDef;
+
+typedef union{ /*!< rpc149 register definition*/
+ __IO uint32_t rpc149;
+ struct
+ {
+ __IO uint32_t rxdly_dir_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc149_TypeDef;
+
+typedef union{ /*!< rpc150 register definition*/
+ __IO uint32_t rpc150;
+ struct
+ {
+ __IO uint32_t rxdly_dq :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc150_TypeDef;
+
+typedef union{ /*!< rpc151 register definition*/
+ __IO uint32_t rpc151;
+ struct
+ {
+ __IO uint32_t rxdly_dqsn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc151_TypeDef;
+
+typedef union{ /*!< rpc152 register definition*/
+ __IO uint32_t rpc152;
+ struct
+ {
+ __IO uint32_t rxdly_dqsp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc152_TypeDef;
+
+typedef union{ /*!< rpc153 register definition*/
+ __IO uint32_t rpc153;
+ struct
+ {
+ __IO uint32_t rxdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc153_TypeDef;
+
+typedef union{ /*!< rpc154 register definition*/
+ __IO uint32_t rpc154;
+ struct
+ {
+ __IO uint32_t rxdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc154_TypeDef;
+
+typedef union{ /*!< rpc155 register definition*/
+ __IO uint32_t rpc155;
+ struct
+ {
+ __IO uint32_t rxdly_offset_addcmd :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc155_TypeDef;
+
+typedef union{ /*!< rpc156 register definition*/
+ __IO uint32_t rpc156;
+ struct
+ {
+ __IO uint32_t rxdly_offset_data :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc156_TypeDef;
+
+typedef union{ /*!< rpc157 register definition*/
+ __IO uint32_t rpc157;
+ struct
+ {
+ __IO uint32_t rxdly_wide_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc157_TypeDef;
+
+typedef union{ /*!< rpc158 register definition*/
+ __IO uint32_t rpc158;
+ struct
+ {
+ __IO uint32_t rxdly_wide_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc158_TypeDef;
+
+typedef union{ /*!< rpc159 register definition*/
+ __IO uint32_t rpc159;
+ struct
+ {
+ __IO uint32_t rxdly_wide_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc159_TypeDef;
+
+typedef union{ /*!< rpc160 register definition*/
+ __IO uint32_t rpc160;
+ struct
+ {
+ __IO uint32_t rxdly_wide_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc160_TypeDef;
+
+typedef union{ /*!< rpc161 register definition*/
+ __IO uint32_t rpc161;
+ struct
+ {
+ __IO uint32_t rxdly_wide_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc161_TypeDef;
+
+typedef union{ /*!< rpc162 register definition*/
+ __IO uint32_t rpc162;
+ struct
+ {
+ __IO uint32_t rxdly_wide_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc162_TypeDef;
+
+typedef union{ /*!< rpc163 register definition*/
+ __IO uint32_t rpc163;
+ struct
+ {
+ __IO uint32_t rxmvdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc163_TypeDef;
+
+typedef union{ /*!< rpc164 register definition*/
+ __IO uint32_t rpc164;
+ struct
+ {
+ __IO uint32_t rxmvdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc164_TypeDef;
+
+typedef union{ /*!< rpc165 register definition*/
+ __IO uint32_t rpc165;
+ struct
+ {
+ __IO uint32_t rxptr_addcmd :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc165_TypeDef;
+
+typedef union{ /*!< rpc166 register definition*/
+ __IO uint32_t rpc166;
+ struct
+ {
+ __IO uint32_t rxptr_data :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc166_TypeDef;
+
+typedef union{ /*!< rpc167 register definition*/
+ __IO uint32_t rpc167;
+ struct
+ {
+ __IO uint32_t rx_md_addcmd :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc167_TypeDef;
+
+typedef union{ /*!< rpc168 register definition*/
+ __IO uint32_t rpc168;
+ struct
+ {
+ __IO uint32_t rx_md_clkn :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc168_TypeDef;
+
+typedef union{ /*!< rpc169 register definition*/
+ __IO uint32_t rpc169;
+ struct
+ {
+ __IO uint32_t rx_md_clkp :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc169_TypeDef;
+
+typedef union{ /*!< rpc170 register definition*/
+ __IO uint32_t rpc170;
+ struct
+ {
+ __IO uint32_t rx_md_dq :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc170_TypeDef;
+
+typedef union{ /*!< rpc171 register definition*/
+ __IO uint32_t rpc171;
+ struct
+ {
+ __IO uint32_t rx_md_dqsn :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc171_TypeDef;
+
+typedef union{ /*!< rpc172 register definition*/
+ __IO uint32_t rpc172;
+ struct
+ {
+ __IO uint32_t rx_md_dqsp :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc172_TypeDef;
+
+typedef union{ /*!< rpc173 register definition*/
+ __IO uint32_t rpc173;
+ struct
+ {
+ __IO uint32_t sclk0_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc173_TypeDef;
+
+typedef union{ /*!< rpc174 register definition*/
+ __IO uint32_t rpc174;
+ struct
+ {
+ __IO uint32_t sclk0_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc174_TypeDef;
+
+typedef union{ /*!< rpc175 register definition*/
+ __IO uint32_t rpc175;
+ struct
+ {
+ __IO uint32_t sclk0_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc175_TypeDef;
+
+typedef union{ /*!< rpc176 register definition*/
+ __IO uint32_t rpc176;
+ struct
+ {
+ __IO uint32_t sclk0_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc176_TypeDef;
+
+typedef union{ /*!< rpc177 register definition*/
+ __IO uint32_t rpc177;
+ struct
+ {
+ __IO uint32_t sclk0_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc177_TypeDef;
+
+typedef union{ /*!< rpc178 register definition*/
+ __IO uint32_t rpc178;
+ struct
+ {
+ __IO uint32_t sclk0_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc178_TypeDef;
+
+typedef union{ /*!< rpc179 register definition*/
+ __IO uint32_t rpc179;
+ struct
+ {
+ __IO uint32_t sclk0_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc179_TypeDef;
+
+typedef union{ /*!< rpc180 register definition*/
+ __IO uint32_t rpc180;
+ struct
+ {
+ __IO uint32_t sclk0_inv_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc180_TypeDef;
+
+typedef union{ /*!< rpc181 register definition*/
+ __IO uint32_t rpc181;
+ struct
+ {
+ __IO uint32_t sclk0_inv_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc181_TypeDef;
+
+typedef union{ /*!< rpc182 register definition*/
+ __IO uint32_t rpc182;
+ struct
+ {
+ __IO uint32_t sclk0_inv_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc182_TypeDef;
+
+typedef union{ /*!< rpc183 register definition*/
+ __IO uint32_t rpc183;
+ struct
+ {
+ __IO uint32_t sclk0_inv_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc183_TypeDef;
+
+typedef union{ /*!< rpc184 register definition*/
+ __IO uint32_t rpc184;
+ struct
+ {
+ __IO uint32_t sclk0_inv_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc184_TypeDef;
+
+typedef union{ /*!< rpc185 register definition*/
+ __IO uint32_t rpc185;
+ struct
+ {
+ __IO uint32_t sclk1_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc185_TypeDef;
+
+typedef union{ /*!< rpc186 register definition*/
+ __IO uint32_t rpc186;
+ struct
+ {
+ __IO uint32_t sclk1_en_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc186_TypeDef;
+
+typedef union{ /*!< rpc187 register definition*/
+ __IO uint32_t rpc187;
+ struct
+ {
+ __IO uint32_t sclk1_en_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc187_TypeDef;
+
+typedef union{ /*!< rpc188 register definition*/
+ __IO uint32_t rpc188;
+ struct
+ {
+ __IO uint32_t sclk1_en_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc188_TypeDef;
+
+typedef union{ /*!< rpc189 register definition*/
+ __IO uint32_t rpc189;
+ struct
+ {
+ __IO uint32_t sclk1_en_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc189_TypeDef;
+
+typedef union{ /*!< rpc190 register definition*/
+ __IO uint32_t rpc190;
+ struct
+ {
+ __IO uint32_t sclk1_en_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc190_TypeDef;
+
+typedef union{ /*!< rpc191 register definition*/
+ __IO uint32_t rpc191;
+ struct
+ {
+ __IO uint32_t sclk1_inv_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc191_TypeDef;
+
+typedef union{ /*!< rpc192 register definition*/
+ __IO uint32_t rpc192;
+ struct
+ {
+ __IO uint32_t sclk1_inv_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc192_TypeDef;
+
+typedef union{ /*!< rpc193 register definition*/
+ __IO uint32_t rpc193;
+ struct
+ {
+ __IO uint32_t sclk1_inv_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc193_TypeDef;
+
+typedef union{ /*!< rpc194 register definition*/
+ __IO uint32_t rpc194;
+ struct
+ {
+ __IO uint32_t sclk1_inv_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc194_TypeDef;
+
+typedef union{ /*!< rpc195 register definition*/
+ __IO uint32_t rpc195;
+ struct
+ {
+ __IO uint32_t sclk1_inv_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc195_TypeDef;
+
+typedef union{ /*!< rpc196 register definition*/
+ __IO uint32_t rpc196;
+ struct
+ {
+ __IO uint32_t sclk1_inv_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc196_TypeDef;
+
+typedef union{ /*!< rpc197 register definition*/
+ __IO uint32_t rpc197;
+ struct
+ {
+ __IO uint32_t soft_reset_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc197_TypeDef;
+
+typedef union{ /*!< rpc198 register definition*/
+ __IO uint32_t rpc198;
+ struct
+ {
+ __IO uint32_t soft_reset_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc198_TypeDef;
+
+typedef union{ /*!< rpc199 register definition*/
+ __IO uint32_t rpc199;
+ struct
+ {
+ __IO uint32_t spare_iog_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc199_TypeDef;
+
+typedef union{ /*!< rpc200 register definition*/
+ __IO uint32_t rpc200;
+ struct
+ {
+ __IO uint32_t spare_iog_clkn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc200_TypeDef;
+
+typedef union{ /*!< rpc201 register definition*/
+ __IO uint32_t rpc201;
+ struct
+ {
+ __IO uint32_t spare_iog_clkp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc201_TypeDef;
+
+typedef union{ /*!< rpc202 register definition*/
+ __IO uint32_t rpc202;
+ struct
+ {
+ __IO uint32_t spare_iog_dq :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc202_TypeDef;
+
+typedef union{ /*!< rpc203 register definition*/
+ __IO uint32_t rpc203;
+ struct
+ {
+ __IO uint32_t spare_iog_dqsn :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc203_TypeDef;
+
+typedef union{ /*!< rpc204 register definition*/
+ __IO uint32_t rpc204;
+ struct
+ {
+ __IO uint32_t spare_iog_dqsp :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc204_TypeDef;
+
+typedef union{ /*!< rpc205 register definition*/
+ __IO uint32_t rpc205;
+ struct
+ {
+ __IO uint32_t spio_sel_di_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc205_TypeDef;
+
+typedef union{ /*!< rpc206 register definition*/
+ __IO uint32_t rpc206;
+ struct
+ {
+ __IO uint32_t spio_sel_di_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc206_TypeDef;
+
+typedef union{ /*!< rpc207 register definition*/
+ __IO uint32_t rpc207;
+ struct
+ {
+ __IO uint32_t stop_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc207_TypeDef;
+
+typedef union{ /*!< rpc208 register definition*/
+ __IO uint32_t rpc208;
+ struct
+ {
+ __IO uint32_t stop_sel_data :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc208_TypeDef;
+
+typedef union{ /*!< rpc209 register definition*/
+ __IO uint32_t rpc209;
+ struct
+ {
+ __IO uint32_t txclk_sel_addcmd :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc209_TypeDef;
+
+typedef union{ /*!< rpc210 register definition*/
+ __IO uint32_t rpc210;
+ struct
+ {
+ __IO uint32_t txclk_sel_clkn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc210_TypeDef;
+
+typedef union{ /*!< rpc211 register definition*/
+ __IO uint32_t rpc211;
+ struct
+ {
+ __IO uint32_t txclk_sel_clkp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc211_TypeDef;
+
+typedef union{ /*!< rpc212 register definition*/
+ __IO uint32_t rpc212;
+ struct
+ {
+ __IO uint32_t txclk_sel_dq :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc212_TypeDef;
+
+typedef union{ /*!< rpc213 register definition*/
+ __IO uint32_t rpc213;
+ struct
+ {
+ __IO uint32_t txclk_sel_dqsn :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc213_TypeDef;
+
+typedef union{ /*!< rpc214 register definition*/
+ __IO uint32_t rpc214;
+ struct
+ {
+ __IO uint32_t txclk_sel_dqsp :2;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc214_TypeDef;
+
+typedef union{ /*!< rpc215 register definition*/
+ __IO uint32_t rpc215;
+ struct
+ {
+ __IO uint32_t txdly_addcmd :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc215_TypeDef;
+
+typedef union{ /*!< rpc216 register definition*/
+ __IO uint32_t rpc216;
+ struct
+ {
+ __IO uint32_t txdly_clkn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc216_TypeDef;
+
+typedef union{ /*!< rpc217 register definition*/
+ __IO uint32_t rpc217;
+ struct
+ {
+ __IO uint32_t txdly_clkp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc217_TypeDef;
+
+typedef union{ /*!< rpc218 register definition*/
+ __IO uint32_t rpc218;
+ struct
+ {
+ __IO uint32_t txdly_dir_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc218_TypeDef;
+
+typedef union{ /*!< rpc219 register definition*/
+ __IO uint32_t rpc219;
+ struct
+ {
+ __IO uint32_t txdly_dir_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc219_TypeDef;
+
+typedef union{ /*!< rpc220 register definition*/
+ __IO uint32_t rpc220;
+ struct
+ {
+ __IO uint32_t txdly_dq :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc220_TypeDef;
+
+typedef union{ /*!< rpc221 register definition*/
+ __IO uint32_t rpc221;
+ struct
+ {
+ __IO uint32_t txdly_dqsn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc221_TypeDef;
+
+typedef union{ /*!< rpc222 register definition*/
+ __IO uint32_t rpc222;
+ struct
+ {
+ __IO uint32_t txdly_dqsp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc222_TypeDef;
+
+typedef union{ /*!< rpc223 register definition*/
+ __IO uint32_t rpc223;
+ struct
+ {
+ __IO uint32_t txdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc223_TypeDef;
+
+typedef union{ /*!< rpc224 register definition*/
+ __IO uint32_t rpc224;
+ struct
+ {
+ __IO uint32_t txdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc224_TypeDef;
+
+typedef union{ /*!< rpc225 register definition*/
+ __IO uint32_t rpc225;
+ struct
+ {
+ __IO uint32_t txdly_offset_addcmd :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc225_TypeDef;
+
+typedef union{ /*!< rpc226 register definition*/
+ __IO uint32_t rpc226;
+ struct
+ {
+ __IO uint32_t txdly_offset_data :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc226_TypeDef;
+
+typedef union{ /*!< rpc227 register definition*/
+ __IO uint32_t rpc227;
+ struct
+ {
+ __IO uint32_t txmvdly_en_addcmd :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc227_TypeDef;
+
+typedef union{ /*!< rpc228 register definition*/
+ __IO uint32_t rpc228;
+ struct
+ {
+ __IO uint32_t txmvdly_en_data :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc228_TypeDef;
+
+typedef union{ /*!< rpc229 register definition*/
+ __IO uint32_t rpc229;
+ struct
+ {
+ __IO uint32_t tx_md_addcmd :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc229_TypeDef;
+
+typedef union{ /*!< rpc230 register definition*/
+ __IO uint32_t rpc230;
+ struct
+ {
+ __IO uint32_t tx_md_clkn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc230_TypeDef;
+
+typedef union{ /*!< rpc231 register definition*/
+ __IO uint32_t rpc231;
+ struct
+ {
+ __IO uint32_t tx_md_clkp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc231_TypeDef;
+
+typedef union{ /*!< rpc232 register definition*/
+ __IO uint32_t rpc232;
+ struct
+ {
+ __IO uint32_t tx_md_dq :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc232_TypeDef;
+
+typedef union{ /*!< rpc233 register definition*/
+ __IO uint32_t rpc233;
+ struct
+ {
+ __IO uint32_t tx_md_dqsn :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc233_TypeDef;
+
+typedef union{ /*!< rpc234 register definition*/
+ __IO uint32_t rpc234;
+ struct
+ {
+ __IO uint32_t tx_md_dqsp :7;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc234_TypeDef;
+
+typedef union{ /*!< rpc235 register definition*/
+ __IO uint32_t rpc235;
+ struct
+ {
+ __IO uint32_t wpd_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc235_TypeDef;
+
+typedef union{ /*!< rpc236 register definition*/
+ __IO uint32_t rpc236;
+ struct
+ {
+ __IO uint32_t wpd_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc236_TypeDef;
+
+typedef union{ /*!< rpc237 register definition*/
+ __IO uint32_t rpc237;
+ struct
+ {
+ __IO uint32_t wpd_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc237_TypeDef;
+
+typedef union{ /*!< rpc238 register definition*/
+ __IO uint32_t rpc238;
+ struct
+ {
+ __IO uint32_t wpd_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc238_TypeDef;
+
+typedef union{ /*!< rpc239 register definition*/
+ __IO uint32_t rpc239;
+ struct
+ {
+ __IO uint32_t wpd_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc239_TypeDef;
+
+typedef union{ /*!< rpc240 register definition*/
+ __IO uint32_t rpc240;
+ struct
+ {
+ __IO uint32_t wpd_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc240_TypeDef;
+
+typedef union{ /*!< rpc241 register definition*/
+ __IO uint32_t rpc241;
+ struct
+ {
+ __IO uint32_t wpd_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc241_TypeDef;
+
+typedef union{ /*!< rpc242 register definition*/
+ __IO uint32_t rpc242;
+ struct
+ {
+ __IO uint32_t wpd_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc242_TypeDef;
+
+typedef union{ /*!< rpc243 register definition*/
+ __IO uint32_t rpc243;
+ struct
+ {
+ __IO uint32_t wpu_addcmd0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc243_TypeDef;
+
+typedef union{ /*!< rpc244 register definition*/
+ __IO uint32_t rpc244;
+ struct
+ {
+ __IO uint32_t wpu_addcmd1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc244_TypeDef;
+
+typedef union{ /*!< rpc245 register definition*/
+ __IO uint32_t rpc245;
+ struct
+ {
+ __IO uint32_t wpu_addcmd2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc245_TypeDef;
+
+typedef union{ /*!< rpc246 register definition*/
+ __IO uint32_t rpc246;
+ struct
+ {
+ __IO uint32_t wpu_data0 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc246_TypeDef;
+
+typedef union{ /*!< rpc247 register definition*/
+ __IO uint32_t rpc247;
+ struct
+ {
+ __IO uint32_t wpu_data1 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc247_TypeDef;
+
+typedef union{ /*!< rpc248 register definition*/
+ __IO uint32_t rpc248;
+ struct
+ {
+ __IO uint32_t wpu_data2 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc248_TypeDef;
+
+typedef union{ /*!< rpc249 register definition*/
+ __IO uint32_t rpc249;
+ struct
+ {
+ __IO uint32_t wpu_data3 :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc249_TypeDef;
+
+typedef union{ /*!< rpc250 register definition*/
+ __IO uint32_t rpc250;
+ struct
+ {
+ __IO uint32_t wpu_ecc :12;
+ __I uint32_t reserved_01 :20;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rpc250_TypeDef;
+
+typedef union{ /*!< spio251 register definition*/
+ __IO uint32_t spio251;
+ struct
+ {
+ __IO uint32_t sel_refclk0 :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_spio251_TypeDef;
+
+typedef union{ /*!< spio252 register definition*/
+ __IO uint32_t spio252;
+ struct
+ {
+ __IO uint32_t sel_refclk1 :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_spio252_TypeDef;
+
+typedef union{ /*!< spio253 register definition*/
+ __IO uint32_t spio253;
+ struct
+ {
+ __IO uint32_t sel_refclk2 :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_spio253_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_TIP register definition*/
+ __IO uint32_t SOFT_RESET_TIP;
+ struct
+ {
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_NV_MAP_TIP_TypeDef NV_MAP_TIP :1;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_V_MAP_TIP_TypeDef V_MAP_TIP :1;
+ __I uint32_t reserved_01 :6;
+ __O CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_PERIPH_TIP_TypeDef PERIPH_TIP :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t BLOCKID_TIP :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_TypeDef;
+
+typedef union{ /*!< rank_select register definition*/
+ __IO uint32_t rank_select;
+ struct
+ {
+ __IO uint32_t rank :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_rank_select_TypeDef;
+
+typedef union{ /*!< lane_select register definition*/
+ __IO uint32_t lane_select;
+ struct
+ {
+ __IO uint32_t lane :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_lane_select_TypeDef;
+
+typedef union{ /*!< training_skip register definition*/
+ __IO uint32_t training_skip;
+ struct
+ {
+ __IO uint32_t skip_bclksclk :1;
+ __IO uint32_t skip_addcmd :1;
+ __IO uint32_t skip_wrlvl :1;
+ __IO uint32_t skip_rdgate :1;
+ __IO uint32_t skip_dq_dqs_opt :1;
+ __IO uint32_t skip_write_calibration :1;
+ __IO uint32_t skip_vref_mr6 :1;
+ __IO uint32_t step7 :1;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_skip_TypeDef;
+
+typedef union{ /*!< training_start register definition*/
+ __IO uint32_t training_start;
+ struct
+ {
+ __IO uint32_t start :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_start_TypeDef;
+
+typedef union{ /*!< training_status register definition*/
+ __I uint32_t training_status;
+ struct
+ {
+ __I uint32_t status :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_status_TypeDef;
+
+typedef union{ /*!< training_reset register definition*/
+ __IO uint32_t training_reset;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_training_reset_TypeDef;
+
+typedef union{ /*!< gt_err_comb register definition*/
+ __I uint32_t gt_err_comb;
+ struct
+ {
+ __I uint32_t error_comb_lanex :6;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_err_comb_TypeDef;
+
+typedef union{ /*!< gt_clk_sel register definition*/
+ __I uint32_t gt_clk_sel;
+ struct
+ {
+ __I uint32_t clk_sel_lanex_rankx :3;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_clk_sel_TypeDef;
+
+typedef union{ /*!< gt_txdly register definition*/
+ __I uint32_t gt_txdly;
+ struct
+ {
+ __I uint32_t txdly0_lanex :8;
+ __I uint32_t txdly1_lanex :8;
+ __I uint32_t txdly2_lanex :8;
+ __I uint32_t txdly3_lanex :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_txdly_TypeDef;
+
+typedef union{ /*!< gt_steps_180 register definition*/
+ __I uint32_t gt_steps_180;
+ struct
+ {
+ __I uint32_t steps_180_lanex_rankx :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_steps_180_TypeDef;
+
+typedef union{ /*!< gt_state register definition*/
+ __I uint32_t gt_state;
+ struct
+ {
+ __I uint32_t gt_state_lanex :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_gt_state_TypeDef;
+
+typedef union{ /*!< wl_delay_0 register definition*/
+ __I uint32_t wl_delay_0;
+ struct
+ {
+ __I uint32_t wldelay_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_wl_delay_0_TypeDef;
+
+typedef union{ /*!< dq_dqs_err_done register definition*/
+ __I uint32_t dq_dqs_err_done;
+ struct
+ {
+ __I uint32_t dq_dqs_error_done_lanex_rankx :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dq_dqs_err_done_TypeDef;
+
+typedef union{ /*!< dqdqs_window register definition*/
+ __I uint32_t dqdqs_window;
+ struct
+ {
+ __I uint32_t ils_lanex_rankx :8;
+ __I uint32_t irs_lanex_rankx :8;
+ __I uint32_t reserved_01 :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_window_TypeDef;
+
+typedef union{ /*!< dqdqs_state register definition*/
+ __I uint32_t dqdqs_state;
+ struct
+ {
+ __I uint32_t state_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_state_TypeDef;
+
+typedef union{ /*!< delta0 register definition*/
+ __I uint32_t delta0;
+ struct
+ {
+ __I uint32_t delay0_lanex :8;
+ __I uint32_t delay1_lanex :8;
+ __I uint32_t delay2_lanex :8;
+ __I uint32_t delay3_lanex :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_delta0_TypeDef;
+
+typedef union{ /*!< delta1 register definition*/
+ __I uint32_t delta1;
+ struct
+ {
+ __I uint32_t delay4_lanex :8;
+ __I uint32_t delay5_lanex :8;
+ __I uint32_t delay6_lanex :8;
+ __I uint32_t delay7_lanex :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_delta1_TypeDef;
+
+typedef union{ /*!< dqdqs_status0 register definition*/
+ __I uint32_t dqdqs_status0;
+ struct
+ {
+ __I uint32_t init_dly_lanex :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status0_TypeDef;
+
+typedef union{ /*!< dqdqs_status1 register definition*/
+ __I uint32_t dqdqs_status1;
+ struct
+ {
+ __I uint32_t dqs_dly_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status1_TypeDef;
+
+typedef union{ /*!< dqdqs_status2 register definition*/
+ __I uint32_t dqdqs_status2;
+ struct
+ {
+ __I uint32_t bit_width_lanex :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status2_TypeDef;
+
+typedef union{ /*!< dqdqs_status3 register definition*/
+ __I uint32_t dqdqs_status3;
+ struct
+ {
+ __I uint32_t initldqs_2_mid_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status3_TypeDef;
+
+typedef union{ /*!< dqdqs_status4 register definition*/
+ __I uint32_t dqdqs_status4;
+ struct
+ {
+ __I uint32_t mid_2_initldqs_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status4_TypeDef;
+
+typedef union{ /*!< dqdqs_status5 register definition*/
+ __I uint32_t dqdqs_status5;
+ struct
+ {
+ __I uint32_t stw_2_initldqs_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status5_TypeDef;
+
+typedef union{ /*!< dqdqs_status6 register definition*/
+ __I uint32_t dqdqs_status6;
+ struct
+ {
+ __I uint32_t initldqs_2_stw_lanex_rankx :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_status6_TypeDef;
+
+typedef union{ /*!< addcmd_status0 register definition*/
+ __I uint32_t addcmd_status0;
+ struct
+ {
+ __I uint32_t delay_vcophs_sel0 :8;
+ __I uint32_t delay_vcophs_sel1 :8;
+ __I uint32_t delay_vcophs_sel2 :8;
+ __I uint32_t delay_vcophs_sel3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_addcmd_status0_TypeDef;
+
+typedef union{ /*!< addcmd_status1 register definition*/
+ __I uint32_t addcmd_status1;
+ struct
+ {
+ __I uint32_t delay_vcophs_sel4 :8;
+ __I uint32_t delay_vcophs_sel5 :8;
+ __I uint32_t delay_vcophs_sel6 :8;
+ __I uint32_t delay_vcophs_sel7 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_addcmd_status1_TypeDef;
+
+typedef union{ /*!< addcmd_answer register definition*/
+ __I uint32_t addcmd_answer;
+ struct
+ {
+ __I uint32_t vcophs_sel_after_training :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_addcmd_answer_TypeDef;
+
+typedef union{ /*!< bclksclk_answer register definition*/
+ __I uint32_t bclksclk_answer;
+ struct
+ {
+ __I uint32_t bclk0_vcophs_sel :4;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_bclksclk_answer_TypeDef;
+
+typedef union{ /*!< dqdqs_wrcalib_offset register definition*/
+ __I uint32_t dqdqs_wrcalib_offset;
+ struct
+ {
+ __I uint32_t wrcalib_offset_lanex :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_dqdqs_wrcalib_offset_TypeDef;
+
+typedef union{ /*!< expert_mode_en register definition*/
+ __IO uint32_t expert_mode_en;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_en :1;
+ __IO uint32_t dyn_ovr_pllcnt_en :1;
+ __IO uint32_t dyn_ovr_rdgate_en :1;
+ __IO uint32_t dyn_ovr_wrcalib_en :1;
+ __IO uint32_t dyn_ovr_calif_en :1;
+ __IO uint32_t dyn_ovr_dfi_shim_en :1;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_mode_en_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_move_reg0 register definition*/
+ __IO uint32_t expert_dlycnt_move_reg0;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_move0 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_move1 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_move2 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_move3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_move_reg1 register definition*/
+ __IO uint32_t expert_dlycnt_move_reg1;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_move4 :4;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_move4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_move4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_move4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_catrn_move :1;
+ __IO uint32_t dyn_ovr_dlycnt_ca_move :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_direction_reg0 register definition*/
+ __IO uint32_t expert_dlycnt_direction_reg0;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction0 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction1 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction2 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_direction_reg1 register definition*/
+ __IO uint32_t expert_dlycnt_direction_reg1;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_direction4 :4;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_direction4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_direction4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_direction4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_catrn_direction :1;
+ __IO uint32_t dyn_ovr_dlycnt_ca_direction :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_load_reg0 register definition*/
+ __IO uint32_t expert_dlycnt_load_reg0;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_load0 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_load1 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_load2 :8;
+ __IO uint32_t dyn_ovr_dlycnt_dq_load3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_load_reg1 register definition*/
+ __IO uint32_t expert_dlycnt_load_reg1;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_dq_load4 :4;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_load4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw270_load4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_dqsw_load4 :1;
+ __IO uint32_t dyn_ovr_dlycnt_catrn_load :1;
+ __IO uint32_t dyn_ovr_dlycnt_ca_load :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_oor_reg0 register definition*/
+ __I uint32_t expert_dlycnt_oor_reg0;
+ struct
+ {
+ __I uint32_t dyn_ovr_dlycnt_dq_oor0 :8;
+ __I uint32_t dyn_ovr_dlycnt_dq_oor1 :8;
+ __I uint32_t dyn_ovr_dlycnt_dq_oor2 :8;
+ __I uint32_t dyn_ovr_dlycnt_dq_oor3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg0_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_oor_reg1 register definition*/
+ __I uint32_t expert_dlycnt_oor_reg1;
+ struct
+ {
+ __I uint32_t dyn_ovr_dlycnt_dq_oor4 :4;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor0 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor1 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor2 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor3 :1;
+ __I uint32_t dyn_ovr_dlycnt_lanectrl_oor4 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor0 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor1 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor2 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor3 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw270_oor4 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor0 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor1 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor2 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor3 :1;
+ __I uint32_t dyn_ovr_dlycnt_dqsw_oor4 :1;
+ __I uint32_t dyn_ovr_dlycnt_catrn_oor :1;
+ __I uint32_t dyn_ovr_dlycnt_ca_oor :1;
+ __I uint32_t reserved_01 :11;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg1_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_mv_rd_dly_reg register definition*/
+ __IO uint32_t expert_dlycnt_mv_rd_dly_reg;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_mv_rd_dly4 :1;
+ __I uint32_t reserved_01 :27;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_mv_rd_dly_reg_TypeDef;
+
+typedef union{ /*!< expert_dlycnt_pause register definition*/
+ __IO uint32_t expert_dlycnt_pause;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_addcmd :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data0 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data1 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data2 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data3 :1;
+ __IO uint32_t dyn_ovr_dlycnt_lanectrl_pause_data4 :1;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dlycnt_pause_TypeDef;
+
+typedef union{ /*!< expert_pllcnt register definition*/
+ __IO uint32_t expert_pllcnt;
+ struct
+ {
+ __IO uint32_t dyn_ovr_dlycnt_rotate :1;
+ __IO uint32_t dyn_ovr_dlycnt_direction :1;
+ __IO uint32_t dyn_ovr_dlycnt_loadphs_b :1;
+ __IO uint32_t dyn_ovr_dlycnt_phsel :4;
+ __I uint32_t reserved_01 :25;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_pllcnt_TypeDef;
+
+typedef union{ /*!< expert_dqlane_readback register definition*/
+ __I uint32_t expert_dqlane_readback;
+ struct
+ {
+ __I uint32_t dq_or :5;
+ __I uint32_t dq_and :5;
+ __I uint32_t burst_valid :5;
+ __I uint32_t reserved_01 :17;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dqlane_readback_TypeDef;
+
+typedef union{ /*!< expert_addcmd_ln_readback register definition*/
+ __I uint32_t expert_addcmd_ln_readback;
+ struct
+ {
+ __I uint32_t rx_refclk :8;
+ __I uint32_t rx_addcmd :4;
+ __I uint32_t rx_bclksclk :2;
+ __I uint32_t reserved_01 :18;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_addcmd_ln_readback_TypeDef;
+
+typedef union{ /*!< expert_read_gate_controls register definition*/
+ __IO uint32_t expert_read_gate_controls;
+ struct
+ {
+ __IO uint32_t dyn_ovr_rdgate_clksel :10;
+ __IO uint32_t dyn_ovr_rdgate_steps180 :20;
+ __I uint32_t reserved_01 :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_read_gate_controls_TypeDef;
+
+typedef union{ /*!< expert_dq_dqs_optimization0 register definition*/
+ __I uint32_t expert_dq_dqs_optimization0;
+ struct
+ {
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane0 :8;
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane1 :8;
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane2 :8;
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization0_TypeDef;
+
+typedef union{ /*!< expert_dq_dqs_optimization1 register definition*/
+ __I uint32_t expert_dq_dqs_optimization1;
+ struct
+ {
+ __I uint32_t dyn_ovr_dqdqs_data_match_lane4 :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization1_TypeDef;
+
+typedef union{ /*!< expert_wrcalib register definition*/
+ __IO uint32_t expert_wrcalib;
+ struct
+ {
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane0 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane1 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane2 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane3 :4;
+ __IO uint32_t dyn_ovr_wrcalib_offset_lane4 :4;
+ __I uint32_t reserved_01 :12;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_wrcalib_TypeDef;
+
+typedef union{ /*!< expert_calif register definition*/
+ __IO uint32_t expert_calif;
+ struct
+ {
+ __IO uint32_t dyn_ovr_calif_read :1;
+ __IO uint32_t dyn_ovr_calif_write :1;
+ __IO uint32_t dyn_ovr_pattern_sel :4;
+ __I uint32_t reserved_01 :26;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_calif_TypeDef;
+
+typedef union{ /*!< expert_calif_readback register definition*/
+ __I uint32_t expert_calif_readback;
+ struct
+ {
+ __I uint32_t wrcalib_pattern_match_lane0 :8;
+ __I uint32_t wrcalib_pattern_match_lane1 :8;
+ __I uint32_t wrcalib_pattern_match_lane2 :8;
+ __I uint32_t wrcalib_pattern_match_lane3 :8;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_calif_readback_TypeDef;
+
+typedef union{ /*!< expert_calif_readback1 register definition*/
+ __I uint32_t expert_calif_readback1;
+ struct
+ {
+ __I uint32_t wrcalib_pattern_match_lane4 :8;
+ __I uint32_t reserved_01 :24;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_calif_readback1_TypeDef;
+
+typedef union{ /*!< expert_dfi_status_override_to_shim register definition*/
+ __IO uint32_t expert_dfi_status_override_to_shim;
+ struct
+ {
+ __IO uint32_t dfi_init_complete_shim :1;
+ __IO uint32_t dfi_training_complete_shim :1;
+ __IO uint32_t dfi_wrlvl_en_shim :1;
+ __IO uint32_t dfi_rdlvl_en_shim :1;
+ __IO uint32_t dfi_rdlvl_gate_en_shim :1;
+ __I uint32_t reserved_01 :27;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_expert_dfi_status_override_to_shim_TypeDef;
+
+typedef union{ /*!< tip_cfg_params register definition*/
+ __IO uint32_t tip_cfg_params;
+ struct
+ {
+ __IO uint32_t addcmd_offset :3;
+ __IO uint32_t bcklsclk_offset :3;
+ __IO uint32_t wrcalib_write_count :7;
+ __IO uint32_t read_gate_min_reads :9;
+ __IO uint32_t addrcmd_wait_count :9;
+ __I uint32_t reserved_01 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_tip_cfg_params_TypeDef;
+
+typedef union{ /*!< tip_vref_param register definition*/
+ __IO uint32_t tip_vref_param;
+ struct
+ {
+ __IO uint32_t vref_override :1;
+ __IO uint32_t data_vref :8;
+ __IO uint32_t ca_vref :8;
+ __I uint32_t reserved_01 :15;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_tip_vref_param_TypeDef;
+
+typedef union{ /*!< lane_alignment_fifo_control register definition*/
+ __IO uint32_t lane_alignment_fifo_control;
+ struct
+ {
+ __IO uint32_t block_fifo :1;
+ __IO uint32_t fifo_reset_n :1;
+ __I uint32_t reserved_01 :30;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_lane_alignment_fifo_control_TypeDef;
+
+typedef union{ /*!< SOFT_RESET_SGMII register definition*/
+ __IO uint32_t SOFT_RESET_SGMII;
+ struct
+ {
+ __O uint32_t nv_map_SGMII :1;
+ __O uint32_t v_map_SGMII :1;
+ __I uint32_t reserved_01 :6;
+ __O uint32_t periph_SGMII :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t blockid_SGMII :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SOFT_RESET_SGMII_TypeDef;
+
+typedef union{ /*!< SGMII_MODE register definition*/
+ __IO uint32_t SGMII_MODE;
+ struct
+ {
+ __IO uint32_t reg_pll_en :1;
+ __IO uint32_t reg_dll_en :1;
+ __IO uint32_t reg_pvt_en :1;
+ __IO uint32_t reg_bc_vrgen_en :1;
+ __IO uint32_t reg_tx0_en :1;
+ __IO uint32_t reg_rx0_en :1;
+ __IO uint32_t reg_tx1_en :1;
+ __IO uint32_t reg_rx1_en :1;
+ __IO uint32_t reg_dll_lock_flt :2;
+ __IO uint32_t reg_dll_adj_code :4;
+ __IO uint32_t reg_rx0_cdr_reset_b :1;
+ __IO uint32_t reg_rx1_cdr_reset_b :1;
+ __IO uint32_t reg_bc_vrgen :6;
+ __IO uint32_t reg_cdr_move_step :1;
+ __IO uint32_t reg_refclk_en_rdiff :1;
+ __IO uint32_t reg_bc_vs :4;
+ __IO uint32_t reg_refclk_en_udrive_p :1;
+ __IO uint32_t reg_refclk_en_ins_hyst_p :1;
+ __IO uint32_t reg_refclk_en_udrive_n :1;
+ __IO uint32_t reg_refclk_en_ins_hyst_n :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SGMII_MODE_TypeDef;
+
+typedef union{ /*!< PLL_CNTL register definition*/
+ __IO uint32_t PLL_CNTL;
+ struct
+ {
+ __IO uint32_t reg_pll_postdiv :7;
+ __I uint32_t aro_pll0_lock :1;
+ __IO uint32_t reg_pll_rfdiv :6;
+ __IO uint32_t reg_pll_reg_rfclk_sel :1;
+ __IO uint32_t reg_pll_lp_requires_lock :1;
+ __IO uint32_t reg_pll_intin :12;
+ __IO uint32_t reg_pll_bwi :2;
+ __IO uint32_t reg_pll_bwp :2;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PLL_CNTL_TypeDef;
+
+typedef union{ /*!< CH0_CNTL register definition*/
+ __IO uint32_t CH0_CNTL;
+ struct
+ {
+ __IO uint32_t reg_tx0_wpu_p :1;
+ __IO uint32_t reg_tx0_wpd_p :1;
+ __IO uint32_t reg_tx0_slew_p :2;
+ __IO uint32_t reg_tx0_drv_p :4;
+ __IO uint32_t reg_tx0_odt_p :4;
+ __IO uint32_t reg_tx0_odt_static_p :3;
+ __IO uint32_t reg_rx0_tim_long :1;
+ __IO uint32_t reg_rx0_wpu_p :1;
+ __IO uint32_t reg_rx0_wpd_p :1;
+ __IO uint32_t reg_rx0_ibufmd_p :3;
+ __IO uint32_t reg_rx0_eyewidth_p :3;
+ __IO uint32_t reg_rx0_odt_p :4;
+ __IO uint32_t reg_rx0_odt_static_p :3;
+ __I uint32_t reserved_01 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_CH0_CNTL_TypeDef;
+
+typedef union{ /*!< CH1_CNTL register definition*/
+ __IO uint32_t CH1_CNTL;
+ struct
+ {
+ __IO uint32_t reg_tx1_wpu_p :1;
+ __IO uint32_t reg_tx1_wpd_p :1;
+ __IO uint32_t reg_tx1_slew_p :2;
+ __IO uint32_t reg_tx1_drv_p :4;
+ __IO uint32_t reg_tx1_odt_p :4;
+ __IO uint32_t reg_tx1_odt_static_p :3;
+ __IO uint32_t reg_rx1_tim_long :1;
+ __IO uint32_t reg_rx1_wpu_p :1;
+ __IO uint32_t reg_rx1_wpd_p :1;
+ __IO uint32_t reg_rx1_ibufmd_p :3;
+ __IO uint32_t reg_rx1_eyewidth_p :3;
+ __IO uint32_t reg_rx1_odt_p :4;
+ __IO uint32_t reg_rx1_odt_static_p :3;
+ __I uint32_t reserved_01 :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_CH1_CNTL_TypeDef;
+
+typedef union{ /*!< RECAL_CNTL register definition*/
+ __IO uint32_t RECAL_CNTL;
+ struct
+ {
+ __IO uint32_t reg_recal_diff_range :5;
+ __IO uint32_t reg_recal_start_en :1;
+ __IO uint32_t reg_pvt_calib_start :1;
+ __IO uint32_t reg_pvt_calib_lock :1;
+ __IO uint32_t reg_recal_upd :1;
+ __IO uint32_t bc_vrgen_direction :1;
+ __IO uint32_t bc_vrgen_load :1;
+ __IO uint32_t bc_vrgen_move :1;
+ __IO uint32_t reg_pvt_reg_calib_clkdiv :2;
+ __IO uint32_t reg_pvt_reg_calib_diffr_vsel :2;
+ __I uint32_t sro_dll_90_code :7;
+ __I uint32_t sro_dll_lock :1;
+ __I uint32_t sro_dll_st_code :7;
+ __I uint32_t sro_recal_start :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_RECAL_CNTL_TypeDef;
+
+typedef union{ /*!< CLK_CNTL register definition*/
+ __IO uint32_t CLK_CNTL;
+ struct
+ {
+ __IO uint32_t reg_refclk_en_term_p :2;
+ __IO uint32_t reg_refclk_en_rxmode_p :2;
+ __IO uint32_t reg_refclk_en_term_n :2;
+ __IO uint32_t reg_refclk_en_rxmode_n :2;
+ __IO uint32_t reg_refclk_clkbuf_en_pullup :1;
+ __IO uint32_t reg_clkmux_fclk_sel :3;
+ __IO uint32_t reg_clkmux_pll0_rfclk0_sel :2;
+ __IO uint32_t reg_clkmux_pll0_rfclk1_sel :2;
+ __IO uint32_t reg_clkmux_spare0 :16;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_CLK_CNTL_TypeDef;
+
+typedef union{ /*!< DYN_CNTL register definition*/
+ __IO uint32_t DYN_CNTL;
+ struct
+ {
+ __IO uint32_t reg_pll_dynen :1;
+ __IO uint32_t reg_dll_dynen :1;
+ __IO uint32_t reg_pvt_dynen :1;
+ __IO uint32_t reg_bc_dynen :1;
+ __IO uint32_t reg_clkmux_dynen :1;
+ __IO uint32_t reg_lane0_dynen :1;
+ __IO uint32_t reg_lane1_dynen :1;
+ __I uint32_t bc_vrgen_oor :1;
+ __IO uint32_t reg_pll_soft_reset_periph :1;
+ __IO uint32_t reg_dll_soft_reset_periph :1;
+ __IO uint32_t reg_pvt_soft_reset_periph :1;
+ __IO uint32_t reg_bc_soft_reset_periph :1;
+ __IO uint32_t reg_clkmux_soft_reset_periph :1;
+ __IO uint32_t reg_lane0_soft_reset_periph :1;
+ __IO uint32_t reg_lane1_soft_reset_periph :1;
+ __I uint32_t pvt_calib_status :1;
+ __I uint32_t aro_pll0_vco0ph_sel :3;
+ __I uint32_t aro_pll0_vco1ph_sel :3;
+ __I uint32_t aro_pll0_vco2ph_sel :3;
+ __I uint32_t aro_pll0_vco3ph_sel :3;
+ __I uint32_t aro_ref_diffr :4;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_DYN_CNTL_TypeDef;
+
+typedef union{ /*!< PVT_STAT register definition*/
+ __IO uint32_t PVT_STAT;
+ struct
+ {
+ __I uint32_t aro_ref_pcode :6;
+ __I uint32_t aro_ioen_bnk :1;
+ __I uint32_t aro_ioen_bnk_b :1;
+ __I uint32_t aro_ref_ncode :6;
+ __I uint32_t aro_calib_status :1;
+ __I uint32_t aro_calib_status_b :1;
+ __I uint32_t aro_pcode :6;
+ __I uint32_t aro_calib_intrpt :1;
+ __I uint32_t pvt_calib_intrpt :1;
+ __I uint32_t aro_ncode :6;
+ __IO uint32_t pvt_calib_lock :1;
+ __IO uint32_t pvt_calib_start :1;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_PVT_STAT_TypeDef;
+
+typedef union{ /*!< SPARE_CNTL register definition*/
+ __IO uint32_t SPARE_CNTL;
+ struct
+ {
+ __IO uint32_t reg_spare :32;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SPARE_CNTL_TypeDef;
+
+typedef union{ /*!< SPARE_STAT register definition*/
+ __I uint32_t SPARE_STAT;
+ struct
+ {
+ __I uint32_t sro_spare :32;
+ } bitfield;
+} CFG_DDR_SGMII_PHY_SPARE_STAT_TypeDef;
+
+/*------------ CFG_DDR_SGMII_PHY definition -----------*/
+typedef struct
+{
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DDR_PHY_TypeDef SOFT_RESET_DDR_PHY; /*!< Offset: 0x0 */
+ __IO CFG_DDR_SGMII_PHY_DDRPHY_MODE_TypeDef DDRPHY_MODE; /*!< Offset: 0x4 */
+ __IO CFG_DDR_SGMII_PHY_DDRPHY_STARTUP_TypeDef DDRPHY_STARTUP; /*!< Offset: 0x8 */
+ __IO uint32_t UNUSED_SPACE0[29]; /*!< Offset: 0xc */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_MAIN_PLL_TypeDef SOFT_RESET_MAIN_PLL; /*!< Offset: 0x80 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL_MAIN_TypeDef PLL_CTRL_MAIN; /*!< Offset: 0x84 */
+ __IO CFG_DDR_SGMII_PHY_PLL_REF_FB_MAIN_TypeDef PLL_REF_FB_MAIN; /*!< Offset: 0x88 */
+ __I CFG_DDR_SGMII_PHY_PLL_FRACN_MAIN_TypeDef PLL_FRACN_MAIN; /*!< Offset: 0x8c */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_0_1_MAIN_TypeDef PLL_DIV_0_1_MAIN; /*!< Offset: 0x90 */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_2_3_MAIN_TypeDef PLL_DIV_2_3_MAIN; /*!< Offset: 0x94 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL2_MAIN_TypeDef PLL_CTRL2_MAIN; /*!< Offset: 0x98 */
+ __I CFG_DDR_SGMII_PHY_PLL_CAL_MAIN_TypeDef PLL_CAL_MAIN; /*!< Offset: 0x9c */
+ __IO CFG_DDR_SGMII_PHY_PLL_PHADJ_MAIN_TypeDef PLL_PHADJ_MAIN; /*!< Offset: 0xa0 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_0_MAIN_TypeDef SSCG_REG_0_MAIN; /*!< Offset: 0xa4 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_1_MAIN_TypeDef SSCG_REG_1_MAIN; /*!< Offset: 0xa8 */
+ __IO CFG_DDR_SGMII_PHY_SSCG_REG_2_MAIN_TypeDef SSCG_REG_2_MAIN; /*!< Offset: 0xac */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_3_MAIN_TypeDef SSCG_REG_3_MAIN; /*!< Offset: 0xb0 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_MAIN_PLL_TypeDef RPC_RESET_MAIN_PLL; /*!< Offset: 0xb4 */
+ __I uint32_t UNUSED_SPACE1[18]; /*!< Offset: 0xb8 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_IOSCB_PLL_TypeDef SOFT_RESET_IOSCB_PLL; /*!< Offset: 0x100 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL_IOSCB_TypeDef PLL_CTRL_IOSCB; /*!< Offset: 0x104 */
+ __IO CFG_DDR_SGMII_PHY_PLL_REF_FB_IOSCB_TypeDef PLL_REF_FB_IOSCB; /*!< Offset: 0x108 */
+ __I CFG_DDR_SGMII_PHY_PLL_FRACN_IOSCB_TypeDef PLL_FRACN_IOSCB; /*!< Offset: 0x10c */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_0_1_IOSCB_TypeDef PLL_DIV_0_1_IOSCB; /*!< Offset: 0x110 */
+ __IO CFG_DDR_SGMII_PHY_PLL_DIV_2_3_IOSCB_TypeDef PLL_DIV_2_3_IOSCB; /*!< Offset: 0x114 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CTRL2_IOSCB_TypeDef PLL_CTRL2_IOSCB; /*!< Offset: 0x118 */
+ __I CFG_DDR_SGMII_PHY_PLL_CAL_IOSCB_TypeDef PLL_CAL_IOSCB; /*!< Offset: 0x11c */
+ __IO CFG_DDR_SGMII_PHY_PLL_PHADJ_IOSCB_TypeDef PLL_PHADJ_IOSCB; /*!< Offset: 0x120 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_0_IOSCB_TypeDef SSCG_REG_0_IOSCB; /*!< Offset: 0x124 */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_1_IOSCB_TypeDef SSCG_REG_1_IOSCB; /*!< Offset: 0x128 */
+ __IO CFG_DDR_SGMII_PHY_SSCG_REG_2_IOSCB_TypeDef SSCG_REG_2_IOSCB; /*!< Offset: 0x12c */
+ __I CFG_DDR_SGMII_PHY_SSCG_REG_3_IOSCB_TypeDef SSCG_REG_3_IOSCB; /*!< Offset: 0x130 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_IOSCB_TypeDef RPC_RESET_IOSCB; /*!< Offset: 0x134 */
+ __I uint32_t UNUSED_SPACE2[18]; /*!< Offset: 0x138 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_BANK_CTRL_TypeDef SOFT_RESET_BANK_CTRL; /*!< Offset: 0x180 */
+ __IO CFG_DDR_SGMII_PHY_DPC_BITS_TypeDef DPC_BITS; /*!< Offset: 0x184 */
+ __I CFG_DDR_SGMII_PHY_BANK_STATUS_TypeDef BANK_STATUS; /*!< Offset: 0x188 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_BANK_CTRL_TypeDef RPC_RESET_BANK_CTRL; /*!< Offset: 0x18c */
+ __I uint32_t UNUSED_SPACE3[28]; /*!< Offset: 0x190 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_IOCALIB_TypeDef SOFT_RESET_IOCALIB; /*!< Offset: 0x200 */
+ __IO CFG_DDR_SGMII_PHY_IOC_REG0_TypeDef IOC_REG0; /*!< Offset: 0x204 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG1_TypeDef IOC_REG1; /*!< Offset: 0x208 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG2_TypeDef IOC_REG2; /*!< Offset: 0x20c */
+ __I CFG_DDR_SGMII_PHY_IOC_REG3_TypeDef IOC_REG3; /*!< Offset: 0x210 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG4_TypeDef IOC_REG4; /*!< Offset: 0x214 */
+ __I CFG_DDR_SGMII_PHY_IOC_REG5_TypeDef IOC_REG5; /*!< Offset: 0x218 */
+ __IO CFG_DDR_SGMII_PHY_IOC_REG6_TypeDef IOC_REG6; /*!< Offset: 0x21c */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_IOCALIB_TypeDef RPC_RESET_IOCALIB; /*!< Offset: 0x220 */
+ __IO CFG_DDR_SGMII_PHY_rpc_calib_TypeDef rpc_calib; /*!< Offset: 0x224 */
+ __I uint32_t UNUSED_SPACE4[22]; /*!< Offset: 0x228 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_CFM_TypeDef SOFT_RESET_CFM; /*!< Offset: 0x280 */
+ __IO CFG_DDR_SGMII_PHY_BCLKMUX_TypeDef BCLKMUX; /*!< Offset: 0x284 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CKMUX_TypeDef PLL_CKMUX; /*!< Offset: 0x288 */
+ __IO CFG_DDR_SGMII_PHY_MSSCLKMUX_TypeDef MSSCLKMUX; /*!< Offset: 0x28c */
+ __IO CFG_DDR_SGMII_PHY_SPARE0_TypeDef SPARE0; /*!< Offset: 0x290 */
+ __I CFG_DDR_SGMII_PHY_FMETER_ADDR_TypeDef FMETER_ADDR; /*!< Offset: 0x294 */
+ __I CFG_DDR_SGMII_PHY_FMETER_DATAW_TypeDef FMETER_DATAW; /*!< Offset: 0x298 */
+ __I CFG_DDR_SGMII_PHY_FMETER_DATAR_TypeDef FMETER_DATAR; /*!< Offset: 0x29c */
+ __I CFG_DDR_SGMII_PHY_TEST_CTRL_TypeDef TEST_CTRL; /*!< Offset: 0x2a0 */
+ __IO CFG_DDR_SGMII_PHY_RPC_RESET_CFM_TypeDef RPC_RESET_CFM; /*!< Offset: 0x2a4 */
+ __I uint32_t UNUSED_SPACE5[22]; /*!< Offset: 0x2a8 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_DRIVER_TypeDef SOFT_RESET_DECODER_DRIVER; /*!< Offset: 0x300 */
+ __IO CFG_DDR_SGMII_PHY_rpc1_DRV_TypeDef rpc1_DRV; /*!< Offset: 0x304 */
+ __IO CFG_DDR_SGMII_PHY_rpc2_DRV_TypeDef rpc2_DRV; /*!< Offset: 0x308 */
+ __IO CFG_DDR_SGMII_PHY_rpc3_DRV_TypeDef rpc3_DRV; /*!< Offset: 0x30c */
+ __IO CFG_DDR_SGMII_PHY_rpc4_DRV_TypeDef rpc4_DRV; /*!< Offset: 0x310 */
+ __I uint32_t UNUSED_SPACE6[27]; /*!< Offset: 0x314 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_ODT_TypeDef SOFT_RESET_DECODER_ODT; /*!< Offset: 0x380 */
+ __IO CFG_DDR_SGMII_PHY_rpc1_ODT_TypeDef rpc1_ODT; /*!< Offset: 0x384 */
+ __IO CFG_DDR_SGMII_PHY_rpc2_ODT_TypeDef rpc2_ODT; /*!< Offset: 0x388 */
+ __IO CFG_DDR_SGMII_PHY_rpc3_ODT_TypeDef rpc3_ODT; /*!< Offset: 0x38c */
+ __IO CFG_DDR_SGMII_PHY_rpc4_ODT_TypeDef rpc4_ODT; /*!< Offset: 0x390 */
+ __IO CFG_DDR_SGMII_PHY_rpc5_ODT_TypeDef rpc5_ODT; /*!< Offset: 0x394 */
+ __IO CFG_DDR_SGMII_PHY_rpc6_ODT_TypeDef rpc6_ODT; /*!< Offset: 0x398 */
+ __IO CFG_DDR_SGMII_PHY_rpc7_ODT_TypeDef rpc7_ODT; /*!< Offset: 0x39c */
+ __IO CFG_DDR_SGMII_PHY_rpc8_ODT_TypeDef rpc8_ODT; /*!< Offset: 0x3a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc9_ODT_TypeDef rpc9_ODT; /*!< Offset: 0x3a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc10_ODT_TypeDef rpc10_ODT; /*!< Offset: 0x3a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc11_ODT_TypeDef rpc11_ODT; /*!< Offset: 0x3ac */
+ __I uint32_t UNUSED_SPACE7[20]; /*!< Offset: 0x3b0 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_DECODER_IO_TypeDef SOFT_RESET_DECODER_IO; /*!< Offset: 0x400 */
+ __IO CFG_DDR_SGMII_PHY_ovrt1_TypeDef ovrt1; /*!< Offset: 0x404 */
+ __IO CFG_DDR_SGMII_PHY_ovrt2_TypeDef ovrt2; /*!< Offset: 0x408 */
+ __IO CFG_DDR_SGMII_PHY_ovrt3_TypeDef ovrt3; /*!< Offset: 0x40c */
+ __IO CFG_DDR_SGMII_PHY_ovrt4_TypeDef ovrt4; /*!< Offset: 0x410 */
+ __IO CFG_DDR_SGMII_PHY_ovrt5_TypeDef ovrt5; /*!< Offset: 0x414 */
+ __IO CFG_DDR_SGMII_PHY_ovrt6_TypeDef ovrt6; /*!< Offset: 0x418 */
+ __IO CFG_DDR_SGMII_PHY_ovrt7_TypeDef ovrt7; /*!< Offset: 0x41c */
+ __IO CFG_DDR_SGMII_PHY_ovrt8_TypeDef ovrt8; /*!< Offset: 0x420 */
+ __IO CFG_DDR_SGMII_PHY_ovrt9_TypeDef ovrt9; /*!< Offset: 0x424 */
+ __IO CFG_DDR_SGMII_PHY_ovrt10_TypeDef ovrt10; /*!< Offset: 0x428 */
+ __IO CFG_DDR_SGMII_PHY_ovrt11_TypeDef ovrt11; /*!< Offset: 0x42c */
+ __IO CFG_DDR_SGMII_PHY_ovrt12_TypeDef ovrt12; /*!< Offset: 0x430 */
+ __IO CFG_DDR_SGMII_PHY_ovrt13_TypeDef ovrt13; /*!< Offset: 0x434 */
+ __IO CFG_DDR_SGMII_PHY_ovrt14_TypeDef ovrt14; /*!< Offset: 0x438 */
+ __IO CFG_DDR_SGMII_PHY_ovrt15_TypeDef ovrt15; /*!< Offset: 0x43c */
+ __IO CFG_DDR_SGMII_PHY_ovrt16_TypeDef ovrt16; /*!< Offset: 0x440 */
+ __IO CFG_DDR_SGMII_PHY_rpc17_TypeDef rpc17; /*!< Offset: 0x444 */
+ __IO CFG_DDR_SGMII_PHY_rpc18_TypeDef rpc18; /*!< Offset: 0x448 */
+ __IO CFG_DDR_SGMII_PHY_rpc19_TypeDef rpc19; /*!< Offset: 0x44c */
+ __IO CFG_DDR_SGMII_PHY_rpc20_TypeDef rpc20; /*!< Offset: 0x450 */
+ __IO CFG_DDR_SGMII_PHY_rpc21_TypeDef rpc21; /*!< Offset: 0x454 */
+ __IO CFG_DDR_SGMII_PHY_rpc22_TypeDef rpc22; /*!< Offset: 0x458 */
+ __IO CFG_DDR_SGMII_PHY_rpc23_TypeDef rpc23; /*!< Offset: 0x45c */
+ __IO CFG_DDR_SGMII_PHY_rpc24_TypeDef rpc24; /*!< Offset: 0x460 */
+ __IO CFG_DDR_SGMII_PHY_rpc25_TypeDef rpc25; /*!< Offset: 0x464 */
+ __IO CFG_DDR_SGMII_PHY_rpc26_TypeDef rpc26; /*!< Offset: 0x468 */
+ __IO CFG_DDR_SGMII_PHY_rpc27_TypeDef rpc27; /*!< Offset: 0x46c */
+ __IO CFG_DDR_SGMII_PHY_rpc28_TypeDef rpc28; /*!< Offset: 0x470 */
+ __IO CFG_DDR_SGMII_PHY_rpc29_TypeDef rpc29; /*!< Offset: 0x474 */
+ __IO CFG_DDR_SGMII_PHY_rpc30_TypeDef rpc30; /*!< Offset: 0x478 */
+ __IO CFG_DDR_SGMII_PHY_rpc31_TypeDef rpc31; /*!< Offset: 0x47c */
+ __IO CFG_DDR_SGMII_PHY_rpc32_TypeDef rpc32; /*!< Offset: 0x480 */
+ __IO CFG_DDR_SGMII_PHY_rpc33_TypeDef rpc33; /*!< Offset: 0x484 */
+ __IO CFG_DDR_SGMII_PHY_rpc34_TypeDef rpc34; /*!< Offset: 0x488 */
+ __IO CFG_DDR_SGMII_PHY_rpc35_TypeDef rpc35; /*!< Offset: 0x48c */
+ __IO CFG_DDR_SGMII_PHY_rpc36_TypeDef rpc36; /*!< Offset: 0x490 */
+ __IO CFG_DDR_SGMII_PHY_rpc37_TypeDef rpc37; /*!< Offset: 0x494 */
+ __IO CFG_DDR_SGMII_PHY_rpc38_TypeDef rpc38; /*!< Offset: 0x498 */
+ __IO CFG_DDR_SGMII_PHY_rpc39_TypeDef rpc39; /*!< Offset: 0x49c */
+ __IO CFG_DDR_SGMII_PHY_rpc40_TypeDef rpc40; /*!< Offset: 0x4a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc41_TypeDef rpc41; /*!< Offset: 0x4a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc42_TypeDef rpc42; /*!< Offset: 0x4a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc43_TypeDef rpc43; /*!< Offset: 0x4ac */
+ __IO CFG_DDR_SGMII_PHY_rpc44_TypeDef rpc44; /*!< Offset: 0x4b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc45_TypeDef rpc45; /*!< Offset: 0x4b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc46_TypeDef rpc46; /*!< Offset: 0x4b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc47_TypeDef rpc47; /*!< Offset: 0x4bc */
+ __IO CFG_DDR_SGMII_PHY_rpc48_TypeDef rpc48; /*!< Offset: 0x4c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc49_TypeDef rpc49; /*!< Offset: 0x4c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc50_TypeDef rpc50; /*!< Offset: 0x4c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc51_TypeDef rpc51; /*!< Offset: 0x4cc */
+ __IO CFG_DDR_SGMII_PHY_rpc52_TypeDef rpc52; /*!< Offset: 0x4d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc53_TypeDef rpc53; /*!< Offset: 0x4d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc54_TypeDef rpc54; /*!< Offset: 0x4d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc55_TypeDef rpc55; /*!< Offset: 0x4dc */
+ __IO CFG_DDR_SGMII_PHY_rpc56_TypeDef rpc56; /*!< Offset: 0x4e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc57_TypeDef rpc57; /*!< Offset: 0x4e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc58_TypeDef rpc58; /*!< Offset: 0x4e8 */
+ __IO CFG_DDR_SGMII_PHY_rpc59_TypeDef rpc59; /*!< Offset: 0x4ec */
+ __IO CFG_DDR_SGMII_PHY_rpc60_TypeDef rpc60; /*!< Offset: 0x4f0 */
+ __IO CFG_DDR_SGMII_PHY_rpc61_TypeDef rpc61; /*!< Offset: 0x4f4 */
+ __IO CFG_DDR_SGMII_PHY_rpc62_TypeDef rpc62; /*!< Offset: 0x4f8 */
+ __IO CFG_DDR_SGMII_PHY_rpc63_TypeDef rpc63; /*!< Offset: 0x4fc */
+ __IO CFG_DDR_SGMII_PHY_rpc64_TypeDef rpc64; /*!< Offset: 0x500 */
+ __IO CFG_DDR_SGMII_PHY_rpc65_TypeDef rpc65; /*!< Offset: 0x504 */
+ __IO CFG_DDR_SGMII_PHY_rpc66_TypeDef rpc66; /*!< Offset: 0x508 */
+ __IO CFG_DDR_SGMII_PHY_rpc67_TypeDef rpc67; /*!< Offset: 0x50c */
+ __IO CFG_DDR_SGMII_PHY_rpc68_TypeDef rpc68; /*!< Offset: 0x510 */
+ __IO CFG_DDR_SGMII_PHY_rpc69_TypeDef rpc69; /*!< Offset: 0x514 */
+ __IO CFG_DDR_SGMII_PHY_rpc70_TypeDef rpc70; /*!< Offset: 0x518 */
+ __IO CFG_DDR_SGMII_PHY_rpc71_TypeDef rpc71; /*!< Offset: 0x51c */
+ __IO CFG_DDR_SGMII_PHY_rpc72_TypeDef rpc72; /*!< Offset: 0x520 */
+ __IO CFG_DDR_SGMII_PHY_rpc73_TypeDef rpc73; /*!< Offset: 0x524 */
+ __IO CFG_DDR_SGMII_PHY_rpc74_TypeDef rpc74; /*!< Offset: 0x528 */
+ __IO CFG_DDR_SGMII_PHY_rpc75_TypeDef rpc75; /*!< Offset: 0x52c */
+ __IO CFG_DDR_SGMII_PHY_rpc76_TypeDef rpc76; /*!< Offset: 0x530 */
+ __IO CFG_DDR_SGMII_PHY_rpc77_TypeDef rpc77; /*!< Offset: 0x534 */
+ __IO CFG_DDR_SGMII_PHY_rpc78_TypeDef rpc78; /*!< Offset: 0x538 */
+ __IO CFG_DDR_SGMII_PHY_rpc79_TypeDef rpc79; /*!< Offset: 0x53c */
+ __IO CFG_DDR_SGMII_PHY_rpc80_TypeDef rpc80; /*!< Offset: 0x540 */
+ __IO CFG_DDR_SGMII_PHY_rpc81_TypeDef rpc81; /*!< Offset: 0x544 */
+ __IO CFG_DDR_SGMII_PHY_rpc82_TypeDef rpc82; /*!< Offset: 0x548 */
+ __IO CFG_DDR_SGMII_PHY_rpc83_TypeDef rpc83; /*!< Offset: 0x54c */
+ __IO CFG_DDR_SGMII_PHY_rpc84_TypeDef rpc84; /*!< Offset: 0x550 */
+ __IO CFG_DDR_SGMII_PHY_rpc85_TypeDef rpc85; /*!< Offset: 0x554 */
+ __IO CFG_DDR_SGMII_PHY_rpc86_TypeDef rpc86; /*!< Offset: 0x558 */
+ __IO CFG_DDR_SGMII_PHY_rpc87_TypeDef rpc87; /*!< Offset: 0x55c */
+ __IO CFG_DDR_SGMII_PHY_rpc88_TypeDef rpc88; /*!< Offset: 0x560 */
+ __IO CFG_DDR_SGMII_PHY_rpc89_TypeDef rpc89; /*!< Offset: 0x564 */
+ __IO CFG_DDR_SGMII_PHY_rpc90_TypeDef rpc90; /*!< Offset: 0x568 */
+ __IO CFG_DDR_SGMII_PHY_rpc91_TypeDef rpc91; /*!< Offset: 0x56c */
+ __IO CFG_DDR_SGMII_PHY_rpc92_TypeDef rpc92; /*!< Offset: 0x570 */
+ __IO CFG_DDR_SGMII_PHY_rpc93_TypeDef rpc93; /*!< Offset: 0x574 */
+ __IO CFG_DDR_SGMII_PHY_rpc94_TypeDef rpc94; /*!< Offset: 0x578 */
+ __IO CFG_DDR_SGMII_PHY_rpc95_TypeDef rpc95; /*!< Offset: 0x57c */
+ __IO CFG_DDR_SGMII_PHY_rpc96_TypeDef rpc96; /*!< Offset: 0x580 */
+ __IO CFG_DDR_SGMII_PHY_rpc97_TypeDef rpc97; /*!< Offset: 0x584 */
+ __IO CFG_DDR_SGMII_PHY_rpc98_TypeDef rpc98; /*!< Offset: 0x588 */
+ __IO CFG_DDR_SGMII_PHY_rpc99_TypeDef rpc99; /*!< Offset: 0x58c */
+ __IO CFG_DDR_SGMII_PHY_rpc100_TypeDef rpc100; /*!< Offset: 0x590 */
+ __IO CFG_DDR_SGMII_PHY_rpc101_TypeDef rpc101; /*!< Offset: 0x594 */
+ __IO CFG_DDR_SGMII_PHY_rpc102_TypeDef rpc102; /*!< Offset: 0x598 */
+ __IO CFG_DDR_SGMII_PHY_rpc103_TypeDef rpc103; /*!< Offset: 0x59c */
+ __IO CFG_DDR_SGMII_PHY_rpc104_TypeDef rpc104; /*!< Offset: 0x5a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc105_TypeDef rpc105; /*!< Offset: 0x5a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc106_TypeDef rpc106; /*!< Offset: 0x5a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc107_TypeDef rpc107; /*!< Offset: 0x5ac */
+ __IO CFG_DDR_SGMII_PHY_rpc108_TypeDef rpc108; /*!< Offset: 0x5b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc109_TypeDef rpc109; /*!< Offset: 0x5b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc110_TypeDef rpc110; /*!< Offset: 0x5b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc111_TypeDef rpc111; /*!< Offset: 0x5bc */
+ __IO CFG_DDR_SGMII_PHY_rpc112_TypeDef rpc112; /*!< Offset: 0x5c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc113_TypeDef rpc113; /*!< Offset: 0x5c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc114_TypeDef rpc114; /*!< Offset: 0x5c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc115_TypeDef rpc115; /*!< Offset: 0x5cc */
+ __IO CFG_DDR_SGMII_PHY_rpc116_TypeDef rpc116; /*!< Offset: 0x5d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc117_TypeDef rpc117; /*!< Offset: 0x5d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc118_TypeDef rpc118; /*!< Offset: 0x5d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc119_TypeDef rpc119; /*!< Offset: 0x5dc */
+ __IO CFG_DDR_SGMII_PHY_rpc120_TypeDef rpc120; /*!< Offset: 0x5e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc121_TypeDef rpc121; /*!< Offset: 0x5e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc122_TypeDef rpc122; /*!< Offset: 0x5e8 */
+ __IO CFG_DDR_SGMII_PHY_rpc123_TypeDef rpc123; /*!< Offset: 0x5ec */
+ __IO CFG_DDR_SGMII_PHY_rpc124_TypeDef rpc124; /*!< Offset: 0x5f0 */
+ __IO CFG_DDR_SGMII_PHY_rpc125_TypeDef rpc125; /*!< Offset: 0x5f4 */
+ __IO CFG_DDR_SGMII_PHY_rpc126_TypeDef rpc126; /*!< Offset: 0x5f8 */
+ __IO CFG_DDR_SGMII_PHY_rpc127_TypeDef rpc127; /*!< Offset: 0x5fc */
+ __IO CFG_DDR_SGMII_PHY_rpc128_TypeDef rpc128; /*!< Offset: 0x600 */
+ __IO CFG_DDR_SGMII_PHY_rpc129_TypeDef rpc129; /*!< Offset: 0x604 */
+ __IO CFG_DDR_SGMII_PHY_rpc130_TypeDef rpc130; /*!< Offset: 0x608 */
+ __IO CFG_DDR_SGMII_PHY_rpc131_TypeDef rpc131; /*!< Offset: 0x60c */
+ __IO CFG_DDR_SGMII_PHY_rpc132_TypeDef rpc132; /*!< Offset: 0x610 */
+ __IO CFG_DDR_SGMII_PHY_rpc133_TypeDef rpc133; /*!< Offset: 0x614 */
+ __IO CFG_DDR_SGMII_PHY_rpc134_TypeDef rpc134; /*!< Offset: 0x618 */
+ __IO CFG_DDR_SGMII_PHY_rpc135_TypeDef rpc135; /*!< Offset: 0x61c */
+ __IO CFG_DDR_SGMII_PHY_rpc136_TypeDef rpc136; /*!< Offset: 0x620 */
+ __IO CFG_DDR_SGMII_PHY_rpc137_TypeDef rpc137; /*!< Offset: 0x624 */
+ __IO CFG_DDR_SGMII_PHY_rpc138_TypeDef rpc138; /*!< Offset: 0x628 */
+ __IO CFG_DDR_SGMII_PHY_rpc139_TypeDef rpc139; /*!< Offset: 0x62c */
+ __IO CFG_DDR_SGMII_PHY_rpc140_TypeDef rpc140; /*!< Offset: 0x630 */
+ __IO CFG_DDR_SGMII_PHY_rpc141_TypeDef rpc141; /*!< Offset: 0x634 */
+ __IO CFG_DDR_SGMII_PHY_rpc142_TypeDef rpc142; /*!< Offset: 0x638 */
+ __IO CFG_DDR_SGMII_PHY_rpc143_TypeDef rpc143; /*!< Offset: 0x63c */
+ __IO CFG_DDR_SGMII_PHY_rpc144_TypeDef rpc144; /*!< Offset: 0x640 */
+ __IO CFG_DDR_SGMII_PHY_rpc145_TypeDef rpc145; /*!< Offset: 0x644 */
+ __IO CFG_DDR_SGMII_PHY_rpc146_TypeDef rpc146; /*!< Offset: 0x648 */
+ __IO CFG_DDR_SGMII_PHY_rpc147_TypeDef rpc147; /*!< Offset: 0x64c */
+ __IO CFG_DDR_SGMII_PHY_rpc148_TypeDef rpc148; /*!< Offset: 0x650 */
+ __IO CFG_DDR_SGMII_PHY_rpc149_TypeDef rpc149; /*!< Offset: 0x654 */
+ __IO CFG_DDR_SGMII_PHY_rpc150_TypeDef rpc150; /*!< Offset: 0x658 */
+ __IO CFG_DDR_SGMII_PHY_rpc151_TypeDef rpc151; /*!< Offset: 0x65c */
+ __IO CFG_DDR_SGMII_PHY_rpc152_TypeDef rpc152; /*!< Offset: 0x660 */
+ __IO CFG_DDR_SGMII_PHY_rpc153_TypeDef rpc153; /*!< Offset: 0x664 */
+ __IO CFG_DDR_SGMII_PHY_rpc154_TypeDef rpc154; /*!< Offset: 0x668 */
+ __IO CFG_DDR_SGMII_PHY_rpc155_TypeDef rpc155; /*!< Offset: 0x66c */
+ __IO CFG_DDR_SGMII_PHY_rpc156_TypeDef rpc156; /*!< Offset: 0x670 */
+ __IO CFG_DDR_SGMII_PHY_rpc157_TypeDef rpc157; /*!< Offset: 0x674 */
+ __IO CFG_DDR_SGMII_PHY_rpc158_TypeDef rpc158; /*!< Offset: 0x678 */
+ __IO CFG_DDR_SGMII_PHY_rpc159_TypeDef rpc159; /*!< Offset: 0x67c */
+ __IO CFG_DDR_SGMII_PHY_rpc160_TypeDef rpc160; /*!< Offset: 0x680 */
+ __IO CFG_DDR_SGMII_PHY_rpc161_TypeDef rpc161; /*!< Offset: 0x684 */
+ __IO CFG_DDR_SGMII_PHY_rpc162_TypeDef rpc162; /*!< Offset: 0x688 */
+ __IO CFG_DDR_SGMII_PHY_rpc163_TypeDef rpc163; /*!< Offset: 0x68c */
+ __IO CFG_DDR_SGMII_PHY_rpc164_TypeDef rpc164; /*!< Offset: 0x690 */
+ __IO CFG_DDR_SGMII_PHY_rpc165_TypeDef rpc165; /*!< Offset: 0x694 */
+ __IO CFG_DDR_SGMII_PHY_rpc166_TypeDef rpc166; /*!< Offset: 0x698 */
+ __IO CFG_DDR_SGMII_PHY_rpc167_TypeDef rpc167; /*!< Offset: 0x69c */
+ __IO CFG_DDR_SGMII_PHY_rpc168_TypeDef rpc168; /*!< Offset: 0x6a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc169_TypeDef rpc169; /*!< Offset: 0x6a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc170_TypeDef rpc170; /*!< Offset: 0x6a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc171_TypeDef rpc171; /*!< Offset: 0x6ac */
+ __IO CFG_DDR_SGMII_PHY_rpc172_TypeDef rpc172; /*!< Offset: 0x6b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc173_TypeDef rpc173; /*!< Offset: 0x6b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc174_TypeDef rpc174; /*!< Offset: 0x6b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc175_TypeDef rpc175; /*!< Offset: 0x6bc */
+ __IO CFG_DDR_SGMII_PHY_rpc176_TypeDef rpc176; /*!< Offset: 0x6c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc177_TypeDef rpc177; /*!< Offset: 0x6c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc178_TypeDef rpc178; /*!< Offset: 0x6c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc179_TypeDef rpc179; /*!< Offset: 0x6cc */
+ __IO CFG_DDR_SGMII_PHY_rpc180_TypeDef rpc180; /*!< Offset: 0x6d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc181_TypeDef rpc181; /*!< Offset: 0x6d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc182_TypeDef rpc182; /*!< Offset: 0x6d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc183_TypeDef rpc183; /*!< Offset: 0x6dc */
+ __IO CFG_DDR_SGMII_PHY_rpc184_TypeDef rpc184; /*!< Offset: 0x6e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc185_TypeDef rpc185; /*!< Offset: 0x6e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc186_TypeDef rpc186; /*!< Offset: 0x6e8 */
+ __IO CFG_DDR_SGMII_PHY_rpc187_TypeDef rpc187; /*!< Offset: 0x6ec */
+ __IO CFG_DDR_SGMII_PHY_rpc188_TypeDef rpc188; /*!< Offset: 0x6f0 */
+ __IO CFG_DDR_SGMII_PHY_rpc189_TypeDef rpc189; /*!< Offset: 0x6f4 */
+ __IO CFG_DDR_SGMII_PHY_rpc190_TypeDef rpc190; /*!< Offset: 0x6f8 */
+ __IO CFG_DDR_SGMII_PHY_rpc191_TypeDef rpc191; /*!< Offset: 0x6fc */
+ __IO CFG_DDR_SGMII_PHY_rpc192_TypeDef rpc192; /*!< Offset: 0x700 */
+ __IO CFG_DDR_SGMII_PHY_rpc193_TypeDef rpc193; /*!< Offset: 0x704 */
+ __IO CFG_DDR_SGMII_PHY_rpc194_TypeDef rpc194; /*!< Offset: 0x708 */
+ __IO CFG_DDR_SGMII_PHY_rpc195_TypeDef rpc195; /*!< Offset: 0x70c */
+ __IO CFG_DDR_SGMII_PHY_rpc196_TypeDef rpc196; /*!< Offset: 0x710 */
+ __IO CFG_DDR_SGMII_PHY_rpc197_TypeDef rpc197; /*!< Offset: 0x714 */
+ __IO CFG_DDR_SGMII_PHY_rpc198_TypeDef rpc198; /*!< Offset: 0x718 */
+ __IO CFG_DDR_SGMII_PHY_rpc199_TypeDef rpc199; /*!< Offset: 0x71c */
+ __IO CFG_DDR_SGMII_PHY_rpc200_TypeDef rpc200; /*!< Offset: 0x720 */
+ __IO CFG_DDR_SGMII_PHY_rpc201_TypeDef rpc201; /*!< Offset: 0x724 */
+ __IO CFG_DDR_SGMII_PHY_rpc202_TypeDef rpc202; /*!< Offset: 0x728 */
+ __IO CFG_DDR_SGMII_PHY_rpc203_TypeDef rpc203; /*!< Offset: 0x72c */
+ __IO CFG_DDR_SGMII_PHY_rpc204_TypeDef rpc204; /*!< Offset: 0x730 */
+ __IO CFG_DDR_SGMII_PHY_rpc205_TypeDef rpc205; /*!< Offset: 0x734 */
+ __IO CFG_DDR_SGMII_PHY_rpc206_TypeDef rpc206; /*!< Offset: 0x738 */
+ __IO CFG_DDR_SGMII_PHY_rpc207_TypeDef rpc207; /*!< Offset: 0x73c */
+ __IO CFG_DDR_SGMII_PHY_rpc208_TypeDef rpc208; /*!< Offset: 0x740 */
+ __IO CFG_DDR_SGMII_PHY_rpc209_TypeDef rpc209; /*!< Offset: 0x744 */
+ __IO CFG_DDR_SGMII_PHY_rpc210_TypeDef rpc210; /*!< Offset: 0x748 */
+ __IO CFG_DDR_SGMII_PHY_rpc211_TypeDef rpc211; /*!< Offset: 0x74c */
+ __IO CFG_DDR_SGMII_PHY_rpc212_TypeDef rpc212; /*!< Offset: 0x750 */
+ __IO CFG_DDR_SGMII_PHY_rpc213_TypeDef rpc213; /*!< Offset: 0x754 */
+ __IO CFG_DDR_SGMII_PHY_rpc214_TypeDef rpc214; /*!< Offset: 0x758 */
+ __IO CFG_DDR_SGMII_PHY_rpc215_TypeDef rpc215; /*!< Offset: 0x75c */
+ __IO CFG_DDR_SGMII_PHY_rpc216_TypeDef rpc216; /*!< Offset: 0x760 */
+ __IO CFG_DDR_SGMII_PHY_rpc217_TypeDef rpc217; /*!< Offset: 0x764 */
+ __IO CFG_DDR_SGMII_PHY_rpc218_TypeDef rpc218; /*!< Offset: 0x768 */
+ __IO CFG_DDR_SGMII_PHY_rpc219_TypeDef rpc219; /*!< Offset: 0x76c */
+ __IO CFG_DDR_SGMII_PHY_rpc220_TypeDef rpc220; /*!< Offset: 0x770 */
+ __IO CFG_DDR_SGMII_PHY_rpc221_TypeDef rpc221; /*!< Offset: 0x774 */
+ __IO CFG_DDR_SGMII_PHY_rpc222_TypeDef rpc222; /*!< Offset: 0x778 */
+ __IO CFG_DDR_SGMII_PHY_rpc223_TypeDef rpc223; /*!< Offset: 0x77c */
+ __IO CFG_DDR_SGMII_PHY_rpc224_TypeDef rpc224; /*!< Offset: 0x780 */
+ __IO CFG_DDR_SGMII_PHY_rpc225_TypeDef rpc225; /*!< Offset: 0x784 */
+ __IO CFG_DDR_SGMII_PHY_rpc226_TypeDef rpc226; /*!< Offset: 0x788 */
+ __IO CFG_DDR_SGMII_PHY_rpc227_TypeDef rpc227; /*!< Offset: 0x78c */
+ __IO CFG_DDR_SGMII_PHY_rpc228_TypeDef rpc228; /*!< Offset: 0x790 */
+ __IO CFG_DDR_SGMII_PHY_rpc229_TypeDef rpc229; /*!< Offset: 0x794 */
+ __IO CFG_DDR_SGMII_PHY_rpc230_TypeDef rpc230; /*!< Offset: 0x798 */
+ __IO CFG_DDR_SGMII_PHY_rpc231_TypeDef rpc231; /*!< Offset: 0x79c */
+ __IO CFG_DDR_SGMII_PHY_rpc232_TypeDef rpc232; /*!< Offset: 0x7a0 */
+ __IO CFG_DDR_SGMII_PHY_rpc233_TypeDef rpc233; /*!< Offset: 0x7a4 */
+ __IO CFG_DDR_SGMII_PHY_rpc234_TypeDef rpc234; /*!< Offset: 0x7a8 */
+ __IO CFG_DDR_SGMII_PHY_rpc235_TypeDef rpc235; /*!< Offset: 0x7ac */
+ __IO CFG_DDR_SGMII_PHY_rpc236_TypeDef rpc236; /*!< Offset: 0x7b0 */
+ __IO CFG_DDR_SGMII_PHY_rpc237_TypeDef rpc237; /*!< Offset: 0x7b4 */
+ __IO CFG_DDR_SGMII_PHY_rpc238_TypeDef rpc238; /*!< Offset: 0x7b8 */
+ __IO CFG_DDR_SGMII_PHY_rpc239_TypeDef rpc239; /*!< Offset: 0x7bc */
+ __IO CFG_DDR_SGMII_PHY_rpc240_TypeDef rpc240; /*!< Offset: 0x7c0 */
+ __IO CFG_DDR_SGMII_PHY_rpc241_TypeDef rpc241; /*!< Offset: 0x7c4 */
+ __IO CFG_DDR_SGMII_PHY_rpc242_TypeDef rpc242; /*!< Offset: 0x7c8 */
+ __IO CFG_DDR_SGMII_PHY_rpc243_TypeDef rpc243; /*!< Offset: 0x7cc */
+ __IO CFG_DDR_SGMII_PHY_rpc244_TypeDef rpc244; /*!< Offset: 0x7d0 */
+ __IO CFG_DDR_SGMII_PHY_rpc245_TypeDef rpc245; /*!< Offset: 0x7d4 */
+ __IO CFG_DDR_SGMII_PHY_rpc246_TypeDef rpc246; /*!< Offset: 0x7d8 */
+ __IO CFG_DDR_SGMII_PHY_rpc247_TypeDef rpc247; /*!< Offset: 0x7dc */
+ __IO CFG_DDR_SGMII_PHY_rpc248_TypeDef rpc248; /*!< Offset: 0x7e0 */
+ __IO CFG_DDR_SGMII_PHY_rpc249_TypeDef rpc249; /*!< Offset: 0x7e4 */
+ __IO CFG_DDR_SGMII_PHY_rpc250_TypeDef rpc250; /*!< Offset: 0x7e8 */
+ __IO CFG_DDR_SGMII_PHY_spio251_TypeDef spio251; /*!< Offset: 0x7ec */
+ __IO CFG_DDR_SGMII_PHY_spio252_TypeDef spio252; /*!< Offset: 0x7f0 */
+ __IO CFG_DDR_SGMII_PHY_spio253_TypeDef spio253; /*!< Offset: 0x7f4 */
+ __I uint32_t UNUSED_SPACE8[2]; /*!< Offset: 0x7f8 */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_TIP_TypeDef SOFT_RESET_TIP; /*!< Offset: 0x800 */
+ __IO CFG_DDR_SGMII_PHY_rank_select_TypeDef rank_select; /*!< Offset: 0x804 */
+ __IO CFG_DDR_SGMII_PHY_lane_select_TypeDef lane_select; /*!< Offset: 0x808 */
+ __IO CFG_DDR_SGMII_PHY_training_skip_TypeDef training_skip; /*!< Offset: 0x80c */
+ __IO CFG_DDR_SGMII_PHY_training_start_TypeDef training_start; /*!< Offset: 0x810 */
+ __I CFG_DDR_SGMII_PHY_training_status_TypeDef training_status; /*!< Offset: 0x814 */
+ __IO CFG_DDR_SGMII_PHY_training_reset_TypeDef training_reset; /*!< Offset: 0x818 */
+ __I CFG_DDR_SGMII_PHY_gt_err_comb_TypeDef gt_err_comb; /*!< Offset: 0x81c */
+ __I CFG_DDR_SGMII_PHY_gt_clk_sel_TypeDef gt_clk_sel; /*!< Offset: 0x820 */
+ __I CFG_DDR_SGMII_PHY_gt_txdly_TypeDef gt_txdly; /*!< Offset: 0x824 */
+ __I CFG_DDR_SGMII_PHY_gt_steps_180_TypeDef gt_steps_180; /*!< Offset: 0x828 */
+ __I CFG_DDR_SGMII_PHY_gt_state_TypeDef gt_state; /*!< Offset: 0x82c */
+ __I CFG_DDR_SGMII_PHY_wl_delay_0_TypeDef wl_delay_0; /*!< Offset: 0x830 */
+ __I CFG_DDR_SGMII_PHY_dq_dqs_err_done_TypeDef dq_dqs_err_done; /*!< Offset: 0x834 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_window_TypeDef dqdqs_window; /*!< Offset: 0x838 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_state_TypeDef dqdqs_state; /*!< Offset: 0x83c */
+ __I CFG_DDR_SGMII_PHY_delta0_TypeDef delta0; /*!< Offset: 0x840 */
+ __I CFG_DDR_SGMII_PHY_delta1_TypeDef delta1; /*!< Offset: 0x844 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status0_TypeDef dqdqs_status0; /*!< Offset: 0x848 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status1_TypeDef dqdqs_status1; /*!< Offset: 0x84c */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status2_TypeDef dqdqs_status2; /*!< Offset: 0x850 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status3_TypeDef dqdqs_status3; /*!< Offset: 0x854 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status4_TypeDef dqdqs_status4; /*!< Offset: 0x858 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status5_TypeDef dqdqs_status5; /*!< Offset: 0x85c */
+ __I CFG_DDR_SGMII_PHY_dqdqs_status6_TypeDef dqdqs_status6; /*!< Offset: 0x860 */
+ __I CFG_DDR_SGMII_PHY_addcmd_status0_TypeDef addcmd_status0; /*!< Offset: 0x864 */
+ __I CFG_DDR_SGMII_PHY_addcmd_status1_TypeDef addcmd_status1; /*!< Offset: 0x868 */
+ __I CFG_DDR_SGMII_PHY_addcmd_answer_TypeDef addcmd_answer; /*!< Offset: 0x86c */
+ __I CFG_DDR_SGMII_PHY_bclksclk_answer_TypeDef bclksclk_answer; /*!< Offset: 0x870 */
+ __I CFG_DDR_SGMII_PHY_dqdqs_wrcalib_offset_TypeDef dqdqs_wrcalib_offset; /*!< Offset: 0x874 */
+ __IO CFG_DDR_SGMII_PHY_expert_mode_en_TypeDef expert_mode_en; /*!< Offset: 0x878 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg0_TypeDef expert_dlycnt_move_reg0; /*!< Offset: 0x87c */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_move_reg1_TypeDef expert_dlycnt_move_reg1; /*!< Offset: 0x880 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg0_TypeDef expert_dlycnt_direction_reg0; /*!< Offset: 0x884 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_direction_reg1_TypeDef expert_dlycnt_direction_reg1; /*!< Offset: 0x888 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg0_TypeDef expert_dlycnt_load_reg0; /*!< Offset: 0x88c */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_load_reg1_TypeDef expert_dlycnt_load_reg1; /*!< Offset: 0x890 */
+ __I CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg0_TypeDef expert_dlycnt_oor_reg0; /*!< Offset: 0x894 */
+ __I CFG_DDR_SGMII_PHY_expert_dlycnt_oor_reg1_TypeDef expert_dlycnt_oor_reg1; /*!< Offset: 0x898 */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_mv_rd_dly_reg_TypeDef expert_dlycnt_mv_rd_dly_reg; /*!< Offset: 0x89c */
+ __IO CFG_DDR_SGMII_PHY_expert_dlycnt_pause_TypeDef expert_dlycnt_pause; /*!< Offset: 0x8a0 */
+ __IO CFG_DDR_SGMII_PHY_expert_pllcnt_TypeDef expert_pllcnt; /*!< Offset: 0x8a4 */
+ __I CFG_DDR_SGMII_PHY_expert_dqlane_readback_TypeDef expert_dqlane_readback; /*!< Offset: 0x8a8 */
+ __I CFG_DDR_SGMII_PHY_expert_addcmd_ln_readback_TypeDef expert_addcmd_ln_readback; /*!< Offset: 0x8ac */
+ __IO CFG_DDR_SGMII_PHY_expert_read_gate_controls_TypeDef expert_read_gate_controls; /*!< Offset: 0x8b0 */
+ __I CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization0_TypeDef expert_dq_dqs_optimization0; /*!< Offset: 0x8b4 */
+ __I CFG_DDR_SGMII_PHY_expert_dq_dqs_optimization1_TypeDef expert_dq_dqs_optimization1; /*!< Offset: 0x8b8 */
+ __IO CFG_DDR_SGMII_PHY_expert_wrcalib_TypeDef expert_wrcalib; /*!< Offset: 0x8bc */
+ __IO CFG_DDR_SGMII_PHY_expert_calif_TypeDef expert_calif; /*!< Offset: 0x8c0 */
+ __I CFG_DDR_SGMII_PHY_expert_calif_readback_TypeDef expert_calif_readback; /*!< Offset: 0x8c4 */
+ __I CFG_DDR_SGMII_PHY_expert_calif_readback1_TypeDef expert_calif_readback1; /*!< Offset: 0x8c8 */
+ __IO CFG_DDR_SGMII_PHY_expert_dfi_status_override_to_shim_TypeDef expert_dfi_status_override_to_shim; /*!< Offset: 0x8cc */
+ __IO CFG_DDR_SGMII_PHY_tip_cfg_params_TypeDef tip_cfg_params; /*!< Offset: 0x8d0 */
+ __IO CFG_DDR_SGMII_PHY_tip_vref_param_TypeDef tip_vref_param; /*!< Offset: 0x8d4 */
+ __IO CFG_DDR_SGMII_PHY_lane_alignment_fifo_control_TypeDef lane_alignment_fifo_control; /*!< Offset: 0x8d8 */
+ __I uint32_t UNUSED_SPACE9[201]; /*!< Offset: 0x8dc */
+ __IO CFG_DDR_SGMII_PHY_SOFT_RESET_SGMII_TypeDef SOFT_RESET_SGMII; /*!< Offset: 0xc00 */
+ __IO CFG_DDR_SGMII_PHY_SGMII_MODE_TypeDef SGMII_MODE; /*!< Offset: 0xc04 */
+ __IO CFG_DDR_SGMII_PHY_PLL_CNTL_TypeDef PLL_CNTL; /*!< Offset: 0xc08 */
+ __IO CFG_DDR_SGMII_PHY_CH0_CNTL_TypeDef CH0_CNTL; /*!< Offset: 0xc0c */
+ __IO CFG_DDR_SGMII_PHY_CH1_CNTL_TypeDef CH1_CNTL; /*!< Offset: 0xc10 */
+ __IO CFG_DDR_SGMII_PHY_RECAL_CNTL_TypeDef RECAL_CNTL; /*!< Offset: 0xc14 */
+ __IO CFG_DDR_SGMII_PHY_CLK_CNTL_TypeDef CLK_CNTL; /*!< Offset: 0xc18 */
+ __IO CFG_DDR_SGMII_PHY_DYN_CNTL_TypeDef DYN_CNTL; /*!< Offset: 0xc1c */
+ __IO CFG_DDR_SGMII_PHY_PVT_STAT_TypeDef PVT_STAT; /*!< Offset: 0xc20 */
+ __IO CFG_DDR_SGMII_PHY_SPARE_CNTL_TypeDef SPARE_CNTL; /*!< Offset: 0xc24 */
+ __I CFG_DDR_SGMII_PHY_SPARE_STAT_TypeDef SPARE_STAT; /*!< Offset: 0xc28 */
+} CFG_DDR_SGMII_PHY_TypeDef;
+
+
+/******************************************************************************/
+/* finish of CFG_DDR_SGMII_PHY definitions */
+/******************************************************************************/
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_SGMII_PHY_DEFS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_regs.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_regs.h
new file mode 100644
index 00000000..51f72e9b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_sgmii_regs.h
@@ -0,0 +1,5558 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_hal.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Register bit offsets and masks definitions for MPFS MSS DDR
+ * This was generated directly from the RTL
+ *
+ */
+
+#ifndef MSS_DDR_REGS_H_
+#define MSS_DDR_REGS_H_
+
+#include "../mss_sysreg.h"
+#include "mss_ddr_sgmii_phy_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------- DDR -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+
+/*============================== CFG_DDR_SGMII_PHY definitions ===========================*/
+
+/* see mss_ddr_sgmii_phy_defs.h */
+
+/******************************************************************************/
+/* finish of CFG_DDR_SGMII_PHY definitions */
+/******************************************************************************/
+
+
+/*============================== DDR_CSR_APB definitions ===========================*/
+
+typedef union{ /*!< CFG_MANUAL_ADDRESS_MAP register definition*/
+ __IO uint32_t CFG_MANUAL_ADDRESS_MAP;
+ struct
+ {
+ __IO uint32_t cfg_manual_address_map :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MANUAL_ADDRESS_MAP_TypeDef;
+
+typedef union{ /*!< CFG_CHIPADDR_MAP register definition*/
+ __IO uint32_t CFG_CHIPADDR_MAP;
+ struct
+ {
+ __IO uint32_t cfg_chipaddr_map :24;
+ __I uint32_t reserved :8;
+ } bitfield;
+} DDR_CSR_APB_CFG_CHIPADDR_MAP_TypeDef;
+
+typedef union{ /*!< CFG_CIDADDR_MAP register definition*/
+ __IO uint32_t CFG_CIDADDR_MAP;
+ struct
+ {
+ __IO uint32_t cfg_cidaddr_map :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_CFG_CIDADDR_MAP_TypeDef;
+
+typedef union{ /*!< CFG_MB_AUTOPCH_COL_BIT_POS_LOW register definition*/
+ __IO uint32_t CFG_MB_AUTOPCH_COL_BIT_POS_LOW;
+ struct
+ {
+ __IO uint32_t cfg_mb_autopch_col_bit_pos_low :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_LOW_TypeDef;
+
+typedef union{ /*!< CFG_MB_AUTOPCH_COL_BIT_POS_HIGH register definition*/
+ __IO uint32_t CFG_MB_AUTOPCH_COL_BIT_POS_HIGH;
+ struct
+ {
+ __IO uint32_t cfg_mb_autopch_col_bit_pos_high :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH_TypeDef;
+
+typedef union{ /*!< CFG_BANKADDR_MAP_0 register definition*/
+ __IO uint32_t CFG_BANKADDR_MAP_0;
+ struct
+ {
+ __IO uint32_t cfg_bankaddr_map_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BANKADDR_MAP_0_TypeDef;
+
+typedef union{ /*!< CFG_BANKADDR_MAP_1 register definition*/
+ __IO uint32_t CFG_BANKADDR_MAP_1;
+ struct
+ {
+ __IO uint32_t cfg_bankaddr_map_1 :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_BANKADDR_MAP_1_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_0 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_0;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_0_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_1 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_1;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_1 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_1_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_2 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_2;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_2 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_2_TypeDef;
+
+typedef union{ /*!< CFG_ROWADDR_MAP_3 register definition*/
+ __IO uint32_t CFG_ROWADDR_MAP_3;
+ struct
+ {
+ __IO uint32_t cfg_rowaddr_map_3 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_ROWADDR_MAP_3_TypeDef;
+
+typedef union{ /*!< CFG_COLADDR_MAP_0 register definition*/
+ __IO uint32_t CFG_COLADDR_MAP_0;
+ struct
+ {
+ __IO uint32_t cfg_coladdr_map_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_COLADDR_MAP_0_TypeDef;
+
+typedef union{ /*!< CFG_COLADDR_MAP_1 register definition*/
+ __IO uint32_t CFG_COLADDR_MAP_1;
+ struct
+ {
+ __IO uint32_t cfg_coladdr_map_1 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_COLADDR_MAP_1_TypeDef;
+
+typedef union{ /*!< CFG_COLADDR_MAP_2 register definition*/
+ __IO uint32_t CFG_COLADDR_MAP_2;
+ struct
+ {
+ __IO uint32_t cfg_coladdr_map_2 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_COLADDR_MAP_2_TypeDef;
+
+typedef union{ /*!< CFG_VRCG_ENABLE register definition*/
+ __IO uint32_t CFG_VRCG_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_vrcg_enable :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_VRCG_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_VRCG_DISABLE register definition*/
+ __IO uint32_t CFG_VRCG_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_vrcg_disable :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_VRCG_DISABLE_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_LATENCY_SET register definition*/
+ __IO uint32_t CFG_WRITE_LATENCY_SET;
+ struct
+ {
+ __IO uint32_t cfg_write_latency_set :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_LATENCY_SET_TypeDef;
+
+typedef union{ /*!< CFG_THERMAL_OFFSET register definition*/
+ __IO uint32_t CFG_THERMAL_OFFSET;
+ struct
+ {
+ __IO uint32_t cfg_thermal_offset :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_THERMAL_OFFSET_TypeDef;
+
+typedef union{ /*!< CFG_SOC_ODT register definition*/
+ __IO uint32_t CFG_SOC_ODT;
+ struct
+ {
+ __IO uint32_t cfg_soc_odt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_SOC_ODT_TypeDef;
+
+typedef union{ /*!< CFG_ODTE_CK register definition*/
+ __IO uint32_t CFG_ODTE_CK;
+ struct
+ {
+ __IO uint32_t cfg_odte_ck :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODTE_CK_TypeDef;
+
+typedef union{ /*!< CFG_ODTE_CS register definition*/
+ __IO uint32_t CFG_ODTE_CS;
+ struct
+ {
+ __IO uint32_t cfg_odte_cs :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODTE_CS_TypeDef;
+
+typedef union{ /*!< CFG_ODTD_CA register definition*/
+ __IO uint32_t CFG_ODTD_CA;
+ struct
+ {
+ __IO uint32_t cfg_odtd_ca :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODTD_CA_TypeDef;
+
+typedef union{ /*!< CFG_LPDDR4_FSP_OP register definition*/
+ __IO uint32_t CFG_LPDDR4_FSP_OP;
+ struct
+ {
+ __IO uint32_t cfg_lpddr4_fsp_op :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LPDDR4_FSP_OP_TypeDef;
+
+typedef union{ /*!< CFG_GENERATE_REFRESH_ON_SRX register definition*/
+ __IO uint32_t CFG_GENERATE_REFRESH_ON_SRX;
+ struct
+ {
+ __IO uint32_t cfg_generate_refresh_on_srx :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_GENERATE_REFRESH_ON_SRX_TypeDef;
+
+typedef union{ /*!< CFG_DBI_CL register definition*/
+ __IO uint32_t CFG_DBI_CL;
+ struct
+ {
+ __IO uint32_t cfg_dbi_cl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_DBI_CL_TypeDef;
+
+typedef union{ /*!< CFG_NON_DBI_CL register definition*/
+ __IO uint32_t CFG_NON_DBI_CL;
+ struct
+ {
+ __IO uint32_t cfg_non_dbi_cl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_NON_DBI_CL_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_WRITE_DATA_0 register definition*/
+ __IO uint32_t INIT_FORCE_WRITE_DATA_0;
+ struct
+ {
+ __IO uint32_t init_force_write_data_0 :9;
+ __I uint32_t reserved :23;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_WRITE_DATA_0_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_CRC register definition*/
+ __IO uint32_t CFG_WRITE_CRC;
+ struct
+ {
+ __IO uint32_t cfg_write_crc :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_CRC_TypeDef;
+
+typedef union{ /*!< CFG_MPR_READ_FORMAT register definition*/
+ __IO uint32_t CFG_MPR_READ_FORMAT;
+ struct
+ {
+ __IO uint32_t cfg_mpr_read_format :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_MPR_READ_FORMAT_TypeDef;
+
+typedef union{ /*!< CFG_WR_CMD_LAT_CRC_DM register definition*/
+ __IO uint32_t CFG_WR_CMD_LAT_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wr_cmd_lat_crc_dm :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_CMD_LAT_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_FINE_GRAN_REF_MODE register definition*/
+ __IO uint32_t CFG_FINE_GRAN_REF_MODE;
+ struct
+ {
+ __IO uint32_t cfg_fine_gran_ref_mode :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_FINE_GRAN_REF_MODE_TypeDef;
+
+typedef union{ /*!< CFG_TEMP_SENSOR_READOUT register definition*/
+ __IO uint32_t CFG_TEMP_SENSOR_READOUT;
+ struct
+ {
+ __IO uint32_t cfg_temp_sensor_readout :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TEMP_SENSOR_READOUT_TypeDef;
+
+typedef union{ /*!< CFG_PER_DRAM_ADDR_EN register definition*/
+ __IO uint32_t CFG_PER_DRAM_ADDR_EN;
+ struct
+ {
+ __IO uint32_t cfg_per_dram_addr_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_PER_DRAM_ADDR_EN_TypeDef;
+
+typedef union{ /*!< CFG_GEARDOWN_MODE register definition*/
+ __IO uint32_t CFG_GEARDOWN_MODE;
+ struct
+ {
+ __IO uint32_t cfg_geardown_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_GEARDOWN_MODE_TypeDef;
+
+typedef union{ /*!< CFG_WR_PREAMBLE register definition*/
+ __IO uint32_t CFG_WR_PREAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_wr_preamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_PREAMBLE_TypeDef;
+
+typedef union{ /*!< CFG_RD_PREAMBLE register definition*/
+ __IO uint32_t CFG_RD_PREAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_rd_preamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_PREAMBLE_TypeDef;
+
+typedef union{ /*!< CFG_RD_PREAMB_TRN_MODE register definition*/
+ __IO uint32_t CFG_RD_PREAMB_TRN_MODE;
+ struct
+ {
+ __IO uint32_t cfg_rd_preamb_trn_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_PREAMB_TRN_MODE_TypeDef;
+
+typedef union{ /*!< CFG_SR_ABORT register definition*/
+ __IO uint32_t CFG_SR_ABORT;
+ struct
+ {
+ __IO uint32_t cfg_sr_abort :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_SR_ABORT_TypeDef;
+
+typedef union{ /*!< CFG_CS_TO_CMDADDR_LATENCY register definition*/
+ __IO uint32_t CFG_CS_TO_CMDADDR_LATENCY;
+ struct
+ {
+ __IO uint32_t cfg_cs_to_cmdaddr_latency :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CS_TO_CMDADDR_LATENCY_TypeDef;
+
+typedef union{ /*!< CFG_INT_VREF_MON register definition*/
+ __IO uint32_t CFG_INT_VREF_MON;
+ struct
+ {
+ __IO uint32_t cfg_int_vref_mon :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_INT_VREF_MON_TypeDef;
+
+typedef union{ /*!< CFG_TEMP_CTRL_REF_MODE register definition*/
+ __IO uint32_t CFG_TEMP_CTRL_REF_MODE;
+ struct
+ {
+ __IO uint32_t cfg_temp_ctrl_ref_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TEMP_CTRL_REF_MODE_TypeDef;
+
+typedef union{ /*!< CFG_TEMP_CTRL_REF_RANGE register definition*/
+ __IO uint32_t CFG_TEMP_CTRL_REF_RANGE;
+ struct
+ {
+ __IO uint32_t cfg_temp_ctrl_ref_range :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TEMP_CTRL_REF_RANGE_TypeDef;
+
+typedef union{ /*!< CFG_MAX_PWR_DOWN_MODE register definition*/
+ __IO uint32_t CFG_MAX_PWR_DOWN_MODE;
+ struct
+ {
+ __IO uint32_t cfg_max_pwr_down_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MAX_PWR_DOWN_MODE_TypeDef;
+
+typedef union{ /*!< CFG_READ_DBI register definition*/
+ __IO uint32_t CFG_READ_DBI;
+ struct
+ {
+ __IO uint32_t cfg_read_dbi :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_DBI_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_DBI register definition*/
+ __IO uint32_t CFG_WRITE_DBI;
+ struct
+ {
+ __IO uint32_t cfg_write_dbi :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_DBI_TypeDef;
+
+typedef union{ /*!< CFG_DATA_MASK register definition*/
+ __IO uint32_t CFG_DATA_MASK;
+ struct
+ {
+ __IO uint32_t cfg_data_mask :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DATA_MASK_TypeDef;
+
+typedef union{ /*!< CFG_CA_PARITY_PERSIST_ERR register definition*/
+ __IO uint32_t CFG_CA_PARITY_PERSIST_ERR;
+ struct
+ {
+ __IO uint32_t cfg_ca_parity_persist_err :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_PARITY_PERSIST_ERR_TypeDef;
+
+typedef union{ /*!< CFG_RTT_PARK register definition*/
+ __IO uint32_t CFG_RTT_PARK;
+ struct
+ {
+ __IO uint32_t cfg_rtt_park :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTT_PARK_TypeDef;
+
+typedef union{ /*!< CFG_ODT_INBUF_4_PD register definition*/
+ __IO uint32_t CFG_ODT_INBUF_4_PD;
+ struct
+ {
+ __IO uint32_t cfg_odt_inbuf_4_pd :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_INBUF_4_PD_TypeDef;
+
+typedef union{ /*!< CFG_CA_PARITY_ERR_STATUS register definition*/
+ __IO uint32_t CFG_CA_PARITY_ERR_STATUS;
+ struct
+ {
+ __IO uint32_t cfg_ca_parity_err_status :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_PARITY_ERR_STATUS_TypeDef;
+
+typedef union{ /*!< CFG_CRC_ERROR_CLEAR register definition*/
+ __IO uint32_t CFG_CRC_ERROR_CLEAR;
+ struct
+ {
+ __IO uint32_t cfg_crc_error_clear :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CRC_ERROR_CLEAR_TypeDef;
+
+typedef union{ /*!< CFG_CA_PARITY_LATENCY register definition*/
+ __IO uint32_t CFG_CA_PARITY_LATENCY;
+ struct
+ {
+ __IO uint32_t cfg_ca_parity_latency :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_PARITY_LATENCY_TypeDef;
+
+typedef union{ /*!< CFG_CCD_S register definition*/
+ __IO uint32_t CFG_CCD_S;
+ struct
+ {
+ __IO uint32_t cfg_ccd_s :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CCD_S_TypeDef;
+
+typedef union{ /*!< CFG_CCD_L register definition*/
+ __IO uint32_t CFG_CCD_L;
+ struct
+ {
+ __IO uint32_t cfg_ccd_l :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_CCD_L_TypeDef;
+
+typedef union{ /*!< CFG_VREFDQ_TRN_ENABLE register definition*/
+ __IO uint32_t CFG_VREFDQ_TRN_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_vrefdq_trn_enable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_VREFDQ_TRN_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_VREFDQ_TRN_RANGE register definition*/
+ __IO uint32_t CFG_VREFDQ_TRN_RANGE;
+ struct
+ {
+ __IO uint32_t cfg_vrefdq_trn_range :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_VREFDQ_TRN_RANGE_TypeDef;
+
+typedef union{ /*!< CFG_VREFDQ_TRN_VALUE register definition*/
+ __IO uint32_t CFG_VREFDQ_TRN_VALUE;
+ struct
+ {
+ __IO uint32_t cfg_vrefdq_trn_value :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_VREFDQ_TRN_VALUE_TypeDef;
+
+typedef union{ /*!< CFG_RRD_S register definition*/
+ __IO uint32_t CFG_RRD_S;
+ struct
+ {
+ __IO uint32_t cfg_rrd_s :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_S_TypeDef;
+
+typedef union{ /*!< CFG_RRD_L register definition*/
+ __IO uint32_t CFG_RRD_L;
+ struct
+ {
+ __IO uint32_t cfg_rrd_l :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_L_TypeDef;
+
+typedef union{ /*!< CFG_WTR_S register definition*/
+ __IO uint32_t CFG_WTR_S;
+ struct
+ {
+ __IO uint32_t cfg_wtr_s :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_S_TypeDef;
+
+typedef union{ /*!< CFG_WTR_L register definition*/
+ __IO uint32_t CFG_WTR_L;
+ struct
+ {
+ __IO uint32_t cfg_wtr_l :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_L_TypeDef;
+
+typedef union{ /*!< CFG_WTR_S_CRC_DM register definition*/
+ __IO uint32_t CFG_WTR_S_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wtr_s_crc_dm :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_S_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_WTR_L_CRC_DM register definition*/
+ __IO uint32_t CFG_WTR_L_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wtr_l_crc_dm :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_L_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_WR_CRC_DM register definition*/
+ __IO uint32_t CFG_WR_CRC_DM;
+ struct
+ {
+ __IO uint32_t cfg_wr_crc_dm :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_CRC_DM_TypeDef;
+
+typedef union{ /*!< CFG_RFC1 register definition*/
+ __IO uint32_t CFG_RFC1;
+ struct
+ {
+ __IO uint32_t cfg_rfc1 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC1_TypeDef;
+
+typedef union{ /*!< CFG_RFC2 register definition*/
+ __IO uint32_t CFG_RFC2;
+ struct
+ {
+ __IO uint32_t cfg_rfc2 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC2_TypeDef;
+
+typedef union{ /*!< CFG_RFC4 register definition*/
+ __IO uint32_t CFG_RFC4;
+ struct
+ {
+ __IO uint32_t cfg_rfc4 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC4_TypeDef;
+
+typedef union{ /*!< CFG_NIBBLE_DEVICES register definition*/
+ __IO uint32_t CFG_NIBBLE_DEVICES;
+ struct
+ {
+ __IO uint32_t cfg_nibble_devices :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_NIBBLE_DEVICES_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS0_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS0_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs0_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS0_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS0_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs0_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS1_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS1_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS1_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS1_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs1_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS2_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS2_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS2_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS2_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs2_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS3_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS3_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs3_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS3_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS3_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs3_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS4_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS4_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs4_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS4_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS4_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs4_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS5_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS5_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs5_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS5_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS5_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs5_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS6_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS6_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs6_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS6_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS6_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs6_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS7_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS7_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs7_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS7_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS7_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs7_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS8_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS8_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs8_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS8_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS8_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs8_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS9_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS9_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs9_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS9_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS9_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs9_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS10_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS10_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs10_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS10_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS10_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs10_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS11_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS11_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs11_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS11_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS11_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs11_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS12_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS12_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs12_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS12_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS12_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs12_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS13_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS13_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs13_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS13_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS13_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs13_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS14_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS14_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs14_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS14_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS14_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs14_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_1_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS15_0 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS15_0;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs15_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_0_TypeDef;
+
+typedef union{ /*!< CFG_BIT_MAP_INDEX_CS15_1 register definition*/
+ __IO uint32_t CFG_BIT_MAP_INDEX_CS15_1;
+ struct
+ {
+ __IO uint32_t cfg_bit_map_index_cs15_1 :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_1_TypeDef;
+
+typedef union{ /*!< CFG_NUM_LOGICAL_RANKS_PER_3DS register definition*/
+ __IO uint32_t CFG_NUM_LOGICAL_RANKS_PER_3DS;
+ struct
+ {
+ __IO uint32_t cfg_num_logical_ranks_per_3ds :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_NUM_LOGICAL_RANKS_PER_3DS_TypeDef;
+
+typedef union{ /*!< CFG_RFC_DLR1 register definition*/
+ __IO uint32_t CFG_RFC_DLR1;
+ struct
+ {
+ __IO uint32_t cfg_rfc_dlr1 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_DLR1_TypeDef;
+
+typedef union{ /*!< CFG_RFC_DLR2 register definition*/
+ __IO uint32_t CFG_RFC_DLR2;
+ struct
+ {
+ __IO uint32_t cfg_rfc_dlr2 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_DLR2_TypeDef;
+
+typedef union{ /*!< CFG_RFC_DLR4 register definition*/
+ __IO uint32_t CFG_RFC_DLR4;
+ struct
+ {
+ __IO uint32_t cfg_rfc_dlr4 :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_DLR4_TypeDef;
+
+typedef union{ /*!< CFG_RRD_DLR register definition*/
+ __IO uint32_t CFG_RRD_DLR;
+ struct
+ {
+ __IO uint32_t cfg_rrd_dlr :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_DLR_TypeDef;
+
+typedef union{ /*!< CFG_FAW_DLR register definition*/
+ __IO uint32_t CFG_FAW_DLR;
+ struct
+ {
+ __IO uint32_t cfg_faw_dlr :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_FAW_DLR_TypeDef;
+
+typedef union{ /*!< CFG_ADVANCE_ACTIVATE_READY register definition*/
+ __IO uint32_t CFG_ADVANCE_ACTIVATE_READY;
+ struct
+ {
+ __IO uint32_t cfg_advance_activate_ready :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ADVANCE_ACTIVATE_READY_TypeDef;
+
+typedef union{ /*!< CTRLR_SOFT_RESET_N register definition*/
+ __IO uint32_t CTRLR_SOFT_RESET_N;
+ struct
+ {
+ __IO uint32_t ctrlr_soft_reset_n :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_SOFT_RESET_N_TypeDef;
+
+typedef union{ /*!< CFG_LOOKAHEAD_PCH register definition*/
+ __IO uint32_t CFG_LOOKAHEAD_PCH;
+ struct
+ {
+ __IO uint32_t cfg_lookahead_pch :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LOOKAHEAD_PCH_TypeDef;
+
+typedef union{ /*!< CFG_LOOKAHEAD_ACT register definition*/
+ __IO uint32_t CFG_LOOKAHEAD_ACT;
+ struct
+ {
+ __IO uint32_t cfg_lookahead_act :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LOOKAHEAD_ACT_TypeDef;
+
+typedef union{ /*!< INIT_AUTOINIT_DISABLE register definition*/
+ __IO uint32_t INIT_AUTOINIT_DISABLE;
+ struct
+ {
+ __IO uint32_t init_autoinit_disable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_AUTOINIT_DISABLE_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_RESET register definition*/
+ __IO uint32_t INIT_FORCE_RESET;
+ struct
+ {
+ __IO uint32_t init_force_reset :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_RESET_TypeDef;
+
+typedef union{ /*!< INIT_GEARDOWN_EN register definition*/
+ __IO uint32_t INIT_GEARDOWN_EN;
+ struct
+ {
+ __IO uint32_t init_geardown_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_GEARDOWN_EN_TypeDef;
+
+typedef union{ /*!< INIT_DISABLE_CKE register definition*/
+ __IO uint32_t INIT_DISABLE_CKE;
+ struct
+ {
+ __IO uint32_t init_disable_cke :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_DISABLE_CKE_TypeDef;
+
+typedef union{ /*!< INIT_CS register definition*/
+ __IO uint32_t INIT_CS;
+ struct
+ {
+ __IO uint32_t init_cs :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_CS_TypeDef;
+
+typedef union{ /*!< INIT_PRECHARGE_ALL register definition*/
+ __IO uint32_t INIT_PRECHARGE_ALL;
+ struct
+ {
+ __IO uint32_t init_precharge_all :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_PRECHARGE_ALL_TypeDef;
+
+typedef union{ /*!< INIT_REFRESH register definition*/
+ __IO uint32_t INIT_REFRESH;
+ struct
+ {
+ __IO uint32_t init_refresh :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_REFRESH_TypeDef;
+
+typedef union{ /*!< INIT_ZQ_CAL_REQ register definition*/
+ __IO uint32_t INIT_ZQ_CAL_REQ;
+ struct
+ {
+ __IO uint32_t init_zq_cal_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ZQ_CAL_REQ_TypeDef;
+
+typedef union{ /*!< INIT_ACK register definition*/
+ __I uint32_t INIT_ACK;
+ struct
+ {
+ __I uint32_t init_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ACK_TypeDef;
+
+typedef union{ /*!< CFG_BL register definition*/
+ __IO uint32_t CFG_BL;
+ struct
+ {
+ __IO uint32_t cfg_bl :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_BL_TypeDef;
+
+typedef union{ /*!< CTRLR_INIT register definition*/
+ __IO uint32_t CTRLR_INIT;
+ struct
+ {
+ __IO uint32_t ctrlr_init :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_INIT_TypeDef;
+
+typedef union{ /*!< CTRLR_INIT_DONE register definition*/
+ __I uint32_t CTRLR_INIT_DONE;
+ struct
+ {
+ __I uint32_t ctrlr_init_done :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_INIT_DONE_TypeDef;
+
+typedef union{ /*!< CFG_AUTO_REF_EN register definition*/
+ __IO uint32_t CFG_AUTO_REF_EN;
+ struct
+ {
+ __IO uint32_t cfg_auto_ref_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_AUTO_REF_EN_TypeDef;
+
+typedef union{ /*!< CFG_RAS register definition*/
+ __IO uint32_t CFG_RAS;
+ struct
+ {
+ __IO uint32_t cfg_ras :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_RAS_TypeDef;
+
+typedef union{ /*!< CFG_RCD register definition*/
+ __IO uint32_t CFG_RCD;
+ struct
+ {
+ __IO uint32_t cfg_rcd :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_RCD_TypeDef;
+
+typedef union{ /*!< CFG_RRD register definition*/
+ __IO uint32_t CFG_RRD;
+ struct
+ {
+ __IO uint32_t cfg_rrd :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RRD_TypeDef;
+
+typedef union{ /*!< CFG_RP register definition*/
+ __IO uint32_t CFG_RP;
+ struct
+ {
+ __IO uint32_t cfg_rp :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_RP_TypeDef;
+
+typedef union{ /*!< CFG_RC register definition*/
+ __IO uint32_t CFG_RC;
+ struct
+ {
+ __IO uint32_t cfg_rc :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_RC_TypeDef;
+
+typedef union{ /*!< CFG_FAW register definition*/
+ __IO uint32_t CFG_FAW;
+ struct
+ {
+ __IO uint32_t cfg_faw :9;
+ __I uint32_t reserved :23;
+ } bitfield;
+} DDR_CSR_APB_CFG_FAW_TypeDef;
+
+typedef union{ /*!< CFG_RFC register definition*/
+ __IO uint32_t CFG_RFC;
+ struct
+ {
+ __IO uint32_t cfg_rfc :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_RFC_TypeDef;
+
+typedef union{ /*!< CFG_RTP register definition*/
+ __IO uint32_t CFG_RTP;
+ struct
+ {
+ __IO uint32_t cfg_rtp :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTP_TypeDef;
+
+typedef union{ /*!< CFG_WR register definition*/
+ __IO uint32_t CFG_WR;
+ struct
+ {
+ __IO uint32_t cfg_wr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_TypeDef;
+
+typedef union{ /*!< CFG_WTR register definition*/
+ __IO uint32_t CFG_WTR;
+ struct
+ {
+ __IO uint32_t cfg_wtr :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WTR_TypeDef;
+
+typedef union{ /*!< CFG_PASR register definition*/
+ __IO uint32_t CFG_PASR;
+ struct
+ {
+ __IO uint32_t cfg_pasr :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_PASR_TypeDef;
+
+typedef union{ /*!< CFG_XP register definition*/
+ __IO uint32_t CFG_XP;
+ struct
+ {
+ __IO uint32_t cfg_xp :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_XP_TypeDef;
+
+typedef union{ /*!< CFG_XSR register definition*/
+ __IO uint32_t CFG_XSR;
+ struct
+ {
+ __IO uint32_t cfg_xsr :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_XSR_TypeDef;
+
+typedef union{ /*!< CFG_CL register definition*/
+ __IO uint32_t CFG_CL;
+ struct
+ {
+ __IO uint32_t cfg_cl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_CL_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_WRITE register definition*/
+ __IO uint32_t CFG_READ_TO_WRITE;
+ struct
+ {
+ __IO uint32_t cfg_read_to_write :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_WRITE_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_WRITE register definition*/
+ __IO uint32_t CFG_WRITE_TO_WRITE;
+ struct
+ {
+ __IO uint32_t cfg_write_to_write :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_WRITE_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_READ register definition*/
+ __IO uint32_t CFG_READ_TO_READ;
+ struct
+ {
+ __IO uint32_t cfg_read_to_read :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_READ_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_READ register definition*/
+ __IO uint32_t CFG_WRITE_TO_READ;
+ struct
+ {
+ __IO uint32_t cfg_write_to_read :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_READ_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_WRITE_ODT register definition*/
+ __IO uint32_t CFG_READ_TO_WRITE_ODT;
+ struct
+ {
+ __IO uint32_t cfg_read_to_write_odt :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_WRITE_ODT_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_WRITE_ODT register definition*/
+ __IO uint32_t CFG_WRITE_TO_WRITE_ODT;
+ struct
+ {
+ __IO uint32_t cfg_write_to_write_odt :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_WRITE_ODT_TypeDef;
+
+typedef union{ /*!< CFG_READ_TO_READ_ODT register definition*/
+ __IO uint32_t CFG_READ_TO_READ_ODT;
+ struct
+ {
+ __IO uint32_t cfg_read_to_read_odt :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_READ_TO_READ_ODT_TypeDef;
+
+typedef union{ /*!< CFG_WRITE_TO_READ_ODT register definition*/
+ __IO uint32_t CFG_WRITE_TO_READ_ODT;
+ struct
+ {
+ __IO uint32_t cfg_write_to_read_odt :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_WRITE_TO_READ_ODT_TypeDef;
+
+typedef union{ /*!< CFG_MIN_READ_IDLE register definition*/
+ __IO uint32_t CFG_MIN_READ_IDLE;
+ struct
+ {
+ __IO uint32_t cfg_min_read_idle :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_MIN_READ_IDLE_TypeDef;
+
+typedef union{ /*!< CFG_MRD register definition*/
+ __IO uint32_t CFG_MRD;
+ struct
+ {
+ __IO uint32_t cfg_mrd :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRD_TypeDef;
+
+typedef union{ /*!< CFG_BT register definition*/
+ __IO uint32_t CFG_BT;
+ struct
+ {
+ __IO uint32_t cfg_bt :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_BT_TypeDef;
+
+typedef union{ /*!< CFG_DS register definition*/
+ __IO uint32_t CFG_DS;
+ struct
+ {
+ __IO uint32_t cfg_ds :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_DS_TypeDef;
+
+typedef union{ /*!< CFG_QOFF register definition*/
+ __IO uint32_t CFG_QOFF;
+ struct
+ {
+ __IO uint32_t cfg_qoff :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_QOFF_TypeDef;
+
+typedef union{ /*!< CFG_RTT register definition*/
+ __IO uint32_t CFG_RTT;
+ struct
+ {
+ __IO uint32_t cfg_rtt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTT_TypeDef;
+
+typedef union{ /*!< CFG_DLL_DISABLE register definition*/
+ __IO uint32_t CFG_DLL_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_dll_disable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DLL_DISABLE_TypeDef;
+
+typedef union{ /*!< CFG_REF_PER register definition*/
+ __IO uint32_t CFG_REF_PER;
+ struct
+ {
+ __IO uint32_t cfg_ref_per :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_REF_PER_TypeDef;
+
+typedef union{ /*!< CFG_STARTUP_DELAY register definition*/
+ __IO uint32_t CFG_STARTUP_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_startup_delay :19;
+ __I uint32_t reserved :13;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARTUP_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_MEM_COLBITS register definition*/
+ __IO uint32_t CFG_MEM_COLBITS;
+ struct
+ {
+ __IO uint32_t cfg_mem_colbits :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_COLBITS_TypeDef;
+
+typedef union{ /*!< CFG_MEM_ROWBITS register definition*/
+ __IO uint32_t CFG_MEM_ROWBITS;
+ struct
+ {
+ __IO uint32_t cfg_mem_rowbits :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_ROWBITS_TypeDef;
+
+typedef union{ /*!< CFG_MEM_BANKBITS register definition*/
+ __IO uint32_t CFG_MEM_BANKBITS;
+ struct
+ {
+ __IO uint32_t cfg_mem_bankbits :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_BANKBITS_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS0 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS0;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs0 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS0_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS1 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS1;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs1 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS1_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS2 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS2;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS2_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS3 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS3;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs3 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS3_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS4 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS4;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs4 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS4_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS5 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS5;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs5 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS5_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS6 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS6;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs6 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS6_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_MAP_CS7 register definition*/
+ __IO uint32_t CFG_ODT_RD_MAP_CS7;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_map_cs7 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_MAP_CS7_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS0 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS0;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs0 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS0_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS1 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS1;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs1 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS1_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS2 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS2;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS2_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS3 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS3;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs3 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS3_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS4 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS4;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs4 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS4_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS5 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS5;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs5 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS5_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS6 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS6;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs6 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS6_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_MAP_CS7 register definition*/
+ __IO uint32_t CFG_ODT_WR_MAP_CS7;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_map_cs7 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_MAP_CS7_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_TURN_ON register definition*/
+ __IO uint32_t CFG_ODT_RD_TURN_ON;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_turn_on :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_TURN_ON_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_TURN_ON register definition*/
+ __IO uint32_t CFG_ODT_WR_TURN_ON;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_turn_on :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_TURN_ON_TypeDef;
+
+typedef union{ /*!< CFG_ODT_RD_TURN_OFF register definition*/
+ __IO uint32_t CFG_ODT_RD_TURN_OFF;
+ struct
+ {
+ __IO uint32_t cfg_odt_rd_turn_off :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_RD_TURN_OFF_TypeDef;
+
+typedef union{ /*!< CFG_ODT_WR_TURN_OFF register definition*/
+ __IO uint32_t CFG_ODT_WR_TURN_OFF;
+ struct
+ {
+ __IO uint32_t cfg_odt_wr_turn_off :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_WR_TURN_OFF_TypeDef;
+
+typedef union{ /*!< CFG_EMR3 register definition*/
+ __IO uint32_t CFG_EMR3;
+ struct
+ {
+ __IO uint32_t cfg_emr3 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_EMR3_TypeDef;
+
+typedef union{ /*!< CFG_TWO_T register definition*/
+ __IO uint32_t CFG_TWO_T;
+ struct
+ {
+ __IO uint32_t cfg_two_t :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TWO_T_TypeDef;
+
+typedef union{ /*!< CFG_TWO_T_SEL_CYCLE register definition*/
+ __IO uint32_t CFG_TWO_T_SEL_CYCLE;
+ struct
+ {
+ __IO uint32_t cfg_two_t_sel_cycle :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TWO_T_SEL_CYCLE_TypeDef;
+
+typedef union{ /*!< CFG_REGDIMM register definition*/
+ __IO uint32_t CFG_REGDIMM;
+ struct
+ {
+ __IO uint32_t cfg_regdimm :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REGDIMM_TypeDef;
+
+typedef union{ /*!< CFG_MOD register definition*/
+ __IO uint32_t CFG_MOD;
+ struct
+ {
+ __IO uint32_t cfg_mod :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_MOD_TypeDef;
+
+typedef union{ /*!< CFG_XS register definition*/
+ __IO uint32_t CFG_XS;
+ struct
+ {
+ __IO uint32_t cfg_xs :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_XS_TypeDef;
+
+typedef union{ /*!< CFG_XSDLL register definition*/
+ __IO uint32_t CFG_XSDLL;
+ struct
+ {
+ __IO uint32_t cfg_xsdll :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_XSDLL_TypeDef;
+
+typedef union{ /*!< CFG_XPR register definition*/
+ __IO uint32_t CFG_XPR;
+ struct
+ {
+ __IO uint32_t cfg_xpr :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_XPR_TypeDef;
+
+typedef union{ /*!< CFG_AL_MODE register definition*/
+ __IO uint32_t CFG_AL_MODE;
+ struct
+ {
+ __IO uint32_t cfg_al_mode :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AL_MODE_TypeDef;
+
+typedef union{ /*!< CFG_CWL register definition*/
+ __IO uint32_t CFG_CWL;
+ struct
+ {
+ __IO uint32_t cfg_cwl :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_CWL_TypeDef;
+
+typedef union{ /*!< CFG_BL_MODE register definition*/
+ __IO uint32_t CFG_BL_MODE;
+ struct
+ {
+ __IO uint32_t cfg_bl_mode :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_BL_MODE_TypeDef;
+
+typedef union{ /*!< CFG_TDQS register definition*/
+ __IO uint32_t CFG_TDQS;
+ struct
+ {
+ __IO uint32_t cfg_tdqs :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TDQS_TypeDef;
+
+typedef union{ /*!< CFG_RTT_WR register definition*/
+ __IO uint32_t CFG_RTT_WR;
+ struct
+ {
+ __IO uint32_t cfg_rtt_wr :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RTT_WR_TypeDef;
+
+typedef union{ /*!< CFG_LP_ASR register definition*/
+ __IO uint32_t CFG_LP_ASR;
+ struct
+ {
+ __IO uint32_t cfg_lp_asr :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_LP_ASR_TypeDef;
+
+typedef union{ /*!< CFG_AUTO_SR register definition*/
+ __IO uint32_t CFG_AUTO_SR;
+ struct
+ {
+ __IO uint32_t cfg_auto_sr :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_AUTO_SR_TypeDef;
+
+typedef union{ /*!< CFG_SRT register definition*/
+ __IO uint32_t CFG_SRT;
+ struct
+ {
+ __IO uint32_t cfg_srt :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_SRT_TypeDef;
+
+typedef union{ /*!< CFG_ADDR_MIRROR register definition*/
+ __IO uint32_t CFG_ADDR_MIRROR;
+ struct
+ {
+ __IO uint32_t cfg_addr_mirror :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ADDR_MIRROR_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_TYPE register definition*/
+ __IO uint32_t CFG_ZQ_CAL_TYPE;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_type :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_TYPE_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_PER register definition*/
+ __IO uint32_t CFG_ZQ_CAL_PER;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_per :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_PER_TypeDef;
+
+typedef union{ /*!< CFG_AUTO_ZQ_CAL_EN register definition*/
+ __IO uint32_t CFG_AUTO_ZQ_CAL_EN;
+ struct
+ {
+ __IO uint32_t cfg_auto_zq_cal_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_AUTO_ZQ_CAL_EN_TypeDef;
+
+typedef union{ /*!< CFG_MEMORY_TYPE register definition*/
+ __IO uint32_t CFG_MEMORY_TYPE;
+ struct
+ {
+ __IO uint32_t cfg_memory_type :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEMORY_TYPE_TypeDef;
+
+typedef union{ /*!< CFG_ONLY_SRANK_CMDS register definition*/
+ __IO uint32_t CFG_ONLY_SRANK_CMDS;
+ struct
+ {
+ __IO uint32_t cfg_only_srank_cmds :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ONLY_SRANK_CMDS_TypeDef;
+
+typedef union{ /*!< CFG_NUM_RANKS register definition*/
+ __IO uint32_t CFG_NUM_RANKS;
+ struct
+ {
+ __IO uint32_t cfg_num_ranks :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_NUM_RANKS_TypeDef;
+
+typedef union{ /*!< CFG_QUAD_RANK register definition*/
+ __IO uint32_t CFG_QUAD_RANK;
+ struct
+ {
+ __IO uint32_t cfg_quad_rank :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_QUAD_RANK_TypeDef;
+
+typedef union{ /*!< CFG_EARLY_RANK_TO_WR_START register definition*/
+ __IO uint32_t CFG_EARLY_RANK_TO_WR_START;
+ struct
+ {
+ __IO uint32_t cfg_early_rank_to_wr_start :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_EARLY_RANK_TO_WR_START_TypeDef;
+
+typedef union{ /*!< CFG_EARLY_RANK_TO_RD_START register definition*/
+ __IO uint32_t CFG_EARLY_RANK_TO_RD_START;
+ struct
+ {
+ __IO uint32_t cfg_early_rank_to_rd_start :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_EARLY_RANK_TO_RD_START_TypeDef;
+
+typedef union{ /*!< CFG_PASR_BANK register definition*/
+ __IO uint32_t CFG_PASR_BANK;
+ struct
+ {
+ __IO uint32_t cfg_pasr_bank :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_PASR_BANK_TypeDef;
+
+typedef union{ /*!< CFG_PASR_SEG register definition*/
+ __IO uint32_t CFG_PASR_SEG;
+ struct
+ {
+ __IO uint32_t cfg_pasr_seg :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_PASR_SEG_TypeDef;
+
+typedef union{ /*!< INIT_MRR_MODE register definition*/
+ __IO uint32_t INIT_MRR_MODE;
+ struct
+ {
+ __IO uint32_t init_mrr_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_MRR_MODE_TypeDef;
+
+typedef union{ /*!< INIT_MR_W_REQ register definition*/
+ __IO uint32_t INIT_MR_W_REQ;
+ struct
+ {
+ __IO uint32_t init_mr_w_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_W_REQ_TypeDef;
+
+typedef union{ /*!< INIT_MR_ADDR register definition*/
+ __IO uint32_t INIT_MR_ADDR;
+ struct
+ {
+ __IO uint32_t init_mr_addr :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_ADDR_TypeDef;
+
+typedef union{ /*!< INIT_MR_WR_DATA register definition*/
+ __IO uint32_t INIT_MR_WR_DATA;
+ struct
+ {
+ __IO uint32_t init_mr_wr_data :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_WR_DATA_TypeDef;
+
+typedef union{ /*!< INIT_MR_WR_MASK register definition*/
+ __IO uint32_t INIT_MR_WR_MASK;
+ struct
+ {
+ __IO uint32_t init_mr_wr_mask :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_INIT_MR_WR_MASK_TypeDef;
+
+typedef union{ /*!< INIT_NOP register definition*/
+ __IO uint32_t INIT_NOP;
+ struct
+ {
+ __IO uint32_t init_nop :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_NOP_TypeDef;
+
+typedef union{ /*!< CFG_INIT_DURATION register definition*/
+ __IO uint32_t CFG_INIT_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_init_duration :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_INIT_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQINIT_CAL_DURATION register definition*/
+ __IO uint32_t CFG_ZQINIT_CAL_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zqinit_cal_duration :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQINIT_CAL_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_L_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_L_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_l_duration :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_L_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_S_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_S_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_s_duration :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_S_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_R_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_R_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_r_duration :11;
+ __I uint32_t reserved :21;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_R_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_MRR register definition*/
+ __IO uint32_t CFG_MRR;
+ struct
+ {
+ __IO uint32_t cfg_mrr :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRR_TypeDef;
+
+typedef union{ /*!< CFG_MRW register definition*/
+ __IO uint32_t CFG_MRW;
+ struct
+ {
+ __IO uint32_t cfg_mrw :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRW_TypeDef;
+
+typedef union{ /*!< CFG_ODT_POWERDOWN register definition*/
+ __IO uint32_t CFG_ODT_POWERDOWN;
+ struct
+ {
+ __IO uint32_t cfg_odt_powerdown :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ODT_POWERDOWN_TypeDef;
+
+typedef union{ /*!< CFG_WL register definition*/
+ __IO uint32_t CFG_WL;
+ struct
+ {
+ __IO uint32_t cfg_wl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_WL_TypeDef;
+
+typedef union{ /*!< CFG_RL register definition*/
+ __IO uint32_t CFG_RL;
+ struct
+ {
+ __IO uint32_t cfg_rl :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_RL_TypeDef;
+
+typedef union{ /*!< CFG_CAL_READ_PERIOD register definition*/
+ __IO uint32_t CFG_CAL_READ_PERIOD;
+ struct
+ {
+ __IO uint32_t cfg_cal_read_period :22;
+ __I uint32_t reserved :10;
+ } bitfield;
+} DDR_CSR_APB_CFG_CAL_READ_PERIOD_TypeDef;
+
+typedef union{ /*!< CFG_NUM_CAL_READS register definition*/
+ __IO uint32_t CFG_NUM_CAL_READS;
+ struct
+ {
+ __IO uint32_t cfg_num_cal_reads :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_NUM_CAL_READS_TypeDef;
+
+typedef union{ /*!< INIT_SELF_REFRESH register definition*/
+ __IO uint32_t INIT_SELF_REFRESH;
+ struct
+ {
+ __IO uint32_t init_self_refresh :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_SELF_REFRESH_TypeDef;
+
+typedef union{ /*!< INIT_SELF_REFRESH_STATUS register definition*/
+ __I uint32_t INIT_SELF_REFRESH_STATUS;
+ struct
+ {
+ __I uint32_t init_self_refresh_status :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_SELF_REFRESH_STATUS_TypeDef;
+
+typedef union{ /*!< INIT_POWER_DOWN register definition*/
+ __IO uint32_t INIT_POWER_DOWN;
+ struct
+ {
+ __IO uint32_t init_power_down :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_POWER_DOWN_TypeDef;
+
+typedef union{ /*!< INIT_POWER_DOWN_STATUS register definition*/
+ __I uint32_t INIT_POWER_DOWN_STATUS;
+ struct
+ {
+ __I uint32_t init_power_down_status :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_POWER_DOWN_STATUS_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_WRITE register definition*/
+ __IO uint32_t INIT_FORCE_WRITE;
+ struct
+ {
+ __IO uint32_t init_force_write :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_WRITE_TypeDef;
+
+typedef union{ /*!< INIT_FORCE_WRITE_CS register definition*/
+ __IO uint32_t INIT_FORCE_WRITE_CS;
+ struct
+ {
+ __IO uint32_t init_force_write_cs :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_INIT_FORCE_WRITE_CS_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_INIT_DISABLE register definition*/
+ __IO uint32_t CFG_CTRLR_INIT_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_init_disable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_INIT_DISABLE_TypeDef;
+
+typedef union{ /*!< CTRLR_READY register definition*/
+ __I uint32_t CTRLR_READY;
+ struct
+ {
+ __I uint32_t ctrlr_ready :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CTRLR_READY_TypeDef;
+
+typedef union{ /*!< INIT_RDIMM_READY register definition*/
+ __I uint32_t INIT_RDIMM_READY;
+ struct
+ {
+ __I uint32_t init_rdimm_ready :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RDIMM_READY_TypeDef;
+
+typedef union{ /*!< INIT_RDIMM_COMPLETE register definition*/
+ __IO uint32_t INIT_RDIMM_COMPLETE;
+ struct
+ {
+ __IO uint32_t init_rdimm_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RDIMM_COMPLETE_TypeDef;
+
+typedef union{ /*!< CFG_RDIMM_LAT register definition*/
+ __IO uint32_t CFG_RDIMM_LAT;
+ struct
+ {
+ __IO uint32_t cfg_rdimm_lat :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_RDIMM_LAT_TypeDef;
+
+typedef union{ /*!< CFG_RDIMM_BSIDE_INVERT register definition*/
+ __IO uint32_t CFG_RDIMM_BSIDE_INVERT;
+ struct
+ {
+ __IO uint32_t cfg_rdimm_bside_invert :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RDIMM_BSIDE_INVERT_TypeDef;
+
+typedef union{ /*!< CFG_LRDIMM register definition*/
+ __IO uint32_t CFG_LRDIMM;
+ struct
+ {
+ __IO uint32_t cfg_lrdimm :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_LRDIMM_TypeDef;
+
+typedef union{ /*!< INIT_MEMORY_RESET_MASK register definition*/
+ __IO uint32_t INIT_MEMORY_RESET_MASK;
+ struct
+ {
+ __IO uint32_t init_memory_reset_mask :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_MEMORY_RESET_MASK_TypeDef;
+
+typedef union{ /*!< CFG_RD_PREAMB_TOGGLE register definition*/
+ __IO uint32_t CFG_RD_PREAMB_TOGGLE;
+ struct
+ {
+ __IO uint32_t cfg_rd_preamb_toggle :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_PREAMB_TOGGLE_TypeDef;
+
+typedef union{ /*!< CFG_RD_POSTAMBLE register definition*/
+ __IO uint32_t CFG_RD_POSTAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_rd_postamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RD_POSTAMBLE_TypeDef;
+
+typedef union{ /*!< CFG_PU_CAL register definition*/
+ __IO uint32_t CFG_PU_CAL;
+ struct
+ {
+ __IO uint32_t cfg_pu_cal :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_PU_CAL_TypeDef;
+
+typedef union{ /*!< CFG_DQ_ODT register definition*/
+ __IO uint32_t CFG_DQ_ODT;
+ struct
+ {
+ __IO uint32_t cfg_dq_odt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_DQ_ODT_TypeDef;
+
+typedef union{ /*!< CFG_CA_ODT register definition*/
+ __IO uint32_t CFG_CA_ODT;
+ struct
+ {
+ __IO uint32_t cfg_ca_odt :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CA_ODT_TypeDef;
+
+typedef union{ /*!< CFG_ZQLATCH_DURATION register definition*/
+ __IO uint32_t CFG_ZQLATCH_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zqlatch_duration :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQLATCH_DURATION_TypeDef;
+
+typedef union{ /*!< INIT_CAL_SELECT register definition*/
+ __IO uint32_t INIT_CAL_SELECT;
+ struct
+ {
+ __IO uint32_t init_cal_select :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_SELECT_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_R_REQ register definition*/
+ __IO uint32_t INIT_CAL_L_R_REQ;
+ struct
+ {
+ __IO uint32_t init_cal_l_r_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_R_REQ_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_B_SIZE register definition*/
+ __IO uint32_t INIT_CAL_L_B_SIZE;
+ struct
+ {
+ __IO uint32_t init_cal_l_b_size :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_B_SIZE_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_R_ACK register definition*/
+ __I uint32_t INIT_CAL_L_R_ACK;
+ struct
+ {
+ __I uint32_t init_cal_l_r_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_R_ACK_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_READ_COMPLETE register definition*/
+ __I uint32_t INIT_CAL_L_READ_COMPLETE;
+ struct
+ {
+ __I uint32_t init_cal_l_read_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_READ_COMPLETE_TypeDef;
+
+typedef union{ /*!< INIT_RWFIFO register definition*/
+ __IO uint32_t INIT_RWFIFO;
+ struct
+ {
+ __IO uint32_t init_rwfifo :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RWFIFO_TypeDef;
+
+typedef union{ /*!< INIT_RD_DQCAL register definition*/
+ __IO uint32_t INIT_RD_DQCAL;
+ struct
+ {
+ __IO uint32_t init_rd_dqcal :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_RD_DQCAL_TypeDef;
+
+typedef union{ /*!< INIT_START_DQSOSC register definition*/
+ __IO uint32_t INIT_START_DQSOSC;
+ struct
+ {
+ __IO uint32_t init_start_dqsosc :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_START_DQSOSC_TypeDef;
+
+typedef union{ /*!< INIT_STOP_DQSOSC register definition*/
+ __IO uint32_t INIT_STOP_DQSOSC;
+ struct
+ {
+ __IO uint32_t init_stop_dqsosc :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_STOP_DQSOSC_TypeDef;
+
+typedef union{ /*!< INIT_ZQ_CAL_START register definition*/
+ __IO uint32_t INIT_ZQ_CAL_START;
+ struct
+ {
+ __IO uint32_t init_zq_cal_start :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ZQ_CAL_START_TypeDef;
+
+typedef union{ /*!< CFG_WR_POSTAMBLE register definition*/
+ __IO uint32_t CFG_WR_POSTAMBLE;
+ struct
+ {
+ __IO uint32_t cfg_wr_postamble :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_WR_POSTAMBLE_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_ADDR_0 register definition*/
+ __IO uint32_t INIT_CAL_L_ADDR_0;
+ struct
+ {
+ __IO uint32_t init_cal_l_addr_0 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_ADDR_0_TypeDef;
+
+typedef union{ /*!< INIT_CAL_L_ADDR_1 register definition*/
+ __IO uint32_t INIT_CAL_L_ADDR_1;
+ struct
+ {
+ __IO uint32_t init_cal_l_addr_1 :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_INIT_CAL_L_ADDR_1_TypeDef;
+
+typedef union{ /*!< CFG_CTRLUPD_TRIG register definition*/
+ __IO uint32_t CFG_CTRLUPD_TRIG;
+ struct
+ {
+ __IO uint32_t cfg_ctrlupd_trig :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLUPD_TRIG_TypeDef;
+
+typedef union{ /*!< CFG_CTRLUPD_START_DELAY register definition*/
+ __IO uint32_t CFG_CTRLUPD_START_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_ctrlupd_start_delay :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLUPD_START_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_CTRLUPD_MAX register definition*/
+ __IO uint32_t CFG_DFI_T_CTRLUPD_MAX;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_ctrlupd_max :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_CTRLUPD_MAX_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_SEL register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_SEL;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_sel :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_SEL_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_VALUE register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_VALUE;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_value :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_VALUE_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_TURN_OFF_DELAY register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_TURN_OFF_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_turn_off_delay :9;
+ __I uint32_t reserved :23;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_TURN_OFF_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_slow_restart_window :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_RESTART_HOLDOFF register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_RESTART_HOLDOFF;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_restart_holdoff :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_RESTART_HOLDOFF_TypeDef;
+
+typedef union{ /*!< CFG_PARITY_RDIMM_DELAY register definition*/
+ __IO uint32_t CFG_PARITY_RDIMM_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_parity_rdimm_delay :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_PARITY_RDIMM_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_CTRLR_BUSY_ENABLE register definition*/
+ __IO uint32_t CFG_CTRLR_BUSY_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_ctrlr_busy_enable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_CTRLR_BUSY_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_ASYNC_ODT register definition*/
+ __IO uint32_t CFG_ASYNC_ODT;
+ struct
+ {
+ __IO uint32_t cfg_async_odt :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ASYNC_ODT_TypeDef;
+
+typedef union{ /*!< CFG_ZQ_CAL_DURATION register definition*/
+ __IO uint32_t CFG_ZQ_CAL_DURATION;
+ struct
+ {
+ __IO uint32_t cfg_zq_cal_duration :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_ZQ_CAL_DURATION_TypeDef;
+
+typedef union{ /*!< CFG_MRRI register definition*/
+ __IO uint32_t CFG_MRRI;
+ struct
+ {
+ __IO uint32_t cfg_mrri :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_MRRI_TypeDef;
+
+typedef union{ /*!< INIT_ODT_FORCE_EN register definition*/
+ __IO uint32_t INIT_ODT_FORCE_EN;
+ struct
+ {
+ __IO uint32_t init_odt_force_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_ODT_FORCE_EN_TypeDef;
+
+typedef union{ /*!< INIT_ODT_FORCE_RANK register definition*/
+ __IO uint32_t INIT_ODT_FORCE_RANK;
+ struct
+ {
+ __IO uint32_t init_odt_force_rank :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_INIT_ODT_FORCE_RANK_TypeDef;
+
+typedef union{ /*!< CFG_PHYUPD_ACK_DELAY register definition*/
+ __IO uint32_t CFG_PHYUPD_ACK_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_phyupd_ack_delay :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_CFG_PHYUPD_ACK_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_MIRROR_X16_BG0_BG1 register definition*/
+ __IO uint32_t CFG_MIRROR_X16_BG0_BG1;
+ struct
+ {
+ __IO uint32_t cfg_mirror_x16_bg0_bg1 :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MIRROR_X16_BG0_BG1_TypeDef;
+
+typedef union{ /*!< INIT_PDA_MR_W_REQ register definition*/
+ __IO uint32_t INIT_PDA_MR_W_REQ;
+ struct
+ {
+ __IO uint32_t init_pda_mr_w_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_PDA_MR_W_REQ_TypeDef;
+
+typedef union{ /*!< INIT_PDA_NIBBLE_SELECT register definition*/
+ __IO uint32_t INIT_PDA_NIBBLE_SELECT;
+ struct
+ {
+ __IO uint32_t init_pda_nibble_select :18;
+ __I uint32_t reserved :14;
+ } bitfield;
+} DDR_CSR_APB_INIT_PDA_NIBBLE_SELECT_TypeDef;
+
+typedef union{ /*!< CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH register definition*/
+ __IO uint32_t CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH;
+ struct
+ {
+ __IO uint32_t cfg_dram_clk_disable_in_self_refresh :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH_TypeDef;
+
+typedef union{ /*!< CFG_CKSRE register definition*/
+ __IO uint32_t CFG_CKSRE;
+ struct
+ {
+ __IO uint32_t cfg_cksre :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_CKSRE_TypeDef;
+
+typedef union{ /*!< CFG_CKSRX register definition*/
+ __IO uint32_t CFG_CKSRX;
+ struct
+ {
+ __IO uint32_t cfg_cksrx :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_CKSRX_TypeDef;
+
+typedef union{ /*!< CFG_RCD_STAB register definition*/
+ __IO uint32_t CFG_RCD_STAB;
+ struct
+ {
+ __IO uint32_t cfg_rcd_stab :14;
+ __I uint32_t reserved :18;
+ } bitfield;
+} DDR_CSR_APB_CFG_RCD_STAB_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_CTRL_DELAY register definition*/
+ __IO uint32_t CFG_DFI_T_CTRL_DELAY;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_ctrl_delay :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_CTRL_DELAY_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_DRAM_CLK_ENABLE register definition*/
+ __IO uint32_t CFG_DFI_T_DRAM_CLK_ENABLE;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_dram_clk_enable :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_DRAM_CLK_ENABLE_TypeDef;
+
+typedef union{ /*!< CFG_IDLE_TIME_TO_SELF_REFRESH register definition*/
+ __IO uint32_t CFG_IDLE_TIME_TO_SELF_REFRESH;
+ struct
+ {
+ __IO uint32_t cfg_idle_time_to_self_refresh :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_IDLE_TIME_TO_SELF_REFRESH_TypeDef;
+
+typedef union{ /*!< CFG_IDLE_TIME_TO_POWER_DOWN register definition*/
+ __IO uint32_t CFG_IDLE_TIME_TO_POWER_DOWN;
+ struct
+ {
+ __IO uint32_t cfg_idle_time_to_power_down :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_IDLE_TIME_TO_POWER_DOWN_TypeDef;
+
+typedef union{ /*!< CFG_BURST_RW_REFRESH_HOLDOFF register definition*/
+ __IO uint32_t CFG_BURST_RW_REFRESH_HOLDOFF;
+ struct
+ {
+ __IO uint32_t cfg_burst_rw_refresh_holdoff :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_BURST_RW_REFRESH_HOLDOFF_TypeDef;
+
+typedef union{ /*!< INIT_REFRESH_COUNT register definition*/
+ __I uint32_t INIT_REFRESH_COUNT;
+ struct
+ {
+ __I uint32_t init_refresh_count :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_INIT_REFRESH_COUNT_TypeDef;
+
+typedef union{ /*!< CFG_BG_INTERLEAVE register definition*/
+ __IO uint32_t CFG_BG_INTERLEAVE;
+ struct
+ {
+ __IO uint32_t cfg_bg_interleave :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_BG_INTERLEAVE_TypeDef;
+
+typedef union{ /*!< CFG_REFRESH_DURING_PHY_TRAINING register definition*/
+ __IO uint32_t CFG_REFRESH_DURING_PHY_TRAINING;
+ struct
+ {
+ __IO uint32_t cfg_refresh_during_phy_training :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REFRESH_DURING_PHY_TRAINING_TypeDef;
+
+typedef union{ /*!< MT_EN register definition*/
+ __IO uint32_t MT_EN;
+ struct
+ {
+ __IO uint32_t mt_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_EN_TypeDef;
+
+typedef union{ /*!< MT_EN_SINGLE register definition*/
+ __IO uint32_t MT_EN_SINGLE;
+ struct
+ {
+ __IO uint32_t mt_en_single :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_EN_SINGLE_TypeDef;
+
+typedef union{ /*!< MT_STOP_ON_ERROR register definition*/
+ __IO uint32_t MT_STOP_ON_ERROR;
+ struct
+ {
+ __IO uint32_t mt_stop_on_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_STOP_ON_ERROR_TypeDef;
+
+typedef union{ /*!< MT_RD_ONLY register definition*/
+ __IO uint32_t MT_RD_ONLY;
+ struct
+ {
+ __IO uint32_t mt_rd_only :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_RD_ONLY_TypeDef;
+
+typedef union{ /*!< MT_WR_ONLY register definition*/
+ __IO uint32_t MT_WR_ONLY;
+ struct
+ {
+ __IO uint32_t mt_wr_only :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_WR_ONLY_TypeDef;
+
+typedef union{ /*!< MT_DATA_PATTERN register definition*/
+ __IO uint32_t MT_DATA_PATTERN;
+ struct
+ {
+ __IO uint32_t mt_data_pattern :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_MT_DATA_PATTERN_TypeDef;
+
+typedef union{ /*!< MT_ADDR_PATTERN register definition*/
+ __IO uint32_t MT_ADDR_PATTERN;
+ struct
+ {
+ __IO uint32_t mt_addr_pattern :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_MT_ADDR_PATTERN_TypeDef;
+
+typedef union{ /*!< MT_DATA_INVERT register definition*/
+ __IO uint32_t MT_DATA_INVERT;
+ struct
+ {
+ __IO uint32_t mt_data_invert :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_DATA_INVERT_TypeDef;
+
+typedef union{ /*!< MT_ADDR_BITS register definition*/
+ __IO uint32_t MT_ADDR_BITS;
+ struct
+ {
+ __IO uint32_t mt_addr_bits :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MT_ADDR_BITS_TypeDef;
+
+typedef union{ /*!< MT_ERROR_STS register definition*/
+ __I uint32_t MT_ERROR_STS;
+ struct
+ {
+ __I uint32_t mt_error_sts :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_STS_TypeDef;
+
+typedef union{ /*!< MT_DONE_ACK register definition*/
+ __I uint32_t MT_DONE_ACK;
+ struct
+ {
+ __I uint32_t mt_done_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_DONE_ACK_TypeDef;
+
+typedef union{ /*!< MT_START_ADDR_0 register definition*/
+ __IO uint32_t MT_START_ADDR_0;
+ struct
+ {
+ __IO uint32_t mt_start_addr_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_START_ADDR_0_TypeDef;
+
+typedef union{ /*!< MT_START_ADDR_1 register definition*/
+ __IO uint32_t MT_START_ADDR_1;
+ struct
+ {
+ __IO uint32_t mt_start_addr_1 :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_MT_START_ADDR_1_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_0 register definition*/
+ __IO uint32_t MT_ERROR_MASK_0;
+ struct
+ {
+ __IO uint32_t mt_error_mask_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_0_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_1 register definition*/
+ __IO uint32_t MT_ERROR_MASK_1;
+ struct
+ {
+ __IO uint32_t mt_error_mask_1 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_1_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_2 register definition*/
+ __IO uint32_t MT_ERROR_MASK_2;
+ struct
+ {
+ __IO uint32_t mt_error_mask_2 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_2_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_3 register definition*/
+ __IO uint32_t MT_ERROR_MASK_3;
+ struct
+ {
+ __IO uint32_t mt_error_mask_3 :32;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_3_TypeDef;
+
+typedef union{ /*!< MT_ERROR_MASK_4 register definition*/
+ __IO uint32_t MT_ERROR_MASK_4;
+ struct
+ {
+ __IO uint32_t mt_error_mask_4 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_MT_ERROR_MASK_4_TypeDef;
+
+typedef union{ /*!< MT_USER_DATA_PATTERN register definition*/
+ __IO uint32_t MT_USER_DATA_PATTERN;
+ struct
+ {
+ __IO uint32_t mt_user_data_pattern :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_MT_USER_DATA_PATTERN_TypeDef;
+
+typedef union{ /*!< MT_ALG_AUTO_PCH register definition*/
+ __IO uint32_t MT_ALG_AUTO_PCH;
+ struct
+ {
+ __IO uint32_t mt_alg_auto_pch :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MT_ALG_AUTO_PCH_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P0 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P0;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p0 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P0_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P1 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P1;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p1 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P1_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P2 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P2;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p2 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P2_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P3 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P3;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p3 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P3_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P4 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P4;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p4 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P4_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P5 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P5;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p5 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P5_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P6 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P6;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p6 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P6_TypeDef;
+
+typedef union{ /*!< CFG_STARVE_TIMEOUT_P7 register definition*/
+ __IO uint32_t CFG_STARVE_TIMEOUT_P7;
+ struct
+ {
+ __IO uint32_t cfg_starve_timeout_p7 :12;
+ __I uint32_t reserved :20;
+ } bitfield;
+} DDR_CSR_APB_CFG_STARVE_TIMEOUT_P7_TypeDef;
+
+typedef union{ /*!< CFG_REORDER_EN register definition*/
+ __IO uint32_t CFG_REORDER_EN;
+ struct
+ {
+ __IO uint32_t cfg_reorder_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REORDER_EN_TypeDef;
+
+typedef union{ /*!< CFG_REORDER_QUEUE_EN register definition*/
+ __IO uint32_t CFG_REORDER_QUEUE_EN;
+ struct
+ {
+ __IO uint32_t cfg_reorder_queue_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REORDER_QUEUE_EN_TypeDef;
+
+typedef union{ /*!< CFG_INTRAPORT_REORDER_EN register definition*/
+ __IO uint32_t CFG_INTRAPORT_REORDER_EN;
+ struct
+ {
+ __IO uint32_t cfg_intraport_reorder_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_INTRAPORT_REORDER_EN_TypeDef;
+
+typedef union{ /*!< CFG_MAINTAIN_COHERENCY register definition*/
+ __IO uint32_t CFG_MAINTAIN_COHERENCY;
+ struct
+ {
+ __IO uint32_t cfg_maintain_coherency :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_MAINTAIN_COHERENCY_TypeDef;
+
+typedef union{ /*!< CFG_Q_AGE_LIMIT register definition*/
+ __IO uint32_t CFG_Q_AGE_LIMIT;
+ struct
+ {
+ __IO uint32_t cfg_q_age_limit :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_Q_AGE_LIMIT_TypeDef;
+
+typedef union{ /*!< CFG_RO_CLOSED_PAGE_POLICY register definition*/
+ __IO uint32_t CFG_RO_CLOSED_PAGE_POLICY;
+ struct
+ {
+ __IO uint32_t cfg_ro_closed_page_policy :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RO_CLOSED_PAGE_POLICY_TypeDef;
+
+typedef union{ /*!< CFG_REORDER_RW_ONLY register definition*/
+ __IO uint32_t CFG_REORDER_RW_ONLY;
+ struct
+ {
+ __IO uint32_t cfg_reorder_rw_only :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_REORDER_RW_ONLY_TypeDef;
+
+typedef union{ /*!< CFG_RO_PRIORITY_EN register definition*/
+ __IO uint32_t CFG_RO_PRIORITY_EN;
+ struct
+ {
+ __IO uint32_t cfg_ro_priority_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RO_PRIORITY_EN_TypeDef;
+
+typedef union{ /*!< CFG_DM_EN register definition*/
+ __IO uint32_t CFG_DM_EN;
+ struct
+ {
+ __IO uint32_t cfg_dm_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DM_EN_TypeDef;
+
+typedef union{ /*!< CFG_RMW_EN register definition*/
+ __IO uint32_t CFG_RMW_EN;
+ struct
+ {
+ __IO uint32_t cfg_rmw_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_RMW_EN_TypeDef;
+
+typedef union{ /*!< CFG_ECC_CORRECTION_EN register definition*/
+ __IO uint32_t CFG_ECC_CORRECTION_EN;
+ struct
+ {
+ __IO uint32_t cfg_ecc_correction_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ECC_CORRECTION_EN_TypeDef;
+
+typedef union{ /*!< CFG_ECC_BYPASS register definition*/
+ __IO uint32_t CFG_ECC_BYPASS;
+ struct
+ {
+ __IO uint32_t cfg_ecc_bypass :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ECC_BYPASS_TypeDef;
+
+typedef union{ /*!< INIT_WRITE_DATA_1B_ECC_ERROR_GEN register definition*/
+ __IO uint32_t INIT_WRITE_DATA_1B_ECC_ERROR_GEN;
+ struct
+ {
+ __IO uint32_t init_write_data_1b_ecc_error_gen :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_INIT_WRITE_DATA_1B_ECC_ERROR_GEN_TypeDef;
+
+typedef union{ /*!< INIT_WRITE_DATA_2B_ECC_ERROR_GEN register definition*/
+ __IO uint32_t INIT_WRITE_DATA_2B_ECC_ERROR_GEN;
+ struct
+ {
+ __IO uint32_t init_write_data_2b_ecc_error_gen :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_INIT_WRITE_DATA_2B_ECC_ERROR_GEN_TypeDef;
+
+typedef union{ /*!< CFG_ECC_1BIT_INT_THRESH register definition*/
+ __IO uint32_t CFG_ECC_1BIT_INT_THRESH;
+ struct
+ {
+ __IO uint32_t cfg_ecc_1bit_int_thresh :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_CFG_ECC_1BIT_INT_THRESH_TypeDef;
+
+typedef union{ /*!< STAT_INT_ECC_1BIT_THRESH register definition*/
+ __I uint32_t STAT_INT_ECC_1BIT_THRESH;
+ struct
+ {
+ __I uint32_t stat_int_ecc_1bit_thresh :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_INT_ECC_1BIT_THRESH_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_ADDR register definition*/
+ __IO uint32_t INIT_READ_CAPTURE_ADDR;
+ struct
+ {
+ __IO uint32_t init_read_capture_addr :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_ADDR_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_0 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_0;
+ struct
+ {
+ __I uint32_t init_read_capture_data_0 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_0_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_1 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_1;
+ struct
+ {
+ __I uint32_t init_read_capture_data_1 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_1_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_2 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_2;
+ struct
+ {
+ __I uint32_t init_read_capture_data_2 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_2_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_3 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_3;
+ struct
+ {
+ __I uint32_t init_read_capture_data_3 :32;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_3_TypeDef;
+
+typedef union{ /*!< INIT_READ_CAPTURE_DATA_4 register definition*/
+ __I uint32_t INIT_READ_CAPTURE_DATA_4;
+ struct
+ {
+ __I uint32_t init_read_capture_data_4 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_INIT_READ_CAPTURE_DATA_4_TypeDef;
+
+typedef union{ /*!< CFG_ERROR_GROUP_SEL register definition*/
+ __IO uint32_t CFG_ERROR_GROUP_SEL;
+ struct
+ {
+ __IO uint32_t cfg_error_group_sel :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ERROR_GROUP_SEL_TypeDef;
+
+typedef union{ /*!< CFG_DATA_SEL register definition*/
+ __IO uint32_t CFG_DATA_SEL;
+ struct
+ {
+ __IO uint32_t cfg_data_sel :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_DATA_SEL_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MODE register definition*/
+ __IO uint32_t CFG_TRIG_MODE;
+ struct
+ {
+ __IO uint32_t cfg_trig_mode :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MODE_TypeDef;
+
+typedef union{ /*!< CFG_POST_TRIG_CYCS register definition*/
+ __IO uint32_t CFG_POST_TRIG_CYCS;
+ struct
+ {
+ __IO uint32_t cfg_post_trig_cycs :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_POST_TRIG_CYCS_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MASK register definition*/
+ __IO uint32_t CFG_TRIG_MASK;
+ struct
+ {
+ __IO uint32_t cfg_trig_mask :3;
+ __I uint32_t reserved :29;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MASK_TypeDef;
+
+typedef union{ /*!< CFG_EN_MASK register definition*/
+ __IO uint32_t CFG_EN_MASK;
+ struct
+ {
+ __IO uint32_t cfg_en_mask :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_EN_MASK_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_ADDR register definition*/
+ __IO uint32_t MTC_ACQ_ADDR;
+ struct
+ {
+ __IO uint32_t mtc_acq_addr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_ADDR_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_CYCS_STORED register definition*/
+ __I uint32_t MTC_ACQ_CYCS_STORED;
+ struct
+ {
+ __I uint32_t mtc_acq_cycs_stored :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_CYCS_STORED_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_TRIG_DETECT register definition*/
+ __I uint32_t MTC_ACQ_TRIG_DETECT;
+ struct
+ {
+ __I uint32_t mtc_acq_trig_detect :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_TRIG_DETECT_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_MEM_TRIG_ADDR register definition*/
+ __I uint32_t MTC_ACQ_MEM_TRIG_ADDR;
+ struct
+ {
+ __I uint32_t mtc_acq_mem_trig_addr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_MEM_TRIG_ADDR_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_MEM_LAST_ADDR register definition*/
+ __I uint32_t MTC_ACQ_MEM_LAST_ADDR;
+ struct
+ {
+ __I uint32_t mtc_acq_mem_last_addr :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_MEM_LAST_ADDR_TypeDef;
+
+typedef union{ /*!< MTC_ACK register definition*/
+ __I uint32_t MTC_ACK;
+ struct
+ {
+ __I uint32_t mtc_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACK_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MT_ADDR_0 register definition*/
+ __IO uint32_t CFG_TRIG_MT_ADDR_0;
+ struct
+ {
+ __IO uint32_t cfg_trig_mt_addr_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MT_ADDR_0_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_MT_ADDR_1 register definition*/
+ __IO uint32_t CFG_TRIG_MT_ADDR_1;
+ struct
+ {
+ __IO uint32_t cfg_trig_mt_addr_1 :7;
+ __I uint32_t reserved :25;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_MT_ADDR_1_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_0 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_0;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_0_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_1 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_1;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_1 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_1_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_2 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_2;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_2 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_2_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_3 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_3;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_3 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_3_TypeDef;
+
+typedef union{ /*!< CFG_TRIG_ERR_MASK_4 register definition*/
+ __IO uint32_t CFG_TRIG_ERR_MASK_4;
+ struct
+ {
+ __IO uint32_t cfg_trig_err_mask_4 :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_TRIG_ERR_MASK_4_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_WR_DATA_0 register definition*/
+ __IO uint32_t MTC_ACQ_WR_DATA_0;
+ struct
+ {
+ __IO uint32_t mtc_acq_wr_data_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_WR_DATA_0_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_WR_DATA_1 register definition*/
+ __IO uint32_t MTC_ACQ_WR_DATA_1;
+ struct
+ {
+ __IO uint32_t mtc_acq_wr_data_1 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_WR_DATA_1_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_WR_DATA_2 register definition*/
+ __IO uint32_t MTC_ACQ_WR_DATA_2;
+ struct
+ {
+ __IO uint32_t mtc_acq_wr_data_2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_WR_DATA_2_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_RD_DATA_0 register definition*/
+ __I uint32_t MTC_ACQ_RD_DATA_0;
+ struct
+ {
+ __I uint32_t mtc_acq_rd_data_0 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_RD_DATA_0_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_RD_DATA_1 register definition*/
+ __I uint32_t MTC_ACQ_RD_DATA_1;
+ struct
+ {
+ __I uint32_t mtc_acq_rd_data_1 :32;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_RD_DATA_1_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_RD_DATA_2 register definition*/
+ __I uint32_t MTC_ACQ_RD_DATA_2;
+ struct
+ {
+ __I uint32_t mtc_acq_rd_data_2 :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_RD_DATA_2_TypeDef;
+
+typedef union{ /*!< CFG_PRE_TRIG_CYCS register definition*/
+ __IO uint32_t CFG_PRE_TRIG_CYCS;
+ struct
+ {
+ __IO uint32_t cfg_pre_trig_cycs :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_CFG_PRE_TRIG_CYCS_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_ERROR_CNT register definition*/
+ __I uint32_t MTC_ACQ_ERROR_CNT;
+ struct
+ {
+ __I uint32_t mtc_acq_error_cnt :10;
+ __I uint32_t reserved :22;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_ERROR_CNT_TypeDef;
+
+typedef union{ /*!< MTC_ACQ_ERROR_CNT_OVFL register definition*/
+ __I uint32_t MTC_ACQ_ERROR_CNT_OVFL;
+ struct
+ {
+ __I uint32_t mtc_acq_error_cnt_ovfl :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_MTC_ACQ_ERROR_CNT_OVFL_TypeDef;
+
+typedef union{ /*!< CFG_DATA_SEL_FIRST_ERROR register definition*/
+ __IO uint32_t CFG_DATA_SEL_FIRST_ERROR;
+ struct
+ {
+ __IO uint32_t cfg_data_sel_first_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DATA_SEL_FIRST_ERROR_TypeDef;
+
+typedef union{ /*!< CFG_DQ_WIDTH register definition*/
+ __IO uint32_t CFG_DQ_WIDTH;
+ struct
+ {
+ __IO uint32_t cfg_dq_width :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_DQ_WIDTH_TypeDef;
+
+typedef union{ /*!< CFG_ACTIVE_DQ_SEL register definition*/
+ __IO uint32_t CFG_ACTIVE_DQ_SEL;
+ struct
+ {
+ __IO uint32_t cfg_active_dq_sel :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_ACTIVE_DQ_SEL_TypeDef;
+
+typedef union{ /*!< STAT_CA_PARITY_ERROR register definition*/
+ __I uint32_t STAT_CA_PARITY_ERROR;
+ struct
+ {
+ __I uint32_t stat_ca_parity_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_CA_PARITY_ERROR_TypeDef;
+
+typedef union{ /*!< INIT_CA_PARITY_ERROR_GEN_REQ register definition*/
+ __IO uint32_t INIT_CA_PARITY_ERROR_GEN_REQ;
+ struct
+ {
+ __IO uint32_t init_ca_parity_error_gen_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_REQ_TypeDef;
+
+typedef union{ /*!< INIT_CA_PARITY_ERROR_GEN_CMD register definition*/
+ __IO uint32_t INIT_CA_PARITY_ERROR_GEN_CMD;
+ struct
+ {
+ __IO uint32_t init_ca_parity_error_gen_cmd :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_CMD_TypeDef;
+
+typedef union{ /*!< INIT_CA_PARITY_ERROR_GEN_ACK register definition*/
+ __I uint32_t INIT_CA_PARITY_ERROR_GEN_ACK;
+ struct
+ {
+ __I uint32_t init_ca_parity_error_gen_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_ACK_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_RDDATA_EN register definition*/
+ __IO uint32_t CFG_DFI_T_RDDATA_EN;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_rddata_en :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_RDDATA_EN_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_PHY_RDLAT register definition*/
+ __IO uint32_t CFG_DFI_T_PHY_RDLAT;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_phy_rdlat :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_PHY_RDLAT_TypeDef;
+
+typedef union{ /*!< CFG_DFI_T_PHY_WRLAT register definition*/
+ __IO uint32_t CFG_DFI_T_PHY_WRLAT;
+ struct
+ {
+ __IO uint32_t cfg_dfi_t_phy_wrlat :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_T_PHY_WRLAT_TypeDef;
+
+typedef union{ /*!< CFG_DFI_PHYUPD_EN register definition*/
+ __IO uint32_t CFG_DFI_PHYUPD_EN;
+ struct
+ {
+ __IO uint32_t cfg_dfi_phyupd_en :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_PHYUPD_EN_TypeDef;
+
+typedef union{ /*!< INIT_DFI_LP_DATA_REQ register definition*/
+ __IO uint32_t INIT_DFI_LP_DATA_REQ;
+ struct
+ {
+ __IO uint32_t init_dfi_lp_data_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_LP_DATA_REQ_TypeDef;
+
+typedef union{ /*!< INIT_DFI_LP_CTRL_REQ register definition*/
+ __IO uint32_t INIT_DFI_LP_CTRL_REQ;
+ struct
+ {
+ __IO uint32_t init_dfi_lp_ctrl_req :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_LP_CTRL_REQ_TypeDef;
+
+typedef union{ /*!< STAT_DFI_LP_ACK register definition*/
+ __I uint32_t STAT_DFI_LP_ACK;
+ struct
+ {
+ __I uint32_t stat_dfi_lp_ack :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_LP_ACK_TypeDef;
+
+typedef union{ /*!< INIT_DFI_LP_WAKEUP register definition*/
+ __IO uint32_t INIT_DFI_LP_WAKEUP;
+ struct
+ {
+ __IO uint32_t init_dfi_lp_wakeup :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_LP_WAKEUP_TypeDef;
+
+typedef union{ /*!< INIT_DFI_DRAM_CLK_DISABLE register definition*/
+ __IO uint32_t INIT_DFI_DRAM_CLK_DISABLE;
+ struct
+ {
+ __IO uint32_t init_dfi_dram_clk_disable :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_INIT_DFI_DRAM_CLK_DISABLE_TypeDef;
+
+typedef union{ /*!< STAT_DFI_TRAINING_ERROR register definition*/
+ __I uint32_t STAT_DFI_TRAINING_ERROR;
+ struct
+ {
+ __I uint32_t stat_dfi_training_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_TRAINING_ERROR_TypeDef;
+
+typedef union{ /*!< STAT_DFI_ERROR register definition*/
+ __I uint32_t STAT_DFI_ERROR;
+ struct
+ {
+ __I uint32_t stat_dfi_error :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_ERROR_TypeDef;
+
+typedef union{ /*!< STAT_DFI_ERROR_INFO register definition*/
+ __I uint32_t STAT_DFI_ERROR_INFO;
+ struct
+ {
+ __I uint32_t stat_dfi_error_info :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_ERROR_INFO_TypeDef;
+
+typedef union{ /*!< CFG_DFI_DATA_BYTE_DISABLE register definition*/
+ __IO uint32_t CFG_DFI_DATA_BYTE_DISABLE;
+ struct
+ {
+ __IO uint32_t cfg_dfi_data_byte_disable :5;
+ __I uint32_t reserved :27;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_DATA_BYTE_DISABLE_TypeDef;
+
+typedef union{ /*!< STAT_DFI_INIT_COMPLETE register definition*/
+ __I uint32_t STAT_DFI_INIT_COMPLETE;
+ struct
+ {
+ __I uint32_t stat_dfi_init_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_INIT_COMPLETE_TypeDef;
+
+typedef union{ /*!< STAT_DFI_TRAINING_COMPLETE register definition*/
+ __I uint32_t STAT_DFI_TRAINING_COMPLETE;
+ struct
+ {
+ __I uint32_t stat_dfi_training_complete :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_STAT_DFI_TRAINING_COMPLETE_TypeDef;
+
+typedef union{ /*!< CFG_DFI_LVL_SEL register definition*/
+ __IO uint32_t CFG_DFI_LVL_SEL;
+ struct
+ {
+ __IO uint32_t cfg_dfi_lvl_sel :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_LVL_SEL_TypeDef;
+
+typedef union{ /*!< CFG_DFI_LVL_PERIODIC register definition*/
+ __IO uint32_t CFG_DFI_LVL_PERIODIC;
+ struct
+ {
+ __IO uint32_t cfg_dfi_lvl_periodic :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_LVL_PERIODIC_TypeDef;
+
+typedef union{ /*!< CFG_DFI_LVL_PATTERN register definition*/
+ __IO uint32_t CFG_DFI_LVL_PATTERN;
+ struct
+ {
+ __IO uint32_t cfg_dfi_lvl_pattern :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_CFG_DFI_LVL_PATTERN_TypeDef;
+
+typedef union{ /*!< PHY_DFI_INIT_START register definition*/
+ __IO uint32_t PHY_DFI_INIT_START;
+ struct
+ {
+ __IO uint32_t phy_dfi_init_start :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_DFI_INIT_START_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI1_0 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI1_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI1_1 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI1_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi1_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_1_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI2_0 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI2_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_START_ADDRESS_AXI2_1 register definition*/
+ __IO uint32_t CFG_AXI_START_ADDRESS_AXI2_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_start_address_axi2_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_1_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI1_0 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI1_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI1_1 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI1_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi1_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_1_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI2_0 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI2_0;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_0_TypeDef;
+
+typedef union{ /*!< CFG_AXI_END_ADDRESS_AXI2_1 register definition*/
+ __IO uint32_t CFG_AXI_END_ADDRESS_AXI2_1;
+ struct
+ {
+ __IO uint32_t cfg_axi_end_address_axi2_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_1_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI1_0 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI1_0;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi1_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_0_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI1_1 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI1_1;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi1_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_1_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI2_0 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI2_0;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi2_0 :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_0_TypeDef;
+
+typedef union{ /*!< CFG_MEM_START_ADDRESS_AXI2_1 register definition*/
+ __IO uint32_t CFG_MEM_START_ADDRESS_AXI2_1;
+ struct
+ {
+ __IO uint32_t cfg_mem_start_address_axi2_1 :2;
+ __I uint32_t reserved :30;
+ } bitfield;
+} DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_1_TypeDef;
+
+typedef union{ /*!< CFG_ENABLE_BUS_HOLD_AXI1 register definition*/
+ __IO uint32_t CFG_ENABLE_BUS_HOLD_AXI1;
+ struct
+ {
+ __IO uint32_t cfg_enable_bus_hold_axi1 :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI1_TypeDef;
+
+typedef union{ /*!< CFG_ENABLE_BUS_HOLD_AXI2 register definition*/
+ __IO uint32_t CFG_ENABLE_BUS_HOLD_AXI2;
+ struct
+ {
+ __IO uint32_t cfg_enable_bus_hold_axi2 :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI2_TypeDef;
+
+typedef union{ /*!< CFG_AXI_AUTO_PCH register definition*/
+ __IO uint32_t CFG_AXI_AUTO_PCH;
+ struct
+ {
+ __IO uint32_t cfg_axi_auto_pch :32;
+ } bitfield;
+} DDR_CSR_APB_CFG_AXI_AUTO_PCH_TypeDef;
+
+typedef union{ /*!< PHY_RESET_CONTROL register definition*/
+ __IO uint32_t PHY_RESET_CONTROL;
+ struct
+ {
+ __IO uint32_t phy_reset_control :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_PHY_RESET_CONTROL_TypeDef;
+
+typedef union{ /*!< PHY_PC_RANK register definition*/
+ __IO uint32_t PHY_PC_RANK;
+ struct
+ {
+ __IO uint32_t phy_pc_rank :4;
+ __I uint32_t reserved :28;
+ } bitfield;
+} DDR_CSR_APB_PHY_PC_RANK_TypeDef;
+
+typedef union{ /*!< PHY_RANKS_TO_TRAIN register definition*/
+ __IO uint32_t PHY_RANKS_TO_TRAIN;
+ struct
+ {
+ __IO uint32_t phy_ranks_to_train :16;
+ __I uint32_t reserved :16;
+ } bitfield;
+} DDR_CSR_APB_PHY_RANKS_TO_TRAIN_TypeDef;
+
+typedef union{ /*!< PHY_WRITE_REQUEST register definition*/
+ __IO uint32_t PHY_WRITE_REQUEST;
+ struct
+ {
+ __IO uint32_t phy_write_request :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_WRITE_REQUEST_TypeDef;
+
+typedef union{ /*!< PHY_WRITE_REQUEST_DONE register definition*/
+ __I uint32_t PHY_WRITE_REQUEST_DONE;
+ struct
+ {
+ __I uint32_t phy_write_request_done :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_WRITE_REQUEST_DONE_TypeDef;
+
+typedef union{ /*!< PHY_READ_REQUEST register definition*/
+ __IO uint32_t PHY_READ_REQUEST;
+ struct
+ {
+ __IO uint32_t phy_read_request :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_READ_REQUEST_TypeDef;
+
+typedef union{ /*!< PHY_READ_REQUEST_DONE register definition*/
+ __I uint32_t PHY_READ_REQUEST_DONE;
+ struct
+ {
+ __I uint32_t phy_read_request_done :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_READ_REQUEST_DONE_TypeDef;
+
+typedef union{ /*!< PHY_WRITE_LEVEL_DELAY register definition*/
+ __IO uint32_t PHY_WRITE_LEVEL_DELAY;
+ struct
+ {
+ __IO uint32_t phy_write_level_delay :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_WRITE_LEVEL_DELAY_TypeDef;
+
+typedef union{ /*!< PHY_GATE_TRAIN_DELAY register definition*/
+ __IO uint32_t PHY_GATE_TRAIN_DELAY;
+ struct
+ {
+ __IO uint32_t phy_gate_train_delay :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_GATE_TRAIN_DELAY_TypeDef;
+
+typedef union{ /*!< PHY_EYE_TRAIN_DELAY register definition*/
+ __IO uint32_t PHY_EYE_TRAIN_DELAY;
+ struct
+ {
+ __IO uint32_t phy_eye_train_delay :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_EYE_TRAIN_DELAY_TypeDef;
+
+typedef union{ /*!< PHY_EYE_PAT register definition*/
+ __IO uint32_t PHY_EYE_PAT;
+ struct
+ {
+ __IO uint32_t phy_eye_pat :8;
+ __I uint32_t reserved :24;
+ } bitfield;
+} DDR_CSR_APB_PHY_EYE_PAT_TypeDef;
+
+typedef union{ /*!< PHY_START_RECAL register definition*/
+ __IO uint32_t PHY_START_RECAL;
+ struct
+ {
+ __IO uint32_t phy_start_recal :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_START_RECAL_TypeDef;
+
+typedef union{ /*!< PHY_CLR_DFI_LVL_PERIODIC register definition*/
+ __IO uint32_t PHY_CLR_DFI_LVL_PERIODIC;
+ struct
+ {
+ __IO uint32_t phy_clr_dfi_lvl_periodic :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_CLR_DFI_LVL_PERIODIC_TypeDef;
+
+typedef union{ /*!< PHY_TRAIN_STEP_ENABLE register definition*/
+ __IO uint32_t PHY_TRAIN_STEP_ENABLE;
+ struct
+ {
+ __IO uint32_t phy_train_step_enable :6;
+ __I uint32_t reserved :26;
+ } bitfield;
+} DDR_CSR_APB_PHY_TRAIN_STEP_ENABLE_TypeDef;
+
+typedef union{ /*!< PHY_LPDDR_DQ_CAL_PAT register definition*/
+ __IO uint32_t PHY_LPDDR_DQ_CAL_PAT;
+ struct
+ {
+ __IO uint32_t phy_lpddr_dq_cal_pat :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_LPDDR_DQ_CAL_PAT_TypeDef;
+
+typedef union{ /*!< PHY_INDPNDT_TRAINING register definition*/
+ __IO uint32_t PHY_INDPNDT_TRAINING;
+ struct
+ {
+ __IO uint32_t phy_indpndt_training :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_INDPNDT_TRAINING_TypeDef;
+
+typedef union{ /*!< PHY_ENCODED_QUAD_CS register definition*/
+ __IO uint32_t PHY_ENCODED_QUAD_CS;
+ struct
+ {
+ __IO uint32_t phy_encoded_quad_cs :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_ENCODED_QUAD_CS_TypeDef;
+
+typedef union{ /*!< PHY_HALF_CLK_DLY_ENABLE register definition*/
+ __IO uint32_t PHY_HALF_CLK_DLY_ENABLE;
+ struct
+ {
+ __IO uint32_t phy_half_clk_dly_enable :1;
+ __I uint32_t reserved :31;
+ } bitfield;
+} DDR_CSR_APB_PHY_HALF_CLK_DLY_ENABLE_TypeDef;
+
+/*------------ ADDR_MAP register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_MANUAL_ADDRESS_MAP_TypeDef CFG_MANUAL_ADDRESS_MAP; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_CHIPADDR_MAP_TypeDef CFG_CHIPADDR_MAP; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_CIDADDR_MAP_TypeDef CFG_CIDADDR_MAP; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_LOW_TypeDef CFG_MB_AUTOPCH_COL_BIT_POS_LOW; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_MB_AUTOPCH_COL_BIT_POS_HIGH_TypeDef CFG_MB_AUTOPCH_COL_BIT_POS_HIGH; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_BANKADDR_MAP_0_TypeDef CFG_BANKADDR_MAP_0; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_BANKADDR_MAP_1_TypeDef CFG_BANKADDR_MAP_1; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_0_TypeDef CFG_ROWADDR_MAP_0; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_1_TypeDef CFG_ROWADDR_MAP_1; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_2_TypeDef CFG_ROWADDR_MAP_2; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_CFG_ROWADDR_MAP_3_TypeDef CFG_ROWADDR_MAP_3; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_COLADDR_MAP_0_TypeDef CFG_COLADDR_MAP_0; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_COLADDR_MAP_1_TypeDef CFG_COLADDR_MAP_1; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_COLADDR_MAP_2_TypeDef CFG_COLADDR_MAP_2; /*!< Offset: 0x34 */
+} DDR_CSR_APB_ADDR_MAP_TypeDef;
+
+/*------------ MC_BASE3 register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_VRCG_ENABLE_TypeDef CFG_VRCG_ENABLE; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_VRCG_DISABLE_TypeDef CFG_VRCG_DISABLE; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_WRITE_LATENCY_SET_TypeDef CFG_WRITE_LATENCY_SET; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_THERMAL_OFFSET_TypeDef CFG_THERMAL_OFFSET; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_SOC_ODT_TypeDef CFG_SOC_ODT; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_ODTE_CK_TypeDef CFG_ODTE_CK; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_ODTE_CS_TypeDef CFG_ODTE_CS; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_ODTD_CA_TypeDef CFG_ODTD_CA; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_LPDDR4_FSP_OP_TypeDef CFG_LPDDR4_FSP_OP; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_GENERATE_REFRESH_ON_SRX_TypeDef CFG_GENERATE_REFRESH_ON_SRX; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_CFG_DBI_CL_TypeDef CFG_DBI_CL; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_NON_DBI_CL_TypeDef CFG_NON_DBI_CL; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_INIT_FORCE_WRITE_DATA_0_TypeDef INIT_FORCE_WRITE_DATA_0; /*!< Offset: 0x30 */
+ __I uint32_t UNUSED_SPACE0[63]; /*!< Offset: 0x34 */
+} DDR_CSR_APB_MC_BASE3_TypeDef;
+
+/*------------ MC_BASE1 register bundle definition -----------*/
+typedef struct /*!< Offset: 0x3c00 */
+{
+ __IO DDR_CSR_APB_CFG_WRITE_CRC_TypeDef CFG_WRITE_CRC; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_MPR_READ_FORMAT_TypeDef CFG_MPR_READ_FORMAT; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_WR_CMD_LAT_CRC_DM_TypeDef CFG_WR_CMD_LAT_CRC_DM; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_FINE_GRAN_REF_MODE_TypeDef CFG_FINE_GRAN_REF_MODE; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_TEMP_SENSOR_READOUT_TypeDef CFG_TEMP_SENSOR_READOUT; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_PER_DRAM_ADDR_EN_TypeDef CFG_PER_DRAM_ADDR_EN; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_GEARDOWN_MODE_TypeDef CFG_GEARDOWN_MODE; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_WR_PREAMBLE_TypeDef CFG_WR_PREAMBLE; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_RD_PREAMBLE_TypeDef CFG_RD_PREAMBLE; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_RD_PREAMB_TRN_MODE_TypeDef CFG_RD_PREAMB_TRN_MODE; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_CFG_SR_ABORT_TypeDef CFG_SR_ABORT; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_CS_TO_CMDADDR_LATENCY_TypeDef CFG_CS_TO_CMDADDR_LATENCY; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_INT_VREF_MON_TypeDef CFG_INT_VREF_MON; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_TEMP_CTRL_REF_MODE_TypeDef CFG_TEMP_CTRL_REF_MODE; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_CFG_TEMP_CTRL_REF_RANGE_TypeDef CFG_TEMP_CTRL_REF_RANGE; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_CFG_MAX_PWR_DOWN_MODE_TypeDef CFG_MAX_PWR_DOWN_MODE; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_READ_DBI_TypeDef CFG_READ_DBI; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_WRITE_DBI_TypeDef CFG_WRITE_DBI; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_CFG_DATA_MASK_TypeDef CFG_DATA_MASK; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_CFG_CA_PARITY_PERSIST_ERR_TypeDef CFG_CA_PARITY_PERSIST_ERR; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_CFG_RTT_PARK_TypeDef CFG_RTT_PARK; /*!< Offset: 0x50 */
+ __IO DDR_CSR_APB_CFG_ODT_INBUF_4_PD_TypeDef CFG_ODT_INBUF_4_PD; /*!< Offset: 0x54 */
+ __IO DDR_CSR_APB_CFG_CA_PARITY_ERR_STATUS_TypeDef CFG_CA_PARITY_ERR_STATUS; /*!< Offset: 0x58 */
+ __IO DDR_CSR_APB_CFG_CRC_ERROR_CLEAR_TypeDef CFG_CRC_ERROR_CLEAR; /*!< Offset: 0x5c */
+ __IO DDR_CSR_APB_CFG_CA_PARITY_LATENCY_TypeDef CFG_CA_PARITY_LATENCY; /*!< Offset: 0x60 */
+ __IO DDR_CSR_APB_CFG_CCD_S_TypeDef CFG_CCD_S; /*!< Offset: 0x64 */
+ __IO DDR_CSR_APB_CFG_CCD_L_TypeDef CFG_CCD_L; /*!< Offset: 0x68 */
+ __IO DDR_CSR_APB_CFG_VREFDQ_TRN_ENABLE_TypeDef CFG_VREFDQ_TRN_ENABLE; /*!< Offset: 0x6c */
+ __IO DDR_CSR_APB_CFG_VREFDQ_TRN_RANGE_TypeDef CFG_VREFDQ_TRN_RANGE; /*!< Offset: 0x70 */
+ __IO DDR_CSR_APB_CFG_VREFDQ_TRN_VALUE_TypeDef CFG_VREFDQ_TRN_VALUE; /*!< Offset: 0x74 */
+ __IO DDR_CSR_APB_CFG_RRD_S_TypeDef CFG_RRD_S; /*!< Offset: 0x78 */
+ __IO DDR_CSR_APB_CFG_RRD_L_TypeDef CFG_RRD_L; /*!< Offset: 0x7c */
+ __IO DDR_CSR_APB_CFG_WTR_S_TypeDef CFG_WTR_S; /*!< Offset: 0x80 */
+ __IO DDR_CSR_APB_CFG_WTR_L_TypeDef CFG_WTR_L; /*!< Offset: 0x84 */
+ __IO DDR_CSR_APB_CFG_WTR_S_CRC_DM_TypeDef CFG_WTR_S_CRC_DM; /*!< Offset: 0x88 */
+ __IO DDR_CSR_APB_CFG_WTR_L_CRC_DM_TypeDef CFG_WTR_L_CRC_DM; /*!< Offset: 0x8c */
+ __IO DDR_CSR_APB_CFG_WR_CRC_DM_TypeDef CFG_WR_CRC_DM; /*!< Offset: 0x90 */
+ __IO DDR_CSR_APB_CFG_RFC1_TypeDef CFG_RFC1; /*!< Offset: 0x94 */
+ __IO DDR_CSR_APB_CFG_RFC2_TypeDef CFG_RFC2; /*!< Offset: 0x98 */
+ __IO DDR_CSR_APB_CFG_RFC4_TypeDef CFG_RFC4; /*!< Offset: 0x9c */
+ __I uint32_t UNUSED_SPACE0[9]; /*!< Offset: 0xa0 */
+ __IO DDR_CSR_APB_CFG_NIBBLE_DEVICES_TypeDef CFG_NIBBLE_DEVICES; /*!< Offset: 0xc4 */
+ __I uint32_t UNUSED_SPACE1[6]; /*!< Offset: 0xc8 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_0_TypeDef CFG_BIT_MAP_INDEX_CS0_0; /*!< Offset: 0xe0 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS0_1_TypeDef CFG_BIT_MAP_INDEX_CS0_1; /*!< Offset: 0xe4 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_0_TypeDef CFG_BIT_MAP_INDEX_CS1_0; /*!< Offset: 0xe8 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS1_1_TypeDef CFG_BIT_MAP_INDEX_CS1_1; /*!< Offset: 0xec */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_0_TypeDef CFG_BIT_MAP_INDEX_CS2_0; /*!< Offset: 0xf0 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS2_1_TypeDef CFG_BIT_MAP_INDEX_CS2_1; /*!< Offset: 0xf4 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_0_TypeDef CFG_BIT_MAP_INDEX_CS3_0; /*!< Offset: 0xf8 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS3_1_TypeDef CFG_BIT_MAP_INDEX_CS3_1; /*!< Offset: 0xfc */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_0_TypeDef CFG_BIT_MAP_INDEX_CS4_0; /*!< Offset: 0x100 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS4_1_TypeDef CFG_BIT_MAP_INDEX_CS4_1; /*!< Offset: 0x104 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_0_TypeDef CFG_BIT_MAP_INDEX_CS5_0; /*!< Offset: 0x108 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS5_1_TypeDef CFG_BIT_MAP_INDEX_CS5_1; /*!< Offset: 0x10c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_0_TypeDef CFG_BIT_MAP_INDEX_CS6_0; /*!< Offset: 0x110 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS6_1_TypeDef CFG_BIT_MAP_INDEX_CS6_1; /*!< Offset: 0x114 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_0_TypeDef CFG_BIT_MAP_INDEX_CS7_0; /*!< Offset: 0x118 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS7_1_TypeDef CFG_BIT_MAP_INDEX_CS7_1; /*!< Offset: 0x11c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_0_TypeDef CFG_BIT_MAP_INDEX_CS8_0; /*!< Offset: 0x120 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS8_1_TypeDef CFG_BIT_MAP_INDEX_CS8_1; /*!< Offset: 0x124 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_0_TypeDef CFG_BIT_MAP_INDEX_CS9_0; /*!< Offset: 0x128 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS9_1_TypeDef CFG_BIT_MAP_INDEX_CS9_1; /*!< Offset: 0x12c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_0_TypeDef CFG_BIT_MAP_INDEX_CS10_0; /*!< Offset: 0x130 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS10_1_TypeDef CFG_BIT_MAP_INDEX_CS10_1; /*!< Offset: 0x134 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_0_TypeDef CFG_BIT_MAP_INDEX_CS11_0; /*!< Offset: 0x138 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS11_1_TypeDef CFG_BIT_MAP_INDEX_CS11_1; /*!< Offset: 0x13c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_0_TypeDef CFG_BIT_MAP_INDEX_CS12_0; /*!< Offset: 0x140 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS12_1_TypeDef CFG_BIT_MAP_INDEX_CS12_1; /*!< Offset: 0x144 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_0_TypeDef CFG_BIT_MAP_INDEX_CS13_0; /*!< Offset: 0x148 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS13_1_TypeDef CFG_BIT_MAP_INDEX_CS13_1; /*!< Offset: 0x14c */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_0_TypeDef CFG_BIT_MAP_INDEX_CS14_0; /*!< Offset: 0x150 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS14_1_TypeDef CFG_BIT_MAP_INDEX_CS14_1; /*!< Offset: 0x154 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_0_TypeDef CFG_BIT_MAP_INDEX_CS15_0; /*!< Offset: 0x158 */
+ __IO DDR_CSR_APB_CFG_BIT_MAP_INDEX_CS15_1_TypeDef CFG_BIT_MAP_INDEX_CS15_1; /*!< Offset: 0x15c */
+ __IO DDR_CSR_APB_CFG_NUM_LOGICAL_RANKS_PER_3DS_TypeDef CFG_NUM_LOGICAL_RANKS_PER_3DS; /*!< Offset: 0x160 */
+ __IO DDR_CSR_APB_CFG_RFC_DLR1_TypeDef CFG_RFC_DLR1; /*!< Offset: 0x164 */
+ __IO DDR_CSR_APB_CFG_RFC_DLR2_TypeDef CFG_RFC_DLR2; /*!< Offset: 0x168 */
+ __IO DDR_CSR_APB_CFG_RFC_DLR4_TypeDef CFG_RFC_DLR4; /*!< Offset: 0x16c */
+ __IO DDR_CSR_APB_CFG_RRD_DLR_TypeDef CFG_RRD_DLR; /*!< Offset: 0x170 */
+ __IO DDR_CSR_APB_CFG_FAW_DLR_TypeDef CFG_FAW_DLR; /*!< Offset: 0x174 */
+ __I uint32_t UNUSED_SPACE2[8]; /*!< Offset: 0x178 */
+ __IO DDR_CSR_APB_CFG_ADVANCE_ACTIVATE_READY_TypeDef CFG_ADVANCE_ACTIVATE_READY; /*!< Offset: 0x198 */
+ __I uint32_t UNUSED_SPACE3[6]; /*!< Offset: 0x19c */
+} DDR_CSR_APB_MC_BASE1_TypeDef;
+
+/*------------ MC_BASE2 register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CTRLR_SOFT_RESET_N_TypeDef CTRLR_SOFT_RESET_N; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_LOOKAHEAD_PCH_TypeDef CFG_LOOKAHEAD_PCH; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_LOOKAHEAD_ACT_TypeDef CFG_LOOKAHEAD_ACT; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_INIT_AUTOINIT_DISABLE_TypeDef INIT_AUTOINIT_DISABLE; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_INIT_FORCE_RESET_TypeDef INIT_FORCE_RESET; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_INIT_GEARDOWN_EN_TypeDef INIT_GEARDOWN_EN; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_INIT_DISABLE_CKE_TypeDef INIT_DISABLE_CKE; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_INIT_CS_TypeDef INIT_CS; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_INIT_PRECHARGE_ALL_TypeDef INIT_PRECHARGE_ALL; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_INIT_REFRESH_TypeDef INIT_REFRESH; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_INIT_ZQ_CAL_REQ_TypeDef INIT_ZQ_CAL_REQ; /*!< Offset: 0x2c */
+ __I DDR_CSR_APB_INIT_ACK_TypeDef INIT_ACK; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_BL_TypeDef CFG_BL; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_CTRLR_INIT_TypeDef CTRLR_INIT; /*!< Offset: 0x38 */
+ __I DDR_CSR_APB_CTRLR_INIT_DONE_TypeDef CTRLR_INIT_DONE; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_AUTO_REF_EN_TypeDef CFG_AUTO_REF_EN; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_RAS_TypeDef CFG_RAS; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_CFG_RCD_TypeDef CFG_RCD; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_CFG_RRD_TypeDef CFG_RRD; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_CFG_RP_TypeDef CFG_RP; /*!< Offset: 0x50 */
+ __IO DDR_CSR_APB_CFG_RC_TypeDef CFG_RC; /*!< Offset: 0x54 */
+ __IO DDR_CSR_APB_CFG_FAW_TypeDef CFG_FAW; /*!< Offset: 0x58 */
+ __IO DDR_CSR_APB_CFG_RFC_TypeDef CFG_RFC; /*!< Offset: 0x5c */
+ __IO DDR_CSR_APB_CFG_RTP_TypeDef CFG_RTP; /*!< Offset: 0x60 */
+ __IO DDR_CSR_APB_CFG_WR_TypeDef CFG_WR; /*!< Offset: 0x64 */
+ __IO DDR_CSR_APB_CFG_WTR_TypeDef CFG_WTR; /*!< Offset: 0x68 */
+ __I uint32_t UNUSED_SPACE1; /*!< Offset: 0x6c */
+ __IO DDR_CSR_APB_CFG_PASR_TypeDef CFG_PASR; /*!< Offset: 0x70 */
+ __IO DDR_CSR_APB_CFG_XP_TypeDef CFG_XP; /*!< Offset: 0x74 */
+ __IO DDR_CSR_APB_CFG_XSR_TypeDef CFG_XSR; /*!< Offset: 0x78 */
+ __I uint32_t UNUSED_SPACE2; /*!< Offset: 0x7c */
+ __IO DDR_CSR_APB_CFG_CL_TypeDef CFG_CL; /*!< Offset: 0x80 */
+ __I uint32_t UNUSED_SPACE3; /*!< Offset: 0x84 */
+ __IO DDR_CSR_APB_CFG_READ_TO_WRITE_TypeDef CFG_READ_TO_WRITE; /*!< Offset: 0x88 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_WRITE_TypeDef CFG_WRITE_TO_WRITE; /*!< Offset: 0x8c */
+ __IO DDR_CSR_APB_CFG_READ_TO_READ_TypeDef CFG_READ_TO_READ; /*!< Offset: 0x90 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_READ_TypeDef CFG_WRITE_TO_READ; /*!< Offset: 0x94 */
+ __IO DDR_CSR_APB_CFG_READ_TO_WRITE_ODT_TypeDef CFG_READ_TO_WRITE_ODT; /*!< Offset: 0x98 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_WRITE_ODT_TypeDef CFG_WRITE_TO_WRITE_ODT; /*!< Offset: 0x9c */
+ __IO DDR_CSR_APB_CFG_READ_TO_READ_ODT_TypeDef CFG_READ_TO_READ_ODT; /*!< Offset: 0xa0 */
+ __IO DDR_CSR_APB_CFG_WRITE_TO_READ_ODT_TypeDef CFG_WRITE_TO_READ_ODT; /*!< Offset: 0xa4 */
+ __IO DDR_CSR_APB_CFG_MIN_READ_IDLE_TypeDef CFG_MIN_READ_IDLE; /*!< Offset: 0xa8 */
+ __IO DDR_CSR_APB_CFG_MRD_TypeDef CFG_MRD; /*!< Offset: 0xac */
+ __IO DDR_CSR_APB_CFG_BT_TypeDef CFG_BT; /*!< Offset: 0xb0 */
+ __IO DDR_CSR_APB_CFG_DS_TypeDef CFG_DS; /*!< Offset: 0xb4 */
+ __IO DDR_CSR_APB_CFG_QOFF_TypeDef CFG_QOFF; /*!< Offset: 0xb8 */
+ __I uint32_t UNUSED_SPACE4[2]; /*!< Offset: 0xbc */
+ __IO DDR_CSR_APB_CFG_RTT_TypeDef CFG_RTT; /*!< Offset: 0xc4 */
+ __IO DDR_CSR_APB_CFG_DLL_DISABLE_TypeDef CFG_DLL_DISABLE; /*!< Offset: 0xc8 */
+ __IO DDR_CSR_APB_CFG_REF_PER_TypeDef CFG_REF_PER; /*!< Offset: 0xcc */
+ __IO DDR_CSR_APB_CFG_STARTUP_DELAY_TypeDef CFG_STARTUP_DELAY; /*!< Offset: 0xd0 */
+ __IO DDR_CSR_APB_CFG_MEM_COLBITS_TypeDef CFG_MEM_COLBITS; /*!< Offset: 0xd4 */
+ __IO DDR_CSR_APB_CFG_MEM_ROWBITS_TypeDef CFG_MEM_ROWBITS; /*!< Offset: 0xd8 */
+ __IO DDR_CSR_APB_CFG_MEM_BANKBITS_TypeDef CFG_MEM_BANKBITS; /*!< Offset: 0xdc */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS0_TypeDef CFG_ODT_RD_MAP_CS0; /*!< Offset: 0xe0 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS1_TypeDef CFG_ODT_RD_MAP_CS1; /*!< Offset: 0xe4 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS2_TypeDef CFG_ODT_RD_MAP_CS2; /*!< Offset: 0xe8 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS3_TypeDef CFG_ODT_RD_MAP_CS3; /*!< Offset: 0xec */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS4_TypeDef CFG_ODT_RD_MAP_CS4; /*!< Offset: 0xf0 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS5_TypeDef CFG_ODT_RD_MAP_CS5; /*!< Offset: 0xf4 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS6_TypeDef CFG_ODT_RD_MAP_CS6; /*!< Offset: 0xf8 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_MAP_CS7_TypeDef CFG_ODT_RD_MAP_CS7; /*!< Offset: 0xfc */
+ __I uint32_t UNUSED_SPACE5[8]; /*!< Offset: 0x100 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS0_TypeDef CFG_ODT_WR_MAP_CS0; /*!< Offset: 0x120 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS1_TypeDef CFG_ODT_WR_MAP_CS1; /*!< Offset: 0x124 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS2_TypeDef CFG_ODT_WR_MAP_CS2; /*!< Offset: 0x128 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS3_TypeDef CFG_ODT_WR_MAP_CS3; /*!< Offset: 0x12c */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS4_TypeDef CFG_ODT_WR_MAP_CS4; /*!< Offset: 0x130 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS5_TypeDef CFG_ODT_WR_MAP_CS5; /*!< Offset: 0x134 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS6_TypeDef CFG_ODT_WR_MAP_CS6; /*!< Offset: 0x138 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_MAP_CS7_TypeDef CFG_ODT_WR_MAP_CS7; /*!< Offset: 0x13c */
+ __I uint32_t UNUSED_SPACE6[8]; /*!< Offset: 0x140 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_TURN_ON_TypeDef CFG_ODT_RD_TURN_ON; /*!< Offset: 0x160 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_TURN_ON_TypeDef CFG_ODT_WR_TURN_ON; /*!< Offset: 0x164 */
+ __IO DDR_CSR_APB_CFG_ODT_RD_TURN_OFF_TypeDef CFG_ODT_RD_TURN_OFF; /*!< Offset: 0x168 */
+ __IO DDR_CSR_APB_CFG_ODT_WR_TURN_OFF_TypeDef CFG_ODT_WR_TURN_OFF; /*!< Offset: 0x16c */
+ __I uint32_t UNUSED_SPACE7[2]; /*!< Offset: 0x170 */
+ __IO DDR_CSR_APB_CFG_EMR3_TypeDef CFG_EMR3; /*!< Offset: 0x178 */
+ __IO DDR_CSR_APB_CFG_TWO_T_TypeDef CFG_TWO_T; /*!< Offset: 0x17c */
+ __IO DDR_CSR_APB_CFG_TWO_T_SEL_CYCLE_TypeDef CFG_TWO_T_SEL_CYCLE; /*!< Offset: 0x180 */
+ __IO DDR_CSR_APB_CFG_REGDIMM_TypeDef CFG_REGDIMM; /*!< Offset: 0x184 */
+ __IO DDR_CSR_APB_CFG_MOD_TypeDef CFG_MOD; /*!< Offset: 0x188 */
+ __IO DDR_CSR_APB_CFG_XS_TypeDef CFG_XS; /*!< Offset: 0x18c */
+ __IO DDR_CSR_APB_CFG_XSDLL_TypeDef CFG_XSDLL; /*!< Offset: 0x190 */
+ __IO DDR_CSR_APB_CFG_XPR_TypeDef CFG_XPR; /*!< Offset: 0x194 */
+ __IO DDR_CSR_APB_CFG_AL_MODE_TypeDef CFG_AL_MODE; /*!< Offset: 0x198 */
+ __IO DDR_CSR_APB_CFG_CWL_TypeDef CFG_CWL; /*!< Offset: 0x19c */
+ __IO DDR_CSR_APB_CFG_BL_MODE_TypeDef CFG_BL_MODE; /*!< Offset: 0x1a0 */
+ __IO DDR_CSR_APB_CFG_TDQS_TypeDef CFG_TDQS; /*!< Offset: 0x1a4 */
+ __IO DDR_CSR_APB_CFG_RTT_WR_TypeDef CFG_RTT_WR; /*!< Offset: 0x1a8 */
+ __IO DDR_CSR_APB_CFG_LP_ASR_TypeDef CFG_LP_ASR; /*!< Offset: 0x1ac */
+ __IO DDR_CSR_APB_CFG_AUTO_SR_TypeDef CFG_AUTO_SR; /*!< Offset: 0x1b0 */
+ __IO DDR_CSR_APB_CFG_SRT_TypeDef CFG_SRT; /*!< Offset: 0x1b4 */
+ __IO DDR_CSR_APB_CFG_ADDR_MIRROR_TypeDef CFG_ADDR_MIRROR; /*!< Offset: 0x1b8 */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_TYPE_TypeDef CFG_ZQ_CAL_TYPE; /*!< Offset: 0x1bc */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_PER_TypeDef CFG_ZQ_CAL_PER; /*!< Offset: 0x1c0 */
+ __IO DDR_CSR_APB_CFG_AUTO_ZQ_CAL_EN_TypeDef CFG_AUTO_ZQ_CAL_EN; /*!< Offset: 0x1c4 */
+ __IO DDR_CSR_APB_CFG_MEMORY_TYPE_TypeDef CFG_MEMORY_TYPE; /*!< Offset: 0x1c8 */
+ __IO DDR_CSR_APB_CFG_ONLY_SRANK_CMDS_TypeDef CFG_ONLY_SRANK_CMDS; /*!< Offset: 0x1cc */
+ __IO DDR_CSR_APB_CFG_NUM_RANKS_TypeDef CFG_NUM_RANKS; /*!< Offset: 0x1d0 */
+ __IO DDR_CSR_APB_CFG_QUAD_RANK_TypeDef CFG_QUAD_RANK; /*!< Offset: 0x1d4 */
+ __I uint32_t UNUSED_SPACE8; /*!< Offset: 0x1d8 */
+ __IO DDR_CSR_APB_CFG_EARLY_RANK_TO_WR_START_TypeDef CFG_EARLY_RANK_TO_WR_START; /*!< Offset: 0x1dc */
+ __IO DDR_CSR_APB_CFG_EARLY_RANK_TO_RD_START_TypeDef CFG_EARLY_RANK_TO_RD_START; /*!< Offset: 0x1e0 */
+ __IO DDR_CSR_APB_CFG_PASR_BANK_TypeDef CFG_PASR_BANK; /*!< Offset: 0x1e4 */
+ __IO DDR_CSR_APB_CFG_PASR_SEG_TypeDef CFG_PASR_SEG; /*!< Offset: 0x1e8 */
+ __IO DDR_CSR_APB_INIT_MRR_MODE_TypeDef INIT_MRR_MODE; /*!< Offset: 0x1ec */
+ __IO DDR_CSR_APB_INIT_MR_W_REQ_TypeDef INIT_MR_W_REQ; /*!< Offset: 0x1f0 */
+ __IO DDR_CSR_APB_INIT_MR_ADDR_TypeDef INIT_MR_ADDR; /*!< Offset: 0x1f4 */
+ __IO DDR_CSR_APB_INIT_MR_WR_DATA_TypeDef INIT_MR_WR_DATA; /*!< Offset: 0x1f8 */
+ __IO DDR_CSR_APB_INIT_MR_WR_MASK_TypeDef INIT_MR_WR_MASK; /*!< Offset: 0x1fc */
+ __IO DDR_CSR_APB_INIT_NOP_TypeDef INIT_NOP; /*!< Offset: 0x200 */
+ __IO DDR_CSR_APB_CFG_INIT_DURATION_TypeDef CFG_INIT_DURATION; /*!< Offset: 0x204 */
+ __IO DDR_CSR_APB_CFG_ZQINIT_CAL_DURATION_TypeDef CFG_ZQINIT_CAL_DURATION; /*!< Offset: 0x208 */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_L_DURATION_TypeDef CFG_ZQ_CAL_L_DURATION; /*!< Offset: 0x20c */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_S_DURATION_TypeDef CFG_ZQ_CAL_S_DURATION; /*!< Offset: 0x210 */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_R_DURATION_TypeDef CFG_ZQ_CAL_R_DURATION; /*!< Offset: 0x214 */
+ __IO DDR_CSR_APB_CFG_MRR_TypeDef CFG_MRR; /*!< Offset: 0x218 */
+ __IO DDR_CSR_APB_CFG_MRW_TypeDef CFG_MRW; /*!< Offset: 0x21c */
+ __IO DDR_CSR_APB_CFG_ODT_POWERDOWN_TypeDef CFG_ODT_POWERDOWN; /*!< Offset: 0x220 */
+ __IO DDR_CSR_APB_CFG_WL_TypeDef CFG_WL; /*!< Offset: 0x224 */
+ __IO DDR_CSR_APB_CFG_RL_TypeDef CFG_RL; /*!< Offset: 0x228 */
+ __IO DDR_CSR_APB_CFG_CAL_READ_PERIOD_TypeDef CFG_CAL_READ_PERIOD; /*!< Offset: 0x22c */
+ __IO DDR_CSR_APB_CFG_NUM_CAL_READS_TypeDef CFG_NUM_CAL_READS; /*!< Offset: 0x230 */
+ __IO DDR_CSR_APB_INIT_SELF_REFRESH_TypeDef INIT_SELF_REFRESH; /*!< Offset: 0x234 */
+ __I DDR_CSR_APB_INIT_SELF_REFRESH_STATUS_TypeDef INIT_SELF_REFRESH_STATUS; /*!< Offset: 0x238 */
+ __IO DDR_CSR_APB_INIT_POWER_DOWN_TypeDef INIT_POWER_DOWN; /*!< Offset: 0x23c */
+ __I DDR_CSR_APB_INIT_POWER_DOWN_STATUS_TypeDef INIT_POWER_DOWN_STATUS; /*!< Offset: 0x240 */
+ __IO DDR_CSR_APB_INIT_FORCE_WRITE_TypeDef INIT_FORCE_WRITE; /*!< Offset: 0x244 */
+ __IO DDR_CSR_APB_INIT_FORCE_WRITE_CS_TypeDef INIT_FORCE_WRITE_CS; /*!< Offset: 0x248 */
+ __IO DDR_CSR_APB_CFG_CTRLR_INIT_DISABLE_TypeDef CFG_CTRLR_INIT_DISABLE; /*!< Offset: 0x24c */
+ __I DDR_CSR_APB_CTRLR_READY_TypeDef CTRLR_READY; /*!< Offset: 0x250 */
+ __I DDR_CSR_APB_INIT_RDIMM_READY_TypeDef INIT_RDIMM_READY; /*!< Offset: 0x254 */
+ __IO DDR_CSR_APB_INIT_RDIMM_COMPLETE_TypeDef INIT_RDIMM_COMPLETE; /*!< Offset: 0x258 */
+ __IO DDR_CSR_APB_CFG_RDIMM_LAT_TypeDef CFG_RDIMM_LAT; /*!< Offset: 0x25c */
+ __IO DDR_CSR_APB_CFG_RDIMM_BSIDE_INVERT_TypeDef CFG_RDIMM_BSIDE_INVERT; /*!< Offset: 0x260 */
+ __IO DDR_CSR_APB_CFG_LRDIMM_TypeDef CFG_LRDIMM; /*!< Offset: 0x264 */
+ __IO DDR_CSR_APB_INIT_MEMORY_RESET_MASK_TypeDef INIT_MEMORY_RESET_MASK; /*!< Offset: 0x268 */
+ __IO DDR_CSR_APB_CFG_RD_PREAMB_TOGGLE_TypeDef CFG_RD_PREAMB_TOGGLE; /*!< Offset: 0x26c */
+ __IO DDR_CSR_APB_CFG_RD_POSTAMBLE_TypeDef CFG_RD_POSTAMBLE; /*!< Offset: 0x270 */
+ __IO DDR_CSR_APB_CFG_PU_CAL_TypeDef CFG_PU_CAL; /*!< Offset: 0x274 */
+ __IO DDR_CSR_APB_CFG_DQ_ODT_TypeDef CFG_DQ_ODT; /*!< Offset: 0x278 */
+ __IO DDR_CSR_APB_CFG_CA_ODT_TypeDef CFG_CA_ODT; /*!< Offset: 0x27c */
+ __IO DDR_CSR_APB_CFG_ZQLATCH_DURATION_TypeDef CFG_ZQLATCH_DURATION; /*!< Offset: 0x280 */
+ __IO DDR_CSR_APB_INIT_CAL_SELECT_TypeDef INIT_CAL_SELECT; /*!< Offset: 0x284 */
+ __IO DDR_CSR_APB_INIT_CAL_L_R_REQ_TypeDef INIT_CAL_L_R_REQ; /*!< Offset: 0x288 */
+ __IO DDR_CSR_APB_INIT_CAL_L_B_SIZE_TypeDef INIT_CAL_L_B_SIZE; /*!< Offset: 0x28c */
+ __I DDR_CSR_APB_INIT_CAL_L_R_ACK_TypeDef INIT_CAL_L_R_ACK; /*!< Offset: 0x290 */
+ __I DDR_CSR_APB_INIT_CAL_L_READ_COMPLETE_TypeDef INIT_CAL_L_READ_COMPLETE; /*!< Offset: 0x294 */
+ __I uint32_t UNUSED_SPACE9[2]; /*!< Offset: 0x298 */
+ __IO DDR_CSR_APB_INIT_RWFIFO_TypeDef INIT_RWFIFO; /*!< Offset: 0x2a0 */
+ __IO DDR_CSR_APB_INIT_RD_DQCAL_TypeDef INIT_RD_DQCAL; /*!< Offset: 0x2a4 */
+ __IO DDR_CSR_APB_INIT_START_DQSOSC_TypeDef INIT_START_DQSOSC; /*!< Offset: 0x2a8 */
+ __IO DDR_CSR_APB_INIT_STOP_DQSOSC_TypeDef INIT_STOP_DQSOSC; /*!< Offset: 0x2ac */
+ __IO DDR_CSR_APB_INIT_ZQ_CAL_START_TypeDef INIT_ZQ_CAL_START; /*!< Offset: 0x2b0 */
+ __IO DDR_CSR_APB_CFG_WR_POSTAMBLE_TypeDef CFG_WR_POSTAMBLE; /*!< Offset: 0x2b4 */
+ __I uint32_t UNUSED_SPACE10; /*!< Offset: 0x2b8 */
+ __IO DDR_CSR_APB_INIT_CAL_L_ADDR_0_TypeDef INIT_CAL_L_ADDR_0; /*!< Offset: 0x2bc */
+ __IO DDR_CSR_APB_INIT_CAL_L_ADDR_1_TypeDef INIT_CAL_L_ADDR_1; /*!< Offset: 0x2c0 */
+ __IO DDR_CSR_APB_CFG_CTRLUPD_TRIG_TypeDef CFG_CTRLUPD_TRIG; /*!< Offset: 0x2c4 */
+ __IO DDR_CSR_APB_CFG_CTRLUPD_START_DELAY_TypeDef CFG_CTRLUPD_START_DELAY; /*!< Offset: 0x2c8 */
+ __IO DDR_CSR_APB_CFG_DFI_T_CTRLUPD_MAX_TypeDef CFG_DFI_T_CTRLUPD_MAX; /*!< Offset: 0x2cc */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_SEL_TypeDef CFG_CTRLR_BUSY_SEL; /*!< Offset: 0x2d0 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_VALUE_TypeDef CFG_CTRLR_BUSY_VALUE; /*!< Offset: 0x2d4 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_TURN_OFF_DELAY_TypeDef CFG_CTRLR_BUSY_TURN_OFF_DELAY; /*!< Offset: 0x2d8 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW_TypeDef CFG_CTRLR_BUSY_SLOW_RESTART_WINDOW; /*!< Offset: 0x2dc */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_RESTART_HOLDOFF_TypeDef CFG_CTRLR_BUSY_RESTART_HOLDOFF; /*!< Offset: 0x2e0 */
+ __IO DDR_CSR_APB_CFG_PARITY_RDIMM_DELAY_TypeDef CFG_PARITY_RDIMM_DELAY; /*!< Offset: 0x2e4 */
+ __IO DDR_CSR_APB_CFG_CTRLR_BUSY_ENABLE_TypeDef CFG_CTRLR_BUSY_ENABLE; /*!< Offset: 0x2e8 */
+ __IO DDR_CSR_APB_CFG_ASYNC_ODT_TypeDef CFG_ASYNC_ODT; /*!< Offset: 0x2ec */
+ __IO DDR_CSR_APB_CFG_ZQ_CAL_DURATION_TypeDef CFG_ZQ_CAL_DURATION; /*!< Offset: 0x2f0 */
+ __IO DDR_CSR_APB_CFG_MRRI_TypeDef CFG_MRRI; /*!< Offset: 0x2f4 */
+ __IO DDR_CSR_APB_INIT_ODT_FORCE_EN_TypeDef INIT_ODT_FORCE_EN; /*!< Offset: 0x2f8 */
+ __IO DDR_CSR_APB_INIT_ODT_FORCE_RANK_TypeDef INIT_ODT_FORCE_RANK; /*!< Offset: 0x2fc */
+ __IO DDR_CSR_APB_CFG_PHYUPD_ACK_DELAY_TypeDef CFG_PHYUPD_ACK_DELAY; /*!< Offset: 0x300 */
+ __IO DDR_CSR_APB_CFG_MIRROR_X16_BG0_BG1_TypeDef CFG_MIRROR_X16_BG0_BG1; /*!< Offset: 0x304 */
+ __IO DDR_CSR_APB_INIT_PDA_MR_W_REQ_TypeDef INIT_PDA_MR_W_REQ; /*!< Offset: 0x308 */
+ __IO DDR_CSR_APB_INIT_PDA_NIBBLE_SELECT_TypeDef INIT_PDA_NIBBLE_SELECT; /*!< Offset: 0x30c */
+ __IO DDR_CSR_APB_CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH_TypeDef CFG_DRAM_CLK_DISABLE_IN_SELF_REFRESH; /*!< Offset: 0x310 */
+ __IO DDR_CSR_APB_CFG_CKSRE_TypeDef CFG_CKSRE; /*!< Offset: 0x314 */
+ __IO DDR_CSR_APB_CFG_CKSRX_TypeDef CFG_CKSRX; /*!< Offset: 0x318 */
+ __IO DDR_CSR_APB_CFG_RCD_STAB_TypeDef CFG_RCD_STAB; /*!< Offset: 0x31c */
+ __IO DDR_CSR_APB_CFG_DFI_T_CTRL_DELAY_TypeDef CFG_DFI_T_CTRL_DELAY; /*!< Offset: 0x320 */
+ __IO DDR_CSR_APB_CFG_DFI_T_DRAM_CLK_ENABLE_TypeDef CFG_DFI_T_DRAM_CLK_ENABLE; /*!< Offset: 0x324 */
+ __IO DDR_CSR_APB_CFG_IDLE_TIME_TO_SELF_REFRESH_TypeDef CFG_IDLE_TIME_TO_SELF_REFRESH; /*!< Offset: 0x328 */
+ __IO DDR_CSR_APB_CFG_IDLE_TIME_TO_POWER_DOWN_TypeDef CFG_IDLE_TIME_TO_POWER_DOWN; /*!< Offset: 0x32c */
+ __IO DDR_CSR_APB_CFG_BURST_RW_REFRESH_HOLDOFF_TypeDef CFG_BURST_RW_REFRESH_HOLDOFF; /*!< Offset: 0x330 */
+ __I DDR_CSR_APB_INIT_REFRESH_COUNT_TypeDef INIT_REFRESH_COUNT; /*!< Offset: 0x334 */
+ __I uint32_t UNUSED_SPACE11[19]; /*!< Offset: 0x338 */
+ __IO DDR_CSR_APB_CFG_BG_INTERLEAVE_TypeDef CFG_BG_INTERLEAVE; /*!< Offset: 0x384 */
+ __I uint32_t UNUSED_SPACE12[29]; /*!< Offset: 0x388 */
+ __IO DDR_CSR_APB_CFG_REFRESH_DURING_PHY_TRAINING_TypeDef CFG_REFRESH_DURING_PHY_TRAINING; /*!< Offset: 0x3fc */
+} DDR_CSR_APB_MC_BASE2_TypeDef;
+
+/*------------ MEM_TEST register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_MT_EN_TypeDef MT_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_MT_EN_SINGLE_TypeDef MT_EN_SINGLE; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_MT_STOP_ON_ERROR_TypeDef MT_STOP_ON_ERROR; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_MT_RD_ONLY_TypeDef MT_RD_ONLY; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_MT_WR_ONLY_TypeDef MT_WR_ONLY; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_MT_DATA_PATTERN_TypeDef MT_DATA_PATTERN; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_MT_ADDR_PATTERN_TypeDef MT_ADDR_PATTERN; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_MT_DATA_INVERT_TypeDef MT_DATA_INVERT; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_MT_ADDR_BITS_TypeDef MT_ADDR_BITS; /*!< Offset: 0x20 */
+ __I DDR_CSR_APB_MT_ERROR_STS_TypeDef MT_ERROR_STS; /*!< Offset: 0x24 */
+ __I DDR_CSR_APB_MT_DONE_ACK_TypeDef MT_DONE_ACK; /*!< Offset: 0x28 */
+ __I uint32_t UNUSED_SPACE0[34]; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_MT_START_ADDR_0_TypeDef MT_START_ADDR_0; /*!< Offset: 0xb4 */
+ __IO DDR_CSR_APB_MT_START_ADDR_1_TypeDef MT_START_ADDR_1; /*!< Offset: 0xb8 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_0_TypeDef MT_ERROR_MASK_0; /*!< Offset: 0xbc */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_1_TypeDef MT_ERROR_MASK_1; /*!< Offset: 0xc0 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_2_TypeDef MT_ERROR_MASK_2; /*!< Offset: 0xc4 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_3_TypeDef MT_ERROR_MASK_3; /*!< Offset: 0xc8 */
+ __IO DDR_CSR_APB_MT_ERROR_MASK_4_TypeDef MT_ERROR_MASK_4; /*!< Offset: 0xcc */
+ __I uint32_t UNUSED_SPACE1[104]; /*!< Offset: 0xd0 */
+ __IO DDR_CSR_APB_MT_USER_DATA_PATTERN_TypeDef MT_USER_DATA_PATTERN; /*!< Offset: 0x270 */
+ __I uint32_t UNUSED_SPACE2[2]; /*!< Offset: 0x274 */
+ __IO DDR_CSR_APB_MT_ALG_AUTO_PCH_TypeDef MT_ALG_AUTO_PCH; /*!< Offset: 0x27c */
+ __I uint32_t UNUSED_SPACE3[2]; /*!< Offset: 0x280 */
+} DDR_CSR_APB_MEM_TEST_TypeDef;
+
+/*------------ MPFE register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P0_TypeDef CFG_STARVE_TIMEOUT_P0; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P1_TypeDef CFG_STARVE_TIMEOUT_P1; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P2_TypeDef CFG_STARVE_TIMEOUT_P2; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P3_TypeDef CFG_STARVE_TIMEOUT_P3; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P4_TypeDef CFG_STARVE_TIMEOUT_P4; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P5_TypeDef CFG_STARVE_TIMEOUT_P5; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P6_TypeDef CFG_STARVE_TIMEOUT_P6; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_STARVE_TIMEOUT_P7_TypeDef CFG_STARVE_TIMEOUT_P7; /*!< Offset: 0x1c */
+ __I uint32_t UNUSED_SPACE0[33]; /*!< Offset: 0x20 */
+} DDR_CSR_APB_MPFE_TypeDef;
+
+/*------------ REORDER register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_REORDER_EN_TypeDef CFG_REORDER_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_REORDER_QUEUE_EN_TypeDef CFG_REORDER_QUEUE_EN; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_INTRAPORT_REORDER_EN_TypeDef CFG_INTRAPORT_REORDER_EN; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_MAINTAIN_COHERENCY_TypeDef CFG_MAINTAIN_COHERENCY; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_Q_AGE_LIMIT_TypeDef CFG_Q_AGE_LIMIT; /*!< Offset: 0x10 */
+ __I uint32_t UNUSED_SPACE0; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_CFG_RO_CLOSED_PAGE_POLICY_TypeDef CFG_RO_CLOSED_PAGE_POLICY; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_REORDER_RW_ONLY_TypeDef CFG_REORDER_RW_ONLY; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_RO_PRIORITY_EN_TypeDef CFG_RO_PRIORITY_EN; /*!< Offset: 0x20 */
+} DDR_CSR_APB_REORDER_TypeDef;
+
+/*------------ RMW register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_DM_EN_TypeDef CFG_DM_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_RMW_EN_TypeDef CFG_RMW_EN; /*!< Offset: 0x4 */
+} DDR_CSR_APB_RMW_TypeDef;
+
+/*------------ ECC register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_ECC_CORRECTION_EN_TypeDef CFG_ECC_CORRECTION_EN; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0[15]; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_ECC_BYPASS_TypeDef CFG_ECC_BYPASS; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_INIT_WRITE_DATA_1B_ECC_ERROR_GEN_TypeDef INIT_WRITE_DATA_1B_ECC_ERROR_GEN; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_INIT_WRITE_DATA_2B_ECC_ERROR_GEN_TypeDef INIT_WRITE_DATA_2B_ECC_ERROR_GEN; /*!< Offset: 0x48 */
+ __I uint32_t UNUSED_SPACE1[4]; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_CFG_ECC_1BIT_INT_THRESH_TypeDef CFG_ECC_1BIT_INT_THRESH; /*!< Offset: 0x5c */
+ __I DDR_CSR_APB_STAT_INT_ECC_1BIT_THRESH_TypeDef STAT_INT_ECC_1BIT_THRESH; /*!< Offset: 0x60 */
+ __I uint32_t UNUSED_SPACE2[2]; /*!< Offset: 0x64 */
+} DDR_CSR_APB_ECC_TypeDef;
+
+/*------------ READ_CAPT register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_INIT_READ_CAPTURE_ADDR_TypeDef INIT_READ_CAPTURE_ADDR; /*!< Offset: 0x0 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_0_TypeDef INIT_READ_CAPTURE_DATA_0; /*!< Offset: 0x4 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_1_TypeDef INIT_READ_CAPTURE_DATA_1; /*!< Offset: 0x8 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_2_TypeDef INIT_READ_CAPTURE_DATA_2; /*!< Offset: 0xc */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_3_TypeDef INIT_READ_CAPTURE_DATA_3; /*!< Offset: 0x10 */
+ __I DDR_CSR_APB_INIT_READ_CAPTURE_DATA_4_TypeDef INIT_READ_CAPTURE_DATA_4; /*!< Offset: 0x14 */
+ __I uint32_t UNUSED_SPACE0[12]; /*!< Offset: 0x18 */
+} DDR_CSR_APB_READ_CAPT_TypeDef;
+
+/*------------ MTA register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_ERROR_GROUP_SEL_TypeDef CFG_ERROR_GROUP_SEL; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_DATA_SEL_TypeDef CFG_DATA_SEL; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_TRIG_MODE_TypeDef CFG_TRIG_MODE; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_POST_TRIG_CYCS_TypeDef CFG_POST_TRIG_CYCS; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_CFG_TRIG_MASK_TypeDef CFG_TRIG_MASK; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_CFG_EN_MASK_TypeDef CFG_EN_MASK; /*!< Offset: 0x14 */
+ __IO DDR_CSR_APB_MTC_ACQ_ADDR_TypeDef MTC_ACQ_ADDR; /*!< Offset: 0x18 */
+ __I DDR_CSR_APB_MTC_ACQ_CYCS_STORED_TypeDef MTC_ACQ_CYCS_STORED; /*!< Offset: 0x1c */
+ __I DDR_CSR_APB_MTC_ACQ_TRIG_DETECT_TypeDef MTC_ACQ_TRIG_DETECT; /*!< Offset: 0x20 */
+ __I DDR_CSR_APB_MTC_ACQ_MEM_TRIG_ADDR_TypeDef MTC_ACQ_MEM_TRIG_ADDR; /*!< Offset: 0x24 */
+ __I DDR_CSR_APB_MTC_ACQ_MEM_LAST_ADDR_TypeDef MTC_ACQ_MEM_LAST_ADDR; /*!< Offset: 0x28 */
+ __I DDR_CSR_APB_MTC_ACK_TypeDef MTC_ACK; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_TRIG_MT_ADDR_0_TypeDef CFG_TRIG_MT_ADDR_0; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_CFG_TRIG_MT_ADDR_1_TypeDef CFG_TRIG_MT_ADDR_1; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_0_TypeDef CFG_TRIG_ERR_MASK_0; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_1_TypeDef CFG_TRIG_ERR_MASK_1; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_2_TypeDef CFG_TRIG_ERR_MASK_2; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_3_TypeDef CFG_TRIG_ERR_MASK_3; /*!< Offset: 0x44 */
+ __IO DDR_CSR_APB_CFG_TRIG_ERR_MASK_4_TypeDef CFG_TRIG_ERR_MASK_4; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_MTC_ACQ_WR_DATA_0_TypeDef MTC_ACQ_WR_DATA_0; /*!< Offset: 0x4c */
+ __IO DDR_CSR_APB_MTC_ACQ_WR_DATA_1_TypeDef MTC_ACQ_WR_DATA_1; /*!< Offset: 0x50 */
+ __IO DDR_CSR_APB_MTC_ACQ_WR_DATA_2_TypeDef MTC_ACQ_WR_DATA_2; /*!< Offset: 0x54 */
+ __I DDR_CSR_APB_MTC_ACQ_RD_DATA_0_TypeDef MTC_ACQ_RD_DATA_0; /*!< Offset: 0x58 */
+ __I DDR_CSR_APB_MTC_ACQ_RD_DATA_1_TypeDef MTC_ACQ_RD_DATA_1; /*!< Offset: 0x5c */
+ __I DDR_CSR_APB_MTC_ACQ_RD_DATA_2_TypeDef MTC_ACQ_RD_DATA_2; /*!< Offset: 0x60 */
+ __I uint32_t UNUSED_SPACE0[50]; /*!< Offset: 0x64 */
+ __IO DDR_CSR_APB_CFG_PRE_TRIG_CYCS_TypeDef CFG_PRE_TRIG_CYCS; /*!< Offset: 0x12c */
+ __I uint32_t UNUSED_SPACE1[2]; /*!< Offset: 0x130 */
+ __I DDR_CSR_APB_MTC_ACQ_ERROR_CNT_TypeDef MTC_ACQ_ERROR_CNT; /*!< Offset: 0x138 */
+ __I uint32_t UNUSED_SPACE2[2]; /*!< Offset: 0x13c */
+ __I DDR_CSR_APB_MTC_ACQ_ERROR_CNT_OVFL_TypeDef MTC_ACQ_ERROR_CNT_OVFL; /*!< Offset: 0x144 */
+ __I uint32_t UNUSED_SPACE3[2]; /*!< Offset: 0x148 */
+ __IO DDR_CSR_APB_CFG_DATA_SEL_FIRST_ERROR_TypeDef CFG_DATA_SEL_FIRST_ERROR; /*!< Offset: 0x150 */
+ __I uint32_t UNUSED_SPACE4[2]; /*!< Offset: 0x154 */
+} DDR_CSR_APB_MTA_TypeDef;
+
+/*------------ DYN_WIDTH_ADJ register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_DQ_WIDTH_TypeDef CFG_DQ_WIDTH; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_ACTIVE_DQ_SEL_TypeDef CFG_ACTIVE_DQ_SEL; /*!< Offset: 0x4 */
+} DDR_CSR_APB_DYN_WIDTH_ADJ_TypeDef;
+
+/*------------ CA_PAR_ERR register bundle definition -----------*/
+typedef struct
+{
+ __I DDR_CSR_APB_STAT_CA_PARITY_ERROR_TypeDef STAT_CA_PARITY_ERROR; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0[2]; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_REQ_TypeDef INIT_CA_PARITY_ERROR_GEN_REQ; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_CMD_TypeDef INIT_CA_PARITY_ERROR_GEN_CMD; /*!< Offset: 0x10 */
+ __I DDR_CSR_APB_INIT_CA_PARITY_ERROR_GEN_ACK_TypeDef INIT_CA_PARITY_ERROR_GEN_ACK; /*!< Offset: 0x14 */
+ __I uint32_t UNUSED_SPACE1[2]; /*!< Offset: 0x18 */
+} DDR_CSR_APB_CA_PAR_ERR_TypeDef;
+
+/*------------ DFI register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_CFG_DFI_T_RDDATA_EN_TypeDef CFG_DFI_T_RDDATA_EN; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_DFI_T_PHY_RDLAT_TypeDef CFG_DFI_T_PHY_RDLAT; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_CFG_DFI_T_PHY_WRLAT_TypeDef CFG_DFI_T_PHY_WRLAT; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_CFG_DFI_PHYUPD_EN_TypeDef CFG_DFI_PHYUPD_EN; /*!< Offset: 0xc */
+ __IO DDR_CSR_APB_INIT_DFI_LP_DATA_REQ_TypeDef INIT_DFI_LP_DATA_REQ; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_INIT_DFI_LP_CTRL_REQ_TypeDef INIT_DFI_LP_CTRL_REQ; /*!< Offset: 0x14 */
+ __I DDR_CSR_APB_STAT_DFI_LP_ACK_TypeDef STAT_DFI_LP_ACK; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_INIT_DFI_LP_WAKEUP_TypeDef INIT_DFI_LP_WAKEUP; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_INIT_DFI_DRAM_CLK_DISABLE_TypeDef INIT_DFI_DRAM_CLK_DISABLE; /*!< Offset: 0x20 */
+ __I DDR_CSR_APB_STAT_DFI_TRAINING_ERROR_TypeDef STAT_DFI_TRAINING_ERROR; /*!< Offset: 0x24 */
+ __I DDR_CSR_APB_STAT_DFI_ERROR_TypeDef STAT_DFI_ERROR; /*!< Offset: 0x28 */
+ __I DDR_CSR_APB_STAT_DFI_ERROR_INFO_TypeDef STAT_DFI_ERROR_INFO; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_CFG_DFI_DATA_BYTE_DISABLE_TypeDef CFG_DFI_DATA_BYTE_DISABLE; /*!< Offset: 0x30 */
+ __I DDR_CSR_APB_STAT_DFI_INIT_COMPLETE_TypeDef STAT_DFI_INIT_COMPLETE; /*!< Offset: 0x34 */
+ __I DDR_CSR_APB_STAT_DFI_TRAINING_COMPLETE_TypeDef STAT_DFI_TRAINING_COMPLETE; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_CFG_DFI_LVL_SEL_TypeDef CFG_DFI_LVL_SEL; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_CFG_DFI_LVL_PERIODIC_TypeDef CFG_DFI_LVL_PERIODIC; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_CFG_DFI_LVL_PATTERN_TypeDef CFG_DFI_LVL_PATTERN; /*!< Offset: 0x44 */
+ __I uint32_t UNUSED_SPACE0[2]; /*!< Offset: 0x48 */
+ __IO DDR_CSR_APB_PHY_DFI_INIT_START_TypeDef PHY_DFI_INIT_START; /*!< Offset: 0x50 */
+ __I uint32_t UNUSED_SPACE1; /*!< Offset: 0x54 */
+} DDR_CSR_APB_DFI_TypeDef;
+
+/*------------ AXI_IF register bundle definition -----------*/
+typedef struct
+{
+ __I uint32_t UNUSED_SPACE0[6]; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_0_TypeDef CFG_AXI_START_ADDRESS_AXI1_0; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI1_1_TypeDef CFG_AXI_START_ADDRESS_AXI1_1; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_0_TypeDef CFG_AXI_START_ADDRESS_AXI2_0; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_CFG_AXI_START_ADDRESS_AXI2_1_TypeDef CFG_AXI_START_ADDRESS_AXI2_1; /*!< Offset: 0x24 */
+ __I uint32_t UNUSED_SPACE1[188]; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_0_TypeDef CFG_AXI_END_ADDRESS_AXI1_0; /*!< Offset: 0x318 */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI1_1_TypeDef CFG_AXI_END_ADDRESS_AXI1_1; /*!< Offset: 0x31c */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_0_TypeDef CFG_AXI_END_ADDRESS_AXI2_0; /*!< Offset: 0x320 */
+ __IO DDR_CSR_APB_CFG_AXI_END_ADDRESS_AXI2_1_TypeDef CFG_AXI_END_ADDRESS_AXI2_1; /*!< Offset: 0x324 */
+ __I uint32_t UNUSED_SPACE2[188]; /*!< Offset: 0x328 */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_0_TypeDef CFG_MEM_START_ADDRESS_AXI1_0; /*!< Offset: 0x618 */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI1_1_TypeDef CFG_MEM_START_ADDRESS_AXI1_1; /*!< Offset: 0x61c */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_0_TypeDef CFG_MEM_START_ADDRESS_AXI2_0; /*!< Offset: 0x620 */
+ __IO DDR_CSR_APB_CFG_MEM_START_ADDRESS_AXI2_1_TypeDef CFG_MEM_START_ADDRESS_AXI2_1; /*!< Offset: 0x624 */
+ __I uint32_t UNUSED_SPACE3[187]; /*!< Offset: 0x628 */
+ __IO DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI1_TypeDef CFG_ENABLE_BUS_HOLD_AXI1; /*!< Offset: 0x914 */
+ __IO DDR_CSR_APB_CFG_ENABLE_BUS_HOLD_AXI2_TypeDef CFG_ENABLE_BUS_HOLD_AXI2; /*!< Offset: 0x918 */
+ __I uint32_t UNUSED_SPACE4[93]; /*!< Offset: 0x91c */
+ __IO DDR_CSR_APB_CFG_AXI_AUTO_PCH_TypeDef CFG_AXI_AUTO_PCH; /*!< Offset: 0xa90 */
+} DDR_CSR_APB_AXI_IF_TypeDef;
+
+/*------------ csr_custom register bundle definition -----------*/
+typedef struct
+{
+ __IO DDR_CSR_APB_PHY_RESET_CONTROL_TypeDef PHY_RESET_CONTROL; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_PHY_PC_RANK_TypeDef PHY_PC_RANK; /*!< Offset: 0x4 */
+ __IO DDR_CSR_APB_PHY_RANKS_TO_TRAIN_TypeDef PHY_RANKS_TO_TRAIN; /*!< Offset: 0x8 */
+ __IO DDR_CSR_APB_PHY_WRITE_REQUEST_TypeDef PHY_WRITE_REQUEST; /*!< Offset: 0xc */
+ __I DDR_CSR_APB_PHY_WRITE_REQUEST_DONE_TypeDef PHY_WRITE_REQUEST_DONE; /*!< Offset: 0x10 */
+ __IO DDR_CSR_APB_PHY_READ_REQUEST_TypeDef PHY_READ_REQUEST; /*!< Offset: 0x14 */
+ __I DDR_CSR_APB_PHY_READ_REQUEST_DONE_TypeDef PHY_READ_REQUEST_DONE; /*!< Offset: 0x18 */
+ __IO DDR_CSR_APB_PHY_WRITE_LEVEL_DELAY_TypeDef PHY_WRITE_LEVEL_DELAY; /*!< Offset: 0x1c */
+ __IO DDR_CSR_APB_PHY_GATE_TRAIN_DELAY_TypeDef PHY_GATE_TRAIN_DELAY; /*!< Offset: 0x20 */
+ __IO DDR_CSR_APB_PHY_EYE_TRAIN_DELAY_TypeDef PHY_EYE_TRAIN_DELAY; /*!< Offset: 0x24 */
+ __IO DDR_CSR_APB_PHY_EYE_PAT_TypeDef PHY_EYE_PAT; /*!< Offset: 0x28 */
+ __IO DDR_CSR_APB_PHY_START_RECAL_TypeDef PHY_START_RECAL; /*!< Offset: 0x2c */
+ __IO DDR_CSR_APB_PHY_CLR_DFI_LVL_PERIODIC_TypeDef PHY_CLR_DFI_LVL_PERIODIC; /*!< Offset: 0x30 */
+ __IO DDR_CSR_APB_PHY_TRAIN_STEP_ENABLE_TypeDef PHY_TRAIN_STEP_ENABLE; /*!< Offset: 0x34 */
+ __IO DDR_CSR_APB_PHY_LPDDR_DQ_CAL_PAT_TypeDef PHY_LPDDR_DQ_CAL_PAT; /*!< Offset: 0x38 */
+ __IO DDR_CSR_APB_PHY_INDPNDT_TRAINING_TypeDef PHY_INDPNDT_TRAINING; /*!< Offset: 0x3c */
+ __IO DDR_CSR_APB_PHY_ENCODED_QUAD_CS_TypeDef PHY_ENCODED_QUAD_CS; /*!< Offset: 0x40 */
+ __IO DDR_CSR_APB_PHY_HALF_CLK_DLY_ENABLE_TypeDef PHY_HALF_CLK_DLY_ENABLE; /*!< Offset: 0x44 */
+ __I uint32_t UNUSED_SPACE0[25]; /*!< Offset: 0x48 */
+} DDR_CSR_APB_csr_custom_TypeDef;
+
+/*------------ DDR_CSR_APB definition -----------*/
+typedef struct
+{
+ __I uint32_t UNUSED_SPACE0[2304]; /*!< Offset: 0x0 */
+ __IO DDR_CSR_APB_ADDR_MAP_TypeDef ADDR_MAP; /*!< Offset: 0x2400 */
+ __I uint32_t UNUSED_SPACE1[242]; /*!< Offset: 0x2438 */
+ __IO DDR_CSR_APB_MC_BASE3_TypeDef MC_BASE3; /*!< Offset: 0x2800 */
+ __I uint32_t UNUSED_SPACE2[1204]; /*!< Offset: 0x2930 */
+ __IO DDR_CSR_APB_MC_BASE1_TypeDef MC_BASE1; /*!< Offset: 0x3c00 */
+ __I uint32_t UNUSED_SPACE3[147]; /*!< Offset: 0x3db4 */
+ __IO DDR_CSR_APB_MC_BASE2_TypeDef MC_BASE2; /*!< Offset: 0x4000 */
+ __IO DDR_CSR_APB_MEM_TEST_TypeDef MEM_TEST; /*!< Offset: 0x4400 */
+ __I uint32_t UNUSED_SPACE4[350]; /*!< Offset: 0x4688 */
+ __IO DDR_CSR_APB_MPFE_TypeDef MPFE; /*!< Offset: 0x4c00 */
+ __I uint32_t UNUSED_SPACE5[215]; /*!< Offset: 0x4ca4 */
+ __IO DDR_CSR_APB_REORDER_TypeDef REORDER; /*!< Offset: 0x5000 */
+ __I uint32_t UNUSED_SPACE6[247]; /*!< Offset: 0x5024 */
+ __IO DDR_CSR_APB_RMW_TypeDef RMW; /*!< Offset: 0x5400 */
+ __I uint32_t UNUSED_SPACE7[254]; /*!< Offset: 0x5408 */
+ __IO DDR_CSR_APB_ECC_TypeDef ECC; /*!< Offset: 0x5800 */
+ __I uint32_t UNUSED_SPACE8[229]; /*!< Offset: 0x586c */
+ __IO DDR_CSR_APB_READ_CAPT_TypeDef READ_CAPT; /*!< Offset: 0x5c00 */
+ __I uint32_t UNUSED_SPACE9[494]; /*!< Offset: 0x5c48 */
+ __IO DDR_CSR_APB_MTA_TypeDef MTA; /*!< Offset: 0x6400 */
+ __I uint32_t UNUSED_SPACE10[1449]; /*!< Offset: 0x655c */
+ __IO DDR_CSR_APB_DYN_WIDTH_ADJ_TypeDef DYN_WIDTH_ADJ; /*!< Offset: 0x7c00 */
+ __I uint32_t UNUSED_SPACE11[254]; /*!< Offset: 0x7c08 */
+ __IO DDR_CSR_APB_CA_PAR_ERR_TypeDef CA_PAR_ERR; /*!< Offset: 0x8000 */
+ __I uint32_t UNUSED_SPACE12[8184]; /*!< Offset: 0x8020 */
+ __IO DDR_CSR_APB_DFI_TypeDef DFI; /*!< Offset: 0x10000 */
+ __I uint32_t UNUSED_SPACE13[2794]; /*!< Offset: 0x10058 */
+ __IO DDR_CSR_APB_AXI_IF_TypeDef AXI_IF; /*!< Offset: 0x12c00 */
+ __I uint32_t UNUSED_SPACE14[41563]; /*!< Offset: 0x13694 */
+ __IO DDR_CSR_APB_csr_custom_TypeDef csr_custom; /*!< Offset: 0x3c000 */
+} DDR_CSR_APB_TypeDef;
+
+
+/*============================== IOSCBCFG definitions ===========================*/
+
+typedef union{ /*!< CONTROL__1 register definition*/
+ __IO uint32_t CONTROL__1;
+ struct
+ {
+ __IO uint32_t INTEN_SCB :1;
+ __IO uint32_t INTEN_ERROR :1;
+ __IO uint32_t INTEN_TIMEOUT :1;
+ __IO uint32_t INTEN_BUSERR :1;
+ __I uint32_t Reserved :4;
+ __IO uint32_t RESET_CYCLE :1;
+ __I uint32_t Reserved1 :7;
+ __IO uint32_t SCBCLOCK_ON :1;
+ __I uint32_t Reserved2 :15;
+ } bitfield;
+} IOSCBCFG_CONTROL__1_TypeDef;
+
+typedef union{ /*!< STATUS register definition*/
+ __I uint32_t STATUS;
+ struct
+ {
+ __I uint32_t SCB_INTERRUPT :1;
+ __I uint32_t SCB_ERROR :1;
+ __I uint32_t TIMEOUT :1;
+ __I uint32_t SCB_BUSERR :1;
+ __I uint32_t Reserved :28;
+ } bitfield;
+} IOSCBCFG_STATUS_TypeDef;
+
+typedef union{ /*!< TIMER register definition*/
+ __IO uint32_t TIMER;
+ struct
+ {
+ __IO uint32_t TIMEOUT :8;
+ __IO uint32_t REQUEST_TIME :8;
+ __I uint32_t Reserved :16;
+ } bitfield;
+} IOSCBCFG_TIMER_TypeDef;
+
+/*------------ IOSCBCFG definition -----------*/
+typedef struct
+{
+ __IO IOSCBCFG_CONTROL__1_TypeDef CONTROL__1; /*!< Offset: 0x0 */
+ __I IOSCBCFG_STATUS_TypeDef STATUS; /*!< Offset: 0x4 */
+ __IO IOSCBCFG_TIMER_TypeDef TIMER; /*!< Offset: 0x8 */
+} IOSCBCFG_TypeDef;
+
+
+/*============================== g5_mss_top_scb_regs definitions ===========================*/
+
+typedef union{ /*!< SOFT_RESET register definition*/
+ __IO uint32_t SOFT_RESET;
+ struct
+ {
+ __O uint32_t NV_MAP :1;
+ __O uint32_t V_MAP :1;
+ __I uint32_t reserved_01 :6;
+ __O uint32_t PERIPH :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t BLOCKID :16;
+ } bitfield;
+} g5_mss_top_scb_regs_SOFT_RESET_TypeDef;
+
+typedef union{ /*!< AXI_WSETUP register definition*/
+ __IO uint32_t AXI_WSETUP;
+ struct
+ {
+ __IO uint32_t ADDR :6;
+ __IO uint32_t BURST :2;
+ __IO uint32_t LENGTH :8;
+ __IO uint32_t SIZE :3;
+ __IO uint32_t LOCK :1;
+ __IO uint32_t CACHE :4;
+ __IO uint32_t PROT :3;
+ __IO uint32_t QOS :4;
+ __IO uint32_t SYSTEM :1;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_WSETUP_TypeDef;
+
+typedef union{ /*!< AXI_WADDR register definition*/
+ __IO uint32_t AXI_WADDR;
+ struct
+ {
+ __IO uint32_t ADDR :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_WADDR_TypeDef;
+
+typedef union{ /*!< AXI_WDATA register definition*/
+ __IO uint32_t AXI_WDATA;
+ struct
+ {
+ __IO uint32_t DATA :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_WDATA_TypeDef;
+
+typedef union{ /*!< AXI_RSETUP register definition*/
+ __IO uint32_t AXI_RSETUP;
+ struct
+ {
+ __IO uint32_t ADDR :6;
+ __IO uint32_t BURST :2;
+ __IO uint32_t LENGTH :8;
+ __IO uint32_t SIZE :3;
+ __IO uint32_t LOCK :1;
+ __IO uint32_t CACHE :4;
+ __IO uint32_t PROT :3;
+ __IO uint32_t QOS :4;
+ __IO uint32_t SYSTEM :1;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_RSETUP_TypeDef;
+
+typedef union{ /*!< AXI_RADDR register definition*/
+ __IO uint32_t AXI_RADDR;
+ struct
+ {
+ __IO uint32_t ADDR :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_RADDR_TypeDef;
+
+typedef union{ /*!< AXI_RDATA register definition*/
+ __IO uint32_t AXI_RDATA;
+ struct
+ {
+ __IO uint32_t DATA :32;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_RDATA_TypeDef;
+
+typedef union{ /*!< AXI_STATUS register definition*/
+ __IO uint32_t AXI_STATUS;
+ struct
+ {
+ __IO uint32_t WRITE_BUSY :1;
+ __IO uint32_t READ_BUSY :1;
+ __IO uint32_t WRITE_ERROR :1;
+ __IO uint32_t READ_ERROR :1;
+ __IO uint32_t WRITE_COUNT :5;
+ __IO uint32_t READ_COUNT :5;
+ __IO uint32_t READ_OVERRUN :1;
+ __IO uint32_t WRITE_OVERRUN :1;
+ __IO uint32_t WRITE_RESPONSE :2;
+ __IO uint32_t READ_RESPONSE :2;
+ __IO uint32_t MSS_RESET :1;
+ __I uint32_t reserved_01 :3;
+ __IO uint32_t INT_ENABLE_READ_ORUN :1;
+ __IO uint32_t INT_ENABLE_WRITE_ORUN :1;
+ __IO uint32_t INT_ENABLE_RRESP :1;
+ __IO uint32_t INT_ENABLE_WRESP :1;
+ __IO uint32_t INT_ENABLE_SYSREG :1;
+ __I uint32_t reserved_02 :3;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_STATUS_TypeDef;
+
+typedef union{ /*!< AXI_CONTROL register definition*/
+ __IO uint32_t AXI_CONTROL;
+ struct
+ {
+ __IO uint32_t ABORT :1;
+ __I uint32_t reserved_01 :7;
+ __IO uint32_t STALL_WRITE :1;
+ __I uint32_t reserved_02 :7;
+ __IO uint32_t START_WRITE :1;
+ __I uint32_t reserved_03 :15;
+ } bitfield;
+} g5_mss_top_scb_regs_AXI_CONTROL_TypeDef;
+
+typedef union{ /*!< REDUNDANCY register definition*/
+ __IO uint32_t REDUNDANCY;
+ struct
+ {
+ __IO uint32_t RESET :1;
+ __IO uint32_t ISOLATE :1;
+ __IO uint32_t NOCLOCK :1;
+ __I uint32_t reserved_01 :29;
+ } bitfield;
+} g5_mss_top_scb_regs_REDUNDANCY_TypeDef;
+
+typedef union{ /*!< BIST_CONFIG register definition*/
+ __IO uint32_t BIST_CONFIG;
+ struct
+ {
+ __I uint32_t enabled :1;
+ __IO uint32_t enable :1;
+ __IO uint32_t reset :1;
+ __IO uint32_t diag_select :1;
+ __I uint32_t reserved_01 :4;
+ __IO uint32_t select :5;
+ __I uint32_t reserved_02 :3;
+ __IO uint32_t margin :3;
+ __I uint32_t reserved_03 :13;
+ } bitfield;
+} g5_mss_top_scb_regs_BIST_CONFIG_TypeDef;
+
+typedef union{ /*!< BIST_DATA register definition*/
+ __IO uint32_t BIST_DATA;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BIST_DATA_TypeDef;
+
+typedef union{ /*!< BIST_COMMAND register definition*/
+ __IO uint32_t BIST_COMMAND;
+ struct
+ {
+ __IO uint32_t update :1;
+ __IO uint32_t capture :1;
+ __IO uint32_t shift :1;
+ __I uint32_t busy :1;
+ __I uint32_t reserved_01 :4;
+ __IO uint32_t length :7;
+ __I uint32_t reserved_02 :17;
+ } bitfield;
+} g5_mss_top_scb_regs_BIST_COMMAND_TypeDef;
+
+typedef union{ /*!< MSS_RESET_CR register definition*/
+ __IO uint32_t MSS_RESET_CR;
+ struct
+ {
+ __IO uint32_t CPU :1;
+ __IO uint32_t MSS :1;
+ __I uint32_t CPUINRESET :1;
+ __IO uint32_t REBOOT_REQUEST :1;
+ __I uint32_t reserved_01 :4;
+ __IO uint32_t SGMII :1;
+ __I uint32_t reserved_02 :7;
+ __I uint32_t REASON :9;
+ __I uint32_t reserved_03 :7;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_RESET_CR_TypeDef;
+
+typedef union{ /*!< MSS_STATUS register definition*/
+ __IO uint32_t MSS_STATUS;
+ struct
+ {
+ __IO uint32_t boot_status :4;
+ __I uint32_t watchdog :5;
+ __I uint32_t debug_active :1;
+ __I uint32_t halt_cpu0 :1;
+ __I uint32_t halt_cpu1 :1;
+ __I uint32_t halt_cpu2 :1;
+ __I uint32_t halt_cpu3 :1;
+ __I uint32_t halt_cpu4 :1;
+ __I uint32_t ecc_error_l2 :1;
+ __I uint32_t ecc_error_other :1;
+ __I uint32_t reserved_01 :15;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_STATUS_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR0 register definition*/
+ __IO uint32_t BOOT_ADDR0;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR0_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR1 register definition*/
+ __IO uint32_t BOOT_ADDR1;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR1_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR2 register definition*/
+ __IO uint32_t BOOT_ADDR2;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR2_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR3 register definition*/
+ __IO uint32_t BOOT_ADDR3;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR3_TypeDef;
+
+typedef union{ /*!< BOOT_ADDR4 register definition*/
+ __IO uint32_t BOOT_ADDR4;
+ struct
+ {
+ __IO uint32_t address :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ADDR4_TypeDef;
+
+typedef union{ /*!< BOOT_ROM0 register definition*/
+ __IO uint32_t BOOT_ROM0;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM0_TypeDef;
+
+typedef union{ /*!< BOOT_ROM1 register definition*/
+ __IO uint32_t BOOT_ROM1;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM1_TypeDef;
+
+typedef union{ /*!< BOOT_ROM2 register definition*/
+ __IO uint32_t BOOT_ROM2;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM2_TypeDef;
+
+typedef union{ /*!< BOOT_ROM3 register definition*/
+ __IO uint32_t BOOT_ROM3;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM3_TypeDef;
+
+typedef union{ /*!< BOOT_ROM4 register definition*/
+ __IO uint32_t BOOT_ROM4;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM4_TypeDef;
+
+typedef union{ /*!< BOOT_ROM5 register definition*/
+ __IO uint32_t BOOT_ROM5;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM5_TypeDef;
+
+typedef union{ /*!< BOOT_ROM6 register definition*/
+ __IO uint32_t BOOT_ROM6;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM6_TypeDef;
+
+typedef union{ /*!< BOOT_ROM7 register definition*/
+ __IO uint32_t BOOT_ROM7;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_BOOT_ROM7_TypeDef;
+
+typedef union{ /*!< FLASH_FREEZE register definition*/
+ __IO uint32_t FLASH_FREEZE;
+ struct
+ {
+ __IO uint32_t in_progress :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_FLASH_FREEZE_TypeDef;
+
+typedef union{ /*!< G5CIO register definition*/
+ __IO uint32_t G5CIO;
+ struct
+ {
+ __IO uint32_t ioout :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_G5CIO_TypeDef;
+
+typedef union{ /*!< DEVICE_ID register definition*/
+ __IO uint32_t DEVICE_ID;
+ struct
+ {
+ __IO uint32_t idp :16;
+ __IO uint32_t idv :4;
+ __I uint32_t reserved_01 :12;
+ } bitfield;
+} g5_mss_top_scb_regs_DEVICE_ID_TypeDef;
+
+typedef union{ /*!< MESSAGE_INT register definition*/
+ __IO uint32_t MESSAGE_INT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_MESSAGE_INT_TypeDef;
+
+typedef union{ /*!< MESSAGE register definition*/
+ __IO uint32_t MESSAGE;
+ struct
+ {
+ __IO uint32_t data :32;
+ } bitfield;
+} g5_mss_top_scb_regs_MESSAGE_TypeDef;
+
+typedef union{ /*!< DEVRST_INT register definition*/
+ __IO uint32_t DEVRST_INT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_DEVRST_INT_TypeDef;
+
+typedef union{ /*!< SCB_INTERRUPT register definition*/
+ __IO uint32_t SCB_INTERRUPT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_SCB_INTERRUPT_TypeDef;
+
+typedef union{ /*!< MSS_INTERRUPT register definition*/
+ __IO uint32_t MSS_INTERRUPT;
+ struct
+ {
+ __IO uint32_t active :1;
+ __I uint32_t reserved_01 :31;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_INTERRUPT_TypeDef;
+
+typedef union{ /*!< DEVICE_CONFIG_CR register definition*/
+ __IO uint32_t DEVICE_CONFIG_CR;
+ struct
+ {
+ __IO uint32_t FACTORY_TEST_MODE :1;
+ __I uint32_t RESERVED :1;
+ __IO uint32_t CRYPTO_DISABLE :1;
+ __IO uint32_t CAN_ALLOWED :1;
+ __IO uint32_t CPU_ALLOWED :1;
+ __IO uint32_t CPU_DISABLE :1;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t CPU_BIST_DISABLE :1;
+ __I uint32_t reserved_02 :7;
+ __IO uint32_t DISABLE_XIP :1;
+ __I uint32_t reserved_03 :15;
+ } bitfield;
+} g5_mss_top_scb_regs_DEVICE_CONFIG_CR_TypeDef;
+
+typedef union{ /*!< ATHENA_CR register definition*/
+ __IO uint32_t ATHENA_CR;
+ struct
+ {
+ __IO uint32_t mss_mode :3;
+ __I uint32_t reserved_01 :1;
+ __IO uint32_t stream_enable :1;
+ __I uint32_t reserved_02 :27;
+ } bitfield;
+} g5_mss_top_scb_regs_ATHENA_CR_TypeDef;
+
+typedef union{ /*!< ENVM_CR register definition*/
+ __IO uint32_t ENVM_CR;
+ struct
+ {
+ __IO uint32_t clock_period :6;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t clock_continuous :1;
+ __IO uint32_t clock_suppress :1;
+ __I uint32_t reserved_02 :6;
+ __IO uint32_t readahead :1;
+ __IO uint32_t slowread :1;
+ __IO uint32_t interrupt_enable :1;
+ __I uint32_t reserved_03 :5;
+ __IO uint32_t timer :8;
+ } bitfield;
+} g5_mss_top_scb_regs_ENVM_CR_TypeDef;
+
+typedef union{ /*!< ENVM_POWER_CR register definition*/
+ __IO uint32_t ENVM_POWER_CR;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t pd1 :1;
+ __IO uint32_t pd2 :1;
+ __IO uint32_t pd3 :1;
+ __IO uint32_t pd4 :1;
+ __IO uint32_t iso :1;
+ __IO uint32_t sleep :1;
+ __I uint32_t reserved_01 :1;
+ __IO uint32_t override :1;
+ __I uint32_t reserved_02 :23;
+ } bitfield;
+} g5_mss_top_scb_regs_ENVM_POWER_CR_TypeDef;
+
+typedef union{ /*!< RAM_SHUTDOWN_CR register definition*/
+ __IO uint32_t RAM_SHUTDOWN_CR;
+ struct
+ {
+ __IO uint32_t can0 :1;
+ __IO uint32_t can1 :1;
+ __IO uint32_t usb :1;
+ __IO uint32_t gem0 :1;
+ __IO uint32_t gem1 :1;
+ __IO uint32_t mmc :1;
+ __IO uint32_t athena :1;
+ __IO uint32_t ddrc :1;
+ __IO uint32_t e51 :1;
+ __IO uint32_t u54_1 :1;
+ __IO uint32_t u54_2 :1;
+ __IO uint32_t u54_3 :1;
+ __IO uint32_t u54_4 :1;
+ __IO uint32_t l2 :1;
+ __I uint32_t reserved_01 :18;
+ } bitfield;
+} g5_mss_top_scb_regs_RAM_SHUTDOWN_CR_TypeDef;
+
+typedef union{ /*!< RAM_MARGIN_CR register definition*/
+ __IO uint32_t RAM_MARGIN_CR;
+ struct
+ {
+ __IO uint32_t enable :1;
+ __IO uint32_t can0 :2;
+ __IO uint32_t can1 :2;
+ __IO uint32_t usb :2;
+ __IO uint32_t gem0 :2;
+ __IO uint32_t gem1 :2;
+ __IO uint32_t mmc :2;
+ __IO uint32_t ddrc :2;
+ __IO uint32_t e51 :2;
+ __IO uint32_t u54_1 :2;
+ __IO uint32_t u54_2 :2;
+ __IO uint32_t u54_3 :2;
+ __IO uint32_t u54_4 :2;
+ __IO uint32_t l2 :2;
+ __I uint32_t reserved_01 :5;
+ } bitfield;
+} g5_mss_top_scb_regs_RAM_MARGIN_CR_TypeDef;
+
+typedef union{ /*!< TRACE_CR register definition*/
+ __IO uint32_t TRACE_CR;
+ struct
+ {
+ __IO uint32_t CPU_DEBUG_DISABLE :1;
+ __IO uint32_t ULTRASOC_DISABLE_JTAG :1;
+ __IO uint32_t ULTRASOC_DISABLE_AXI :1;
+ __I uint32_t reserved_01 :5;
+ __IO uint32_t ULTRASOC_FABRIC :1;
+ __I uint32_t reserved_02 :23;
+ } bitfield;
+} g5_mss_top_scb_regs_TRACE_CR_TypeDef;
+
+typedef union{ /*!< MSSIO_CONTROL_CR register definition*/
+ __IO uint32_t MSSIO_CONTROL_CR;
+ struct
+ {
+ __IO uint32_t lp_state_mss :1;
+ __IO uint32_t lp_state_ip_mss :1;
+ __IO uint32_t lp_state_op_mss :1;
+ __IO uint32_t lp_state_persist_mss :1;
+ __IO uint32_t lp_state_bypass_mss :1;
+ __IO uint32_t lp_pll_locked_mss :1;
+ __IO uint32_t lp_stop_clocks_out_mss :1;
+ __I uint32_t lp_stop_clocks_done_mss :1;
+ __IO uint32_t mss_dce :3;
+ __IO uint32_t mss_core_up :1;
+ __IO uint32_t mss_flash_valid :1;
+ __IO uint32_t mss_io_en :1;
+ __IO uint32_t mss_sel_hw_dyn :1;
+ __IO uint32_t mss_sel_hw_def :1;
+ __I uint32_t reserved_01 :16;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_CONTROL_CR_TypeDef;
+
+typedef union{ /*!< MSS_IO_LOCKDOWN_CR register definition*/
+ __I uint32_t MSS_IO_LOCKDOWN_CR;
+ struct
+ {
+ __I uint32_t mssio_b2_lockdn_en :1;
+ __I uint32_t mssio_b4_lockdn_en :1;
+ __I uint32_t sgmii_io_lockdn_en :1;
+ __I uint32_t ddr_io_lockdn_en :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_MSS_IO_LOCKDOWN_CR_TypeDef;
+
+typedef union{ /*!< MSSIO_BANK2_CFG_CR register definition*/
+ __IO uint32_t MSSIO_BANK2_CFG_CR;
+ struct
+ {
+ __IO uint32_t bank_pcode :6;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t bank_ncode :6;
+ __I uint32_t reserved_02 :2;
+ __IO uint32_t vs :4;
+ __I uint32_t reserved_03 :12;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_BANK2_CFG_CR_TypeDef;
+
+typedef union{ /*!< MSSIO_BANK4_CFG_CR register definition*/
+ __IO uint32_t MSSIO_BANK4_CFG_CR;
+ struct
+ {
+ __IO uint32_t bank_pcode :6;
+ __I uint32_t reserved_01 :2;
+ __IO uint32_t bank_ncode :6;
+ __I uint32_t reserved_02 :2;
+ __IO uint32_t vs :4;
+ __I uint32_t reserved_03 :12;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_BANK4_CFG_CR_TypeDef;
+
+typedef union{ /*!< DLL0_CTRL0 register definition*/
+ __IO uint32_t DLL0_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL0_CTRL1 register definition*/
+ __IO uint32_t DLL0_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL0_STAT0 register definition*/
+ __IO uint32_t DLL0_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_STAT0_TypeDef;
+
+typedef union{ /*!< DLL0_STAT1 register definition*/
+ __I uint32_t DLL0_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_STAT1_TypeDef;
+
+typedef union{ /*!< DLL0_STAT2 register definition*/
+ __I uint32_t DLL0_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_STAT2_TypeDef;
+
+typedef union{ /*!< DLL0_TEST register definition*/
+ __IO uint32_t DLL0_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL0_TEST_TypeDef;
+
+typedef union{ /*!< DLL1_CTRL0 register definition*/
+ __IO uint32_t DLL1_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL1_CTRL1 register definition*/
+ __IO uint32_t DLL1_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL1_STAT0 register definition*/
+ __IO uint32_t DLL1_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_STAT0_TypeDef;
+
+typedef union{ /*!< DLL1_STAT1 register definition*/
+ __I uint32_t DLL1_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_STAT1_TypeDef;
+
+typedef union{ /*!< DLL1_STAT2 register definition*/
+ __I uint32_t DLL1_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_STAT2_TypeDef;
+
+typedef union{ /*!< DLL1_TEST register definition*/
+ __IO uint32_t DLL1_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL1_TEST_TypeDef;
+
+typedef union{ /*!< DLL2_CTRL0 register definition*/
+ __IO uint32_t DLL2_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL2_CTRL1 register definition*/
+ __IO uint32_t DLL2_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL2_STAT0 register definition*/
+ __IO uint32_t DLL2_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_STAT0_TypeDef;
+
+typedef union{ /*!< DLL2_STAT1 register definition*/
+ __I uint32_t DLL2_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_STAT1_TypeDef;
+
+typedef union{ /*!< DLL2_STAT2 register definition*/
+ __I uint32_t DLL2_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_STAT2_TypeDef;
+
+typedef union{ /*!< DLL2_TEST register definition*/
+ __IO uint32_t DLL2_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL2_TEST_TypeDef;
+
+typedef union{ /*!< DLL3_CTRL0 register definition*/
+ __IO uint32_t DLL3_CTRL0;
+ struct
+ {
+ __IO uint32_t phase_p :2;
+ __IO uint32_t phase_s :2;
+ __IO uint32_t sel_p :2;
+ __IO uint32_t sel_s :2;
+ __IO uint32_t ref_sel :1;
+ __IO uint32_t fb_sel :1;
+ __IO uint32_t div_sel :1;
+ __I uint32_t reserved :3;
+ __IO uint32_t alu_upd :2;
+ __I uint32_t reserved2 :3;
+ __IO uint32_t lock_frc :1;
+ __IO uint32_t lock_flt :2;
+ __I uint32_t reserved3 :2;
+ __IO uint32_t lock_high :4;
+ __IO uint32_t lock_low :4;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_CTRL0_TypeDef;
+
+typedef union{ /*!< DLL3_CTRL1 register definition*/
+ __IO uint32_t DLL3_CTRL1;
+ struct
+ {
+ __IO uint32_t set_alu :8;
+ __IO uint32_t adj_del4 :7;
+ __IO uint32_t test_s :1;
+ __I uint32_t reserved :7;
+ __IO uint32_t test_ring :1;
+ __IO uint32_t init_code :6;
+ __IO uint32_t relock_fast :1;
+ __I uint32_t reserved2 :1;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_CTRL1_TypeDef;
+
+typedef union{ /*!< DLL3_STAT0 register definition*/
+ __IO uint32_t DLL3_STAT0;
+ struct
+ {
+ __IO uint32_t reset :1;
+ __IO uint32_t bypass :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :3;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :1;
+ __I uint32_t reserved8 :1;
+ __IO uint32_t phase_move_clk :1;
+ __I uint32_t reserved9 :1;
+ __I uint32_t reserved10 :2;
+ __I uint32_t reserved11 :8;
+ __I uint32_t reserved12 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_STAT0_TypeDef;
+
+typedef union{ /*!< DLL3_STAT1 register definition*/
+ __I uint32_t DLL3_STAT1;
+ struct
+ {
+ __I uint32_t sro_del4 :7;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :8;
+ __I uint32_t sro_alu_cnt :9;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :2;
+ __I uint32_t reserved5 :2;
+ __I uint32_t reserved6 :2;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_STAT1_TypeDef;
+
+typedef union{ /*!< DLL3_STAT2 register definition*/
+ __I uint32_t DLL3_STAT2;
+ struct
+ {
+ __I uint32_t reserved :1;
+ __I uint32_t reserved2 :1;
+ __I uint32_t sro_lock :1;
+ __I uint32_t reserved3 :1;
+ __I uint32_t reserved4 :1;
+ __I uint32_t reserved5 :1;
+ __I uint32_t reserved6 :1;
+ __I uint32_t reserved7 :9;
+ __I uint32_t reserved8 :8;
+ __I uint32_t reserved9 :8;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_STAT2_TypeDef;
+
+typedef union{ /*!< DLL3_TEST register definition*/
+ __IO uint32_t DLL3_TEST;
+ struct
+ {
+ __IO uint32_t cfm_enable :1;
+ __IO uint32_t cfm_select :1;
+ __IO uint32_t ref_select :1;
+ __I uint32_t reserved :1;
+ __I uint32_t reserved_01 :28;
+ } bitfield;
+} g5_mss_top_scb_regs_DLL3_TEST_TypeDef;
+
+typedef union{ /*!< MSSIO_VB2_CFG register definition*/
+ __IO uint32_t MSSIO_VB2_CFG;
+ struct
+ {
+ __IO uint32_t dpc_io_cfg_ibufmd_0 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_1 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_0 :1;
+ __IO uint32_t dpc_io_cfg_drv_1 :1;
+ __IO uint32_t dpc_io_cfg_drv_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_3 :1;
+ __IO uint32_t dpc_io_cfg_clamp :1;
+ __IO uint32_t dpc_io_cfg_enhyst :1;
+ __IO uint32_t dpc_io_cfg_lockdn_en :1;
+ __IO uint32_t dpc_io_cfg_wpd :1;
+ __IO uint32_t dpc_io_cfg_wpu :1;
+ __IO uint32_t dpc_io_cfg_atp_en :1;
+ __IO uint32_t dpc_io_cfg_lp_persist_en :1;
+ __IO uint32_t dpc_io_cfg_lp_bypass_en :1;
+ __I uint32_t reserved_01 :17;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_VB2_CFG_TypeDef;
+
+typedef union{ /*!< MSSIO_VB4_CFG register definition*/
+ __IO uint32_t MSSIO_VB4_CFG;
+ struct
+ {
+ __IO uint32_t dpc_io_cfg_ibufmd_0 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_1 :1;
+ __IO uint32_t dpc_io_cfg_ibufmd_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_0 :1;
+ __IO uint32_t dpc_io_cfg_drv_1 :1;
+ __IO uint32_t dpc_io_cfg_drv_2 :1;
+ __IO uint32_t dpc_io_cfg_drv_3 :1;
+ __IO uint32_t dpc_io_cfg_clamp :1;
+ __IO uint32_t dpc_io_cfg_enhyst :1;
+ __IO uint32_t dpc_io_cfg_lockdn_en :1;
+ __IO uint32_t dpc_io_cfg_wpd :1;
+ __IO uint32_t dpc_io_cfg_wpu :1;
+ __IO uint32_t dpc_io_cfg_atp_en :1;
+ __IO uint32_t dpc_io_cfg_lp_persist_en :1;
+ __IO uint32_t dpc_io_cfg_lp_bypass_en :1;
+ __I uint32_t reserved_01 :17;
+ } bitfield;
+} g5_mss_top_scb_regs_MSSIO_VB4_CFG_TypeDef;
+
+/*------------ g5_mss_top_scb_regs definition -----------*/
+typedef struct
+{
+ __IO g5_mss_top_scb_regs_SOFT_RESET_TypeDef SOFT_RESET; /*!< Offset: 0x0 */
+ __I uint32_t UNUSED_SPACE0[3]; /*!< Offset: 0x4 */
+ __IO g5_mss_top_scb_regs_AXI_WSETUP_TypeDef AXI_WSETUP; /*!< Offset: 0x10 */
+ __IO g5_mss_top_scb_regs_AXI_WADDR_TypeDef AXI_WADDR; /*!< Offset: 0x14 */
+ __IO g5_mss_top_scb_regs_AXI_WDATA_TypeDef AXI_WDATA; /*!< Offset: 0x18 */
+ __IO g5_mss_top_scb_regs_AXI_RSETUP_TypeDef AXI_RSETUP; /*!< Offset: 0x1c */
+ __IO g5_mss_top_scb_regs_AXI_RADDR_TypeDef AXI_RADDR; /*!< Offset: 0x20 */
+ __IO g5_mss_top_scb_regs_AXI_RDATA_TypeDef AXI_RDATA; /*!< Offset: 0x24 */
+ __IO g5_mss_top_scb_regs_AXI_STATUS_TypeDef AXI_STATUS; /*!< Offset: 0x28 */
+ __IO g5_mss_top_scb_regs_AXI_CONTROL_TypeDef AXI_CONTROL; /*!< Offset: 0x2c */
+ __IO g5_mss_top_scb_regs_REDUNDANCY_TypeDef REDUNDANCY; /*!< Offset: 0x30 */
+ __I uint32_t UNUSED_SPACE1[7]; /*!< Offset: 0x34 */
+ __IO g5_mss_top_scb_regs_BIST_CONFIG_TypeDef BIST_CONFIG; /*!< Offset: 0x50 */
+ __IO g5_mss_top_scb_regs_BIST_DATA_TypeDef BIST_DATA; /*!< Offset: 0x54 */
+ __IO g5_mss_top_scb_regs_BIST_COMMAND_TypeDef BIST_COMMAND; /*!< Offset: 0x58 */
+ __I uint32_t UNUSED_SPACE2[41]; /*!< Offset: 0x5c */
+ __IO g5_mss_top_scb_regs_MSS_RESET_CR_TypeDef MSS_RESET_CR; /*!< Offset: 0x100 */
+ __IO g5_mss_top_scb_regs_MSS_STATUS_TypeDef MSS_STATUS; /*!< Offset: 0x104 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR0_TypeDef BOOT_ADDR0; /*!< Offset: 0x108 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR1_TypeDef BOOT_ADDR1; /*!< Offset: 0x10c */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR2_TypeDef BOOT_ADDR2; /*!< Offset: 0x110 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR3_TypeDef BOOT_ADDR3; /*!< Offset: 0x114 */
+ __IO g5_mss_top_scb_regs_BOOT_ADDR4_TypeDef BOOT_ADDR4; /*!< Offset: 0x118 */
+ __I uint32_t UNUSED_SPACE3; /*!< Offset: 0x11c */
+ __IO g5_mss_top_scb_regs_BOOT_ROM0_TypeDef BOOT_ROM0; /*!< Offset: 0x120 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM1_TypeDef BOOT_ROM1; /*!< Offset: 0x124 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM2_TypeDef BOOT_ROM2; /*!< Offset: 0x128 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM3_TypeDef BOOT_ROM3; /*!< Offset: 0x12c */
+ __IO g5_mss_top_scb_regs_BOOT_ROM4_TypeDef BOOT_ROM4; /*!< Offset: 0x130 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM5_TypeDef BOOT_ROM5; /*!< Offset: 0x134 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM6_TypeDef BOOT_ROM6; /*!< Offset: 0x138 */
+ __IO g5_mss_top_scb_regs_BOOT_ROM7_TypeDef BOOT_ROM7; /*!< Offset: 0x13c */
+ __I uint32_t UNUSED_SPACE4[16]; /*!< Offset: 0x140 */
+ __IO g5_mss_top_scb_regs_FLASH_FREEZE_TypeDef FLASH_FREEZE; /*!< Offset: 0x180 */
+ __IO g5_mss_top_scb_regs_G5CIO_TypeDef G5CIO; /*!< Offset: 0x184 */
+ __IO g5_mss_top_scb_regs_DEVICE_ID_TypeDef DEVICE_ID; /*!< Offset: 0x188 */
+ __IO g5_mss_top_scb_regs_MESSAGE_INT_TypeDef MESSAGE_INT; /*!< Offset: 0x18c */
+ __IO g5_mss_top_scb_regs_MESSAGE_TypeDef MESSAGE; /*!< Offset: 0x190 */
+ __IO g5_mss_top_scb_regs_DEVRST_INT_TypeDef DEVRST_INT; /*!< Offset: 0x194 */
+ __IO g5_mss_top_scb_regs_SCB_INTERRUPT_TypeDef SCB_INTERRUPT; /*!< Offset: 0x198 */
+ __IO g5_mss_top_scb_regs_MSS_INTERRUPT_TypeDef MSS_INTERRUPT; /*!< Offset: 0x19c */
+ __IO g5_mss_top_scb_regs_DEVICE_CONFIG_CR_TypeDef DEVICE_CONFIG_CR; /*!< Offset: 0x1a0 */
+ __IO g5_mss_top_scb_regs_ATHENA_CR_TypeDef ATHENA_CR; /*!< Offset: 0x1a4 */
+ __IO g5_mss_top_scb_regs_ENVM_CR_TypeDef ENVM_CR; /*!< Offset: 0x1a8 */
+ __IO g5_mss_top_scb_regs_ENVM_POWER_CR_TypeDef ENVM_POWER_CR; /*!< Offset: 0x1ac */
+ __IO g5_mss_top_scb_regs_RAM_SHUTDOWN_CR_TypeDef RAM_SHUTDOWN_CR; /*!< Offset: 0x1b0 */
+ __IO g5_mss_top_scb_regs_RAM_MARGIN_CR_TypeDef RAM_MARGIN_CR; /*!< Offset: 0x1b4 */
+ __IO g5_mss_top_scb_regs_TRACE_CR_TypeDef TRACE_CR; /*!< Offset: 0x1b8 */
+ __IO g5_mss_top_scb_regs_MSSIO_CONTROL_CR_TypeDef MSSIO_CONTROL_CR; /*!< Offset: 0x1bc */
+ __I g5_mss_top_scb_regs_MSS_IO_LOCKDOWN_CR_TypeDef MSS_IO_LOCKDOWN_CR; /*!< Offset: 0x1c0 */
+ __IO g5_mss_top_scb_regs_MSSIO_BANK2_CFG_CR_TypeDef MSSIO_BANK2_CFG_CR; /*!< Offset: 0x1c4 */
+ __IO g5_mss_top_scb_regs_MSSIO_BANK4_CFG_CR_TypeDef MSSIO_BANK4_CFG_CR; /*!< Offset: 0x1c8 */
+ __I uint32_t UNUSED_SPACE5[13]; /*!< Offset: 0x1cc */
+ __IO g5_mss_top_scb_regs_DLL0_CTRL0_TypeDef DLL0_CTRL0; /*!< Offset: 0x200 */
+ __IO g5_mss_top_scb_regs_DLL0_CTRL1_TypeDef DLL0_CTRL1; /*!< Offset: 0x204 */
+ __IO g5_mss_top_scb_regs_DLL0_STAT0_TypeDef DLL0_STAT0; /*!< Offset: 0x208 */
+ __I g5_mss_top_scb_regs_DLL0_STAT1_TypeDef DLL0_STAT1; /*!< Offset: 0x20c */
+ __I g5_mss_top_scb_regs_DLL0_STAT2_TypeDef DLL0_STAT2; /*!< Offset: 0x210 */
+ __IO g5_mss_top_scb_regs_DLL0_TEST_TypeDef DLL0_TEST; /*!< Offset: 0x214 */
+ __I uint32_t UNUSED_SPACE6[2]; /*!< Offset: 0x218 */
+ __IO g5_mss_top_scb_regs_DLL1_CTRL0_TypeDef DLL1_CTRL0; /*!< Offset: 0x220 */
+ __IO g5_mss_top_scb_regs_DLL1_CTRL1_TypeDef DLL1_CTRL1; /*!< Offset: 0x224 */
+ __IO g5_mss_top_scb_regs_DLL1_STAT0_TypeDef DLL1_STAT0; /*!< Offset: 0x228 */
+ __I g5_mss_top_scb_regs_DLL1_STAT1_TypeDef DLL1_STAT1; /*!< Offset: 0x22c */
+ __I g5_mss_top_scb_regs_DLL1_STAT2_TypeDef DLL1_STAT2; /*!< Offset: 0x230 */
+ __IO g5_mss_top_scb_regs_DLL1_TEST_TypeDef DLL1_TEST; /*!< Offset: 0x234 */
+ __I uint32_t UNUSED_SPACE7[2]; /*!< Offset: 0x238 */
+ __IO g5_mss_top_scb_regs_DLL2_CTRL0_TypeDef DLL2_CTRL0; /*!< Offset: 0x240 */
+ __IO g5_mss_top_scb_regs_DLL2_CTRL1_TypeDef DLL2_CTRL1; /*!< Offset: 0x244 */
+ __IO g5_mss_top_scb_regs_DLL2_STAT0_TypeDef DLL2_STAT0; /*!< Offset: 0x248 */
+ __I g5_mss_top_scb_regs_DLL2_STAT1_TypeDef DLL2_STAT1; /*!< Offset: 0x24c */
+ __I g5_mss_top_scb_regs_DLL2_STAT2_TypeDef DLL2_STAT2; /*!< Offset: 0x250 */
+ __IO g5_mss_top_scb_regs_DLL2_TEST_TypeDef DLL2_TEST; /*!< Offset: 0x254 */
+ __I uint32_t UNUSED_SPACE8[2]; /*!< Offset: 0x258 */
+ __IO g5_mss_top_scb_regs_DLL3_CTRL0_TypeDef DLL3_CTRL0; /*!< Offset: 0x260 */
+ __IO g5_mss_top_scb_regs_DLL3_CTRL1_TypeDef DLL3_CTRL1; /*!< Offset: 0x264 */
+ __IO g5_mss_top_scb_regs_DLL3_STAT0_TypeDef DLL3_STAT0; /*!< Offset: 0x268 */
+ __I g5_mss_top_scb_regs_DLL3_STAT1_TypeDef DLL3_STAT1; /*!< Offset: 0x26c */
+ __I g5_mss_top_scb_regs_DLL3_STAT2_TypeDef DLL3_STAT2; /*!< Offset: 0x270 */
+ __IO g5_mss_top_scb_regs_DLL3_TEST_TypeDef DLL3_TEST; /*!< Offset: 0x274 */
+ __IO g5_mss_top_scb_regs_MSSIO_VB2_CFG_TypeDef MSSIO_VB2_CFG; /*!< Offset: 0x278 */
+ __IO g5_mss_top_scb_regs_MSSIO_VB4_CFG_TypeDef MSSIO_VB4_CFG; /*!< Offset: 0x27c */
+} g5_mss_top_scb_regs_TypeDef;
+
+
+#define CFG_DDR_SGMII_PHY_BASE (0x20007000) /*!< ( CFG_DDR_SGMII_PHY ) Base Address */
+#define DDRCFG_BASE (0x20080000) /*!< ( DDRCFG ) Base Address */
+
+#define SYSREGSCB_BASE (0x20003000) /*!< ( SYSREGSCB ) Base Address */
+#define IOSCBCFG_BASE (0x37080000) /*!< ( IOSCBCFG ) Base Address */
+
+extern CFG_DDR_SGMII_PHY_TypeDef * const CFG_DDR_SGMII_PHY ;
+extern DDR_CSR_APB_TypeDef * const DDRCFG ;
+extern IOSCBCFG_TypeDef * const SCBCFG_REGS ;
+extern g5_mss_top_scb_regs_TypeDef * const SCB_REGS ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_REGS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_test_pattern.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_test_pattern.c
new file mode 100644
index 00000000..c125b72f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_ddr_test_pattern.c
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+#include
+
+const uint32_t ddr_test_pattern[768] =
+{
+ 0x48b301bc, 0x79330115, 0xf5330139, 0x693301bc,
+ 0x893b00a9, 0x093b0128, 0x0d3b00c9, 0x551b00cd,
+ 0x161b0077, 0x8d510197, 0x0127581b, 0x00e7161b,
+ 0x01066633, 0x561b8d31, 0x8d310037, 0x8f3b9da9,
+ 0xd61b01e5, 0x959b0112, 0xd51b00f2, 0x8e4d0132,
+ 0x00d2959b, 0x8e2d8dc9, 0x00a2d29b, 0x005642b3,
+ 0xa4507637, 0x005f0f3b, 0x00dac5b3, 0xceb6061b,
+ 0x00cf063b, 0x01a5f5b3, 0x0155c5b3, 0x01460a3b,
+ 0x00ba0a3b, 0x01ad161b, 0x006d559b, 0x015d151b,
+ 0x561b8dd1, 0x8e4900bd, 0x551b8db1, 0x161b019d,
+ 0x8e49007d, 0x05bb8db1, 0x161b00ba, 0x5a1b01e9,
+ 0x151b0029, 0x6a330139, 0x561b00ca, 0x8e4900d9,
+ 0x00ca4a33, 0x0169551b, 0x00a9161b, 0x4a338e49,
+ 0xe63300ca, 0xf533012d, 0x7633012d, 0x8e490196,
+ 0x00ca0a3b, 0x0077d51b, 0x0197961b, 0x00ba0a3b,
+ 0x00b989bb, 0x959b8d51, 0xd61b00e7, 0x8e4d0127,
+ 0xd59b8e29, 0x8e2d0037, 0xbef9a5b7, 0x3f75859b,
+ 0x9f319f2d, 0x01770bbb, 0x011fd61b, 0x00ff971b,
+ 0x013fd59b, 0x961b8f51, 0x8e4d00df, 0xdf9b8f31,
+ 0x4fb300af, 0xc73301f7, 0x8fbb01a6, 0x773301fb,
+ 0x8f350137, 0x015f8abb, 0x00ea8abb, 0x01a9961b,
+ 0x0069d71b, 0x0159959b, 0xd61b8f51, 0x8e4d00b9,
+ 0xd59b8f31, 0x961b0199, 0x8e4d0079, 0x873b8f31,
+ 0x161b00ea, 0x5a9b01ea, 0x159b002a, 0xeab3013a,
+ 0x561b00ca, 0x8e4d00da, 0x00cacab3, 0x016a559b,
+ 0x00aa161b, 0xcab38e4d, 0x663300ca, 0x75b30149,
+ 0x76330149, 0x8e4d01b6, 0x00ca8abb, 0x00ea8abb,
+ 0x00ec8cbb, 0x019b161b, 0x007b571b, 0x559b8f51,
+ 0x161b012b, 0x8e4d00eb, 0x5b1b8f31, 0x4b33003b,
+ 0x87370167, 0x071bc671, 0x9fb98f27, 0x016787bb,
+ 0x171b9cbd, 0x579b00ff, 0x561b011f, 0x8f5d013f,
+ 0x00df179b, 0x8f3d8fd1, 0x00af5f1b, 0x01e74f33,
+ 0x013d4733, 0x01e48f3b, 0x01977733, 0x01a74733,
+ 0x00df06bb, 0xd79b9eb9, 0x971b006c, 0x961b01ac,
+ 0x8fd9015c, 0x00bcd71b, 0x8fb98f51, 0x019cd61b,
+ 0x007c971b, 0x8fb98f51, 0x971b9ebd, 0xd79b01ea,
+ 0x961b002a, 0x8fd9013a, 0x00dad71b, 0x8fb98f51,
+ 0x016ad61b, 0x00aa971b, 0x8fb98f51, 0x015a6733,
+ 0x015a7633, 0x01277733, 0x9fb98f51, 0x9fb96722,
+ 0x9fb56702, 0x67e2c71c, 0x01578abb, 0x262377c2,
+ 0x8a3b0157, 0x77e20147, 0x01472823, 0x0127893b,
+ 0x2a2367c2, 0x8dbb0127, 0x778201b7, 0x00dd86bb,
+ 0x8cbbcf14, 0x77a20197, 0x01972e23, 0x013789bb,
+ 0x20236786, 0x8d3b0337, 0x222301a7, 0x742a03a7,
+ 0x696a748a, 0x6a2a69ca, 0x7b666a8a, 0x7c267bc6,
+ 0x6d667c86, 0x614d6dc6, 0xe7b78082, 0x87936a09,
+ 0xc51c6677, 0xbb67b7b7, 0xe8578793, 0xf7b7c55c,
+ 0x87933c6e, 0xc91c3727, 0xa54ff7b7, 0x53a78793,
+ 0x57b7c95c, 0x8793510e, 0xcd1c27f7, 0x9b0577b7,
+ 0x88c78793, 0xe7b7cd5c, 0x87931f83, 0xd11c9ab7,
+ 0x5be0d7b7, 0xd1978793, 0x00052023, 0x00052223,
+ 0x8082d15c, 0x7139ce79, 0xf426f822, 0xe852f04a,
+ 0xec4efc06, 0xe05ae456, 0x84aa411c, 0x073b892e,
+ 0xc11800f6, 0xfa138432, 0x756303f7, 0x415c00c7,
+ 0xc15c2785, 0x020a0f63, 0x04000993, 0x414989bb,
+ 0x0009879b, 0x02f46763, 0x8a931982, 0xd9930284,
+ 0x85ca0209, 0x8533864e, 0x50ef014a, 0x043b4b00,
+ 0x85d60144, 0xc0ef8526, 0x041bf7cf, 0x994efc04,
+ 0x89ca4a01, 0x00890b3b, 0x03f00a93, 0x85cea039,
+ 0xc0ef8526, 0x8993f60f, 0x07bb0409, 0xe8e3413b,
+ 0x579bfefa, 0x06130064, 0x063bfc00, 0x559b02f6,
+ 0x059a0064, 0x9e2195ca, 0x0006079b, 0x7442c38d,
+ 0x02848513, 0x74a270e2, 0x69e27902, 0x6b026aa2,
+ 0x6a429552, 0x92011602, 0x506f6121, 0x70e24400,
+ 0x74a27442, 0x69e27902, 0x6aa26a42, 0x61216b02,
+ 0x80828082, 0xf0227179, 0xf406ec26, 0x41544110,
+ 0x579b84ae, 0x969b01d6, 0x8fd50036, 0x0186d59b,
+ 0x0106d69b, 0x00d104a3, 0x0087d693, 0x0ff6f693,
+ 0x171b07a2, 0x8fd50036, 0x00f11523, 0x0187579b,
+ 0x00f10623, 0x0107579b, 0x06a38321, 0x771300f1,
+ 0x17930ff7, 0x8f5d00b6, 0x00b10423, 0x00e11723,
+ 0x03f67613, 0x03700793, 0xe763842a, 0x079312c7,
+ 0x863b0380, 0x852240c7, 0x00025597, 0x19858593,
+ 0xea5ff0ef, 0x8522002c, 0xf0ef4621, 0x4783e9bf,
+ 0x802300b4, 0x578300f4, 0x80a300a4, 0x441c00f4,
+ 0x0087d79b, 0x00f48123, 0x81a3441c, 0x478300f4,
+ 0x822300f4, 0x578300f4, 0x82a300e4, 0x445c00f4,
+ 0x0087d79b, 0x00f48323, 0x83a3445c, 0x478300f4,
+ 0x84230134, 0x578300f4, 0x84a30124, 0x481c00f4,
+ 0x0087d79b, 0x00f48523, 0x85a3481c, 0x478300f4,
+ 0xb303679c, 0x04e30407, 0x8522fe03, 0x60a26402,
+ 0x83020141, 0xe0221141, 0x7d1ce406, 0xef89842a,
+ 0x4501643c, 0xb303679c, 0x0d630287, 0x85220003,
+ 0x60a26402, 0x83020141, 0x679c67bc, 0xd3ed67bc,
+ 0xdd799782, 0x640260a2, 0x80820141, 0x679c653c,
+ 0x0307b303, 0x00030363, 0x45018302, 0x711d8082,
+ 0x102cf42e, 0xf832ec06, 0xe0bafc36, 0xe8c2e4be,
+ 0xe42eecc6, 0x261240ef, 0x612560e2, 0x11418082,
+ 0xe406e022, 0x842a611c, 0xc7914fbc, 0x70ef6128,
+ 0x30239d6f, 0x643c0404, 0x53fc679c, 0x6828c791,
+ 0x9c4f70ef, 0x04043823, 0xcf897c1c, 0x53386398,
+ 0x67bce709, 0x57fc679c, 0x6c28c791, 0x9a8f70ef,
+ 0x04043c23, 0x09042783, 0x177d777d, 0x60a28ff9,
+ 0x08f42823, 0x01416402, 0x71798082, 0xf406f022,
+ 0xe84aec26, 0xe052e44e, 0xc9795429, 0x09052783,
+ 0x440184aa, 0xc7e98b85, 0x00053983, 0xf0ef892e,
+ 0x842af4ff, 0x864aed55, 0x85264581, 0x0c6000ef,
+ 0xed0d842a, 0x0289b703, 0x00197a13, 0xa783cb29,
+ 0x77b30709, 0xf79300f9, 0xe7b36007, 0xc3a10147,
+ 0x97028526, 0x6490cd0d, 0x00029597, 0x43058593,
+ 0x0002c517, 0xb7850513, 0xf17ff0ef, 0xf0ef8526,
+ 0x842aec7f, 0x6490c535, 0x00029597, 0x41058593,
+ 0x0002c517, 0xbc850513, 0xef7ff0ef, 0x7c9ca891,
+ 0x639cc39d, 0xc3856bbc, 0x97828526, 0xcd01842a,
+ 0x95976490, 0x85930002, 0xc5173e65, 0x05130002,
+ 0xf0efb6e5, 0xa583ecdf, 0x79330709, 0x791300b9,
+ 0x69336009, 0x0d630149, 0x85260009, 0xed3ff0ef,
+ 0xac2357fd, 0xa78308f4, 0x9bf90904, 0x08f4a823,
+ 0x852270a2, 0x64e27402, 0x69a26942, 0x61456a02,
+ 0x71798082, 0xe84af022, 0xf406e44e, 0x7938ec26,
+ 0x892e87aa, 0x89b26304, 0xf8070513, 0xf8048493,
+ 0x07078413, 0x08050793, 0x00879463, 0xa8394501,
+ 0x00090a63, 0x8763611c, 0x60dc0127, 0x84938526,
+ 0xb7cdf807, 0xf0ef85ce, 0xd965ec5f, 0x740270a2,
+ 0x694264e2, 0x614569a2, 0x11018082, 0xec06e822,
+ 0x7508842a, 0x860a468d, 0x0002f597, 0x73858593,
+ 0x488000ef, 0x8522e911, 0x800ff0ef, 0xc11c4782,
+ 0xc51c4792, 0xc15c47a2, 0xf0ef8522, 0x60e2eb2f,
+ 0x61056442, 0x715d8082, 0xf84ae0a2, 0xe486f44e,
+ 0xf052fc26, 0xe85aec56, 0x653ce45e, 0x458189ae,
+ 0x842a679c, 0x63848932, 0x867ff0ef, 0x09042783,
+ 0x0693862a, 0x8b850200, 0x0693c399, 0x601c02b0,
+ 0x451785a6, 0x05130003, 0x63980265, 0x4a1784ce,
+ 0x0a130003, 0x40ef05aa, 0x4a977e02, 0x8a930003,
+ 0x4b17046a, 0x0b130003, 0x4b97036b, 0x8b930003,
+ 0xd063026b, 0x640c0404, 0x0002d517, 0xe6850513,
+ 0x0019191b, 0x7b2240ef, 0x29857824, 0x07040413,
+ 0xf8048493, 0x08048793, 0x02f41c63, 0x640660a6,
+ 0x85a64601, 0xb0ef8522, 0x86aa54f1, 0x85d2864e,
+ 0xa0ef855a, 0x8b9b4852, 0x86520019, 0x852285a6,
+ 0xa95ff0ef, 0x85a689de, 0x8522864a, 0x7601b0ef,
+ 0xbb7d84aa, 0x854e75a2, 0x45f2a0ef, 0x85d2bd69,
+ 0xa0ef854e, 0xb5e14552, 0x651785ee, 0x05130003,
+ 0x83635765, 0x855a000a, 0x43f2a0ef, 0x854e85d2,
+ 0x4372a0ef, 0xb7192a85, 0x856685ee, 0x000a8363,
+ 0xa0ef855a, 0x85d24252, 0xa0ef854e, 0x2a8541d2,
+ 0x9863bf25, 0x86560147, 0xe42e8522, 0x99fff0ef,
+ 0x865e65a2, 0xb0ef8522, 0x85aa6f61, 0x4158b799,
+ 0x00ff0637, 0x0187569b, 0x0187179b, 0x169b8fd5,
+ 0x8ef10087, 0x66c18fd5, 0xf0068693, 0x0087571b,
+ 0x8fd98f75, 0x93811782, 0x8082953e, 0xec4e7139,
+ 0x89aae852, 0x85328a2e, 0x00034597, 0xac058593,
+ 0xf04af426, 0xfc06e456, 0x8ab2f822, 0x84ba8936,
+ 0x00f290ef, 0x66c1e539, 0x85ce8652, 0x80ef842a,
+ 0x571b0132, 0x179b0185, 0x8fd90185, 0x00ff06b7,
+ 0x0085171b, 0x8fd98f75, 0x551b6741, 0x07130085,
+ 0x8d79f007, 0x20238d5d, 0x479100a9, 0x70e2c09c,
+ 0x74428522, 0x790274a2, 0x6a4269e2, 0x61216aa2,
+ 0xe5978082, 0x85930003, 0x855657e5, 0x7b2290ef,
+ 0xe909842a, 0x864a66c1, 0x854e85d2, 0x37d200ef,
+ 0xb7e947d1, 0x0003e597, 0x56458593, 0x90ef8556,
+ 0x842a7902, 0x66c1e911, 0x85d2864a, 0x40ef854e,
+ 0x07936302, 0xb75d0200, 0x00030597, 0x5b058593,
+ 0x90ef8556, 0x842a76c2, 0x66c1e909, 0x85d2864a,
+ 0xf0ef854e, 0x47c112c1, 0x547db751, 0x7131b749,
+ 0xf526f922, 0xed4ef14a, 0xe556e952, 0xfcdee15a,
+ 0xf4e6f8e2, 0xeceef0ea, 0xfd068936, 0x89ae84aa,
+ 0xb0ef8a32, 0x842a64e1, 0x00036b17, 0x168b0b13,
+ 0x02010b93, 0x00033c17, 0xb64c0c13, 0x03010a93,
+ 0x01c10c93, 0x02810d13, 0x01810d93, 0x5e632901,
+ 0x57e10004, 0x00f40663, 0x450557d5, 0x0ef41563,
+ 0x00036917, 0x1b090913, 0x4601a855, 0x852685a2,
+ 0x3351b0ef, 0x855ae42a, 0x740290ef, 0x862a67a2,
+ 0x853e85da, 0x6ea290ef, 0x865ee921, 0x852685a2,
+ 0xe5aff0ef, 0x0e051763, 0x85627582, 0x24b2a0ef,
+ 0x661786d6, 0x06130003, 0x85a22166, 0xb0ef8526,
+ 0xc90d75b1, 0x47915742, 0x02f71663, 0xc39d411c,
+ 0x00036517, 0x20850513, 0x21f2a0ef, 0x00036517,
+ 0x20c50513, 0xdf3fc0ef, 0x852685a2, 0x5b41b0ef,
+ 0xb7b5842a, 0x866a86e6, 0x852685a2, 0xe26ff0ef,
+ 0x7602e541, 0x86d6876e, 0x855285ca, 0xe21ff0ef,
+ 0x47e2e53d, 0x1f634672, 0x75a204f6, 0x90ef8556,
+ 0xdd4d0172, 0x00036917, 0x15c90913, 0x460185a2,
+ 0xb0ef8526, 0x842a2831, 0x85ce4601, 0xb0ef8526,
+ 0x86aa2771, 0x85ca8622, 0x00036517, 0x1a850513,
+ 0x1a72a0ef, 0x70ea4501, 0x74aa744a, 0x69ea790a,
+ 0x6aaa6a4a, 0x7be66b0a, 0x7ca67c46, 0x6de67d06,
+ 0x80826129, 0x00036917, 0x11c90913, 0x6917bf45,
+ 0x09130003, 0xb75d12a9, 0x00036917, 0x0d890913,
+ 0x6917bf71, 0x09130003, 0xbf490ae9, 0x00347179,
+ 0xf022860a, 0xf406ec26, 0x842ae84a, 0xf0ef84ae,
+ 0xcd1dcbef, 0x45814601, 0xb0ef8522, 0x892a1fb1,
+ 0x85a64601, 0xb0ef8522, 0x86aa1ef1, 0x6597864a,
+ 0x85930003, 0x6517ffa5, 0x05130003, 0xa0ef0125,
+ 0x45011192, 0x740270a2, 0x694264e2, 0x80826145,
+ 0x660266a2, 0x852285a6, 0xe17ff0ef, 0x715db7e5,
+ 0x00037597, 0xe5858593, 0xe486fc26, 0xf84ae0a2,
+ 0xf052f44e, 0xe85aec56, 0xc0ef84aa, 0x5a6301c1,
+ 0xc0ef0205, 0x862a3421, 0x00037597, 0xe3058593,
+ 0x00036517, 0x11050513, 0x0bf2a0ef, 0x60a64501,
+ 0x74e26406, 0x79a27942, 0x6ae27a02, 0x61616b42,
+ 0x842a8082, 0x651785a6, 0x05130003, 0xa0efa325
+};
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_io.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_io.c
new file mode 100644
index 00000000..08a1fb77
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_io.c
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_io.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MSS IO related code
+ *
+ */
+#include
+#include
+
+#include "mpfs_hal/mss_hal.h"
+
+/*******************************************************************************
+ * external functions
+ */
+
+
+/*
+ * IOMUX values from Libero
+ */
+IOMUX_CONFIG iomux_config_values = {
+ LIBERO_SETTING_IOMUX0_CR, /* Selects whether the peripheral is connected to
+ the Fabric or IOMUX structure. */
+ LIBERO_SETTING_IOMUX1_CR, /* BNK4 SDV PAD 0 to 7, each IO has 4 bits */
+ LIBERO_SETTING_IOMUX2_CR, /* BNK4 SDV PAD 8 to 13 */
+ LIBERO_SETTING_IOMUX3_CR, /* BNK2 SDV PAD 14 to 21 */
+ LIBERO_SETTING_IOMUX4_CR, /* BNK2 SDV PAD 22 to 29 */
+ LIBERO_SETTING_IOMUX5_CR, /* BNK2 PAD 30 to 37 */
+ LIBERO_SETTING_IOMUX6_CR /* Sets whether the MMC/SD Voltage select lines
+ are inverted on entry to the IOMUX structure */
+};
+
+/*
+ * Bank 4 and 2 settings, the 38 MSSIO.
+ */
+MSSIO_BANK4_CONFIG mssio_bank4_io_config = {
+ /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
+ x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_0_1_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_2_3_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_4_5_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_6_7_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_8_9_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_10_11_CR,
+ LIBERO_SETTING_MSSIO_BANK4_IO_CFG_12_13_CR,
+};
+
+/*
+ * Bank 4 and 2 settings, the 38 MSSIO.
+ */
+MSSIO_BANK2_CONFIG mssio_bank2_io_config = {
+ /* LIBERO_SETTING_mssio_bank4_io_cfg_0_cr
+ x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_0_1_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_2_3_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_4_5_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_6_7_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_8_9_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_10_11_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_12_13_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_14_15_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_16_17_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_18_19_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_20_21_CR,
+ LIBERO_SETTING_MSSIO_BANK2_IO_CFG_22_23_CR
+};
+
+/*******************************************************************************
+ * Local functions
+ */
+static uint8_t io_mux_and_bank_config(void);
+
+/***************************************************************************//**
+ * MSSIO OFF Mode
+ *
+ * The following settings are applied if MMSIO unused/off
+ *
+ * The IO Buffers are disabled.
+ * Output drivers are disabled (set the drv<3:0> bits to 0000, output
+ * enable "mss_oe" bit to 0)
+ * Disable the WPU bit set to 0 and enable the WPD bit set to 1.
+ * Receivers are disabled. (Ibufmd<2:0> set to 7)
+ *
+ * MSS can enable OFF mode through configurator bit for selective MSSIO
+ * from Bank2/Bank4 by making drv<3:0>/mss_oe bit to "0" for that
+ * particular MSSIO making Output driver disabled and ibufmd <2:0> bit to
+ * "7" for that particular MSSIO making input receiver disabled.
+ *
+ */
+
+/***************************************************************************//**
+ * mssio_setup()
+ *
+ * Setup the IOMUX and IO bank 2 and 4.
+ *
+ * To setup bank 2 and 4, ncode and pcode scb registers in system
+ * register block are set as per Libero supplied values.
+ * These need to be transferred to I/0
+ *
+ * @return 0 => pass
+ */
+uint8_t mssio_setup(void)
+{
+ uint8_t ret_status = 0U;
+ ret_status = io_mux_and_bank_config();
+ set_bank2_and_bank4_volts();
+ return (ret_status);
+}
+
+/***************************************************************************//**
+ * io_mux_and_bank_config(void)
+ * sets up the IOMUX and bank 2 and 4 pcodes and n codes
+ * @return 0 => OK
+ */
+static uint8_t io_mux_and_bank_config(void)
+{
+ /* Configure IO mux's
+ *
+ * IOMUX1_CR - IOMUX5_CR, five 32-bit registers, with four bits four bits
+ * for each I/O determine what is connected to each pad
+ *
+ * All internal peripherals are also connected to the fabric (apart from
+ * MMC/SDIO/GPIO/USB). The IOMUX0 register configures whether the IO
+ * function is connected to the fabric or the IOMUX.
+ *
+ * IOMUX6_CR Sets whether the MMC/SD Voltage select lines are inverted on
+ * entry to the IOMUX structure
+ *
+ * */
+ config_32_copy((void *)(&(SYSREG->IOMUX0_CR)),
+ &(iomux_config_values),
+ sizeof(IOMUX_CONFIG));
+
+ /*
+ * Configure MSS IO banks
+ * sets pcode and ncode using (mssio_bank2_cfg_cr/mssio_bank4_cfg_cr)
+ *
+ * The MSS IO pad configuration is provided by nineteen system registers
+ * each configuring two IO's using 15-bits per IO
+ * - (mssio_bank*_io_cfg_*_*_cr).
+
+ | mssio_bank*_io_cfg_*_*_cr | offset | info |
+ | field | offset | info |
+ |:-------------------------:|:-------------:|:-----|
+ | io_cfg_ibufmd_0 |0 | |
+ | io_cfg_ibufmd_1 |1 | |
+ | io_cfg_ibufmd_2 |2 | |
+ | io_cfg_drv_0 |3 | |
+ | Io_cfg_drv_1 |4 | |
+ | Io_cfg_drv_2 |5 | |
+ | io_cfg_drv_3 |6 | |
+ | io_cfg_clamp |7 | |
+ | io_cfg_enhyst |8 | |
+ | io_cfg_lockdn_en |9 | |
+ | io_cfg_wpd |10 | |
+ | io_cfg_wpu |11 | |
+ | io_cfg_atp_en |12 | |
+ | io_cfg_lp_persist_en |13 | |
+ | io_cfg_lp_bypass_en |14 | |
+ * */
+
+ config_32_copy((void *)(&(SYSREG->MSSIO_BANK4_IO_CFG_0_1_CR)),
+ &(mssio_bank4_io_config),
+ sizeof(MSSIO_BANK4_CONFIG));
+
+ config_32_copy((void *)(&(SYSREG->MSSIO_BANK2_IO_CFG_0_1_CR)),
+ &(mssio_bank2_io_config),
+ sizeof(MSSIO_BANK2_CONFIG));
+
+ set_bank2_and_bank4_volts();
+
+ return(0L);
+}
+
+/**
+ * set_bank2_and_bank4_volts(void)
+ * sets bank voltage parameters
+ * bank_pcode
+ * bank_ncode
+ * vs
+ * @return
+ */
+void set_bank2_and_bank4_volts(void)
+{
+
+ SCB_REGS->MSSIO_BANK2_CFG_CR.MSSIO_BANK2_CFG_CR =\
+ (uint32_t)LIBERO_SETTING_MSSIO_BANK2_CFG_CR;
+ SCB_REGS->MSSIO_BANK4_CFG_CR.MSSIO_BANK4_CFG_CR =\
+ (uint32_t)LIBERO_SETTING_MSSIO_BANK4_CFG_CR;
+
+ return;
+}
+
+#ifdef EXAMPLE_MSSIO_APP_CODE
+#include "drivers/mss_gpio/mss_gpio.h"
+/**
+ *
+ * @return 0 => OK
+ */
+int32_t gpio_toggle_test(void)
+{
+ SYSREG->TEMP0 = 0x11111111;
+
+ for (int l = 0 ; l < 14 ; l++)
+ {
+ for (int i = 0 ; i < 14 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO0_LO, i, 0x0);
+ }
+ for (int i = 0 ; i < 24 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO1_LO, i, 0x0);
+ }
+ SYSREG->TEMP0 = 0xFFFFFFFFUL;
+ for (int i = 0 ; i < 14 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO0_LO, i, 0x1);
+ }
+ for (int i = 0 ; i < 24 ; i++)
+ {
+ SYSREG->TEMP0 = 0x12345678;
+ MSS_GPIO_set_output(GPIO1_LO, i, 0x1);
+ }
+ }
+ return(0UL);
+}
+
+
+/**
+ *
+ * @return 0 => OK
+ */
+int32_t gpio_set_config(void)
+{
+ SYSREG->SOFT_RESET_CR &= ~((1U<<20U)|(1U<<21U)|(1U<<22U));
+ SYSREG->SUBBLK_CLOCK_CR |= ((1U<<20U)|(1U<<21U)|(1U<<22U));
+ MSS_GPIO_init(GPIO0_LO);
+ MSS_GPIO_init(GPIO1_LO);
+ for (int i = 0 ; i < 14 ; i++)
+ {
+ MSS_GPIO_config(GPIO0_LO, i, MSS_GPIO_OUTPUT_MODE);
+ }
+ for (int i = 0 ; i < 24 ; i++)
+ {
+ MSS_GPIO_config(GPIO1_LO, i, MSS_GPIO_OUTPUT_MODE);
+ }
+ return(0UL);
+}
+#endif
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_io_config.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_io_config.h
new file mode 100644
index 00000000..0feebdfc
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_io_config.h
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_io_config.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MSS IO related code
+ *
+ */
+
+#ifndef xUSER_CONFIG_MSS_DDRC_MSS_IO_CONFIG_H_
+#define xUSER_CONFIG_MSS_DDRC_MSS_IO_CONFIG_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * There are 38 general purpose IO pads, referred to as MSSIO, to support
+ * peripheral devices. System registers will select which signals are connected
+ * to the IO pads. These are in addition to the SGMII IO for the Ethernet MACs,
+ * DDR I/O and two IOs to allow interfacing to an external 32kHz crystal. All
+ * of these MSSIOs are bonded out to pins in all packages. The MSSIOs may be
+ * configured as the IOs of any of the MSS peripherals listed in the table
+ * below.
+ */
+
+/*
+ - MUX -> PAD options set by Libero, register iomux1_cr to iomux5_cr
+ | option | value | Info |
+ |:-------------:|:-------------:|:-----:|
+ | SD_SDIO | 0x0 | |
+ | EMMC | 0x1 | |
+ | QSPI | 0x2 | |
+ | SPI | 0x3 | |
+ | USB | 0x4 | |
+ | MMUART | 0x5 | |
+ | I2C | 0x6 | |
+ | CAN | 0x7 | |
+ | MDIO | 0x8 | |
+ | Miscellaneous | 0x9 | |
+ | Reservedx | 0xA | |
+ | GPIO_PAD | 0xB | |
+ | Fabric_test | 0xC | |
+ | Logic_0 | 0xD | |
+ | Logic_1 | 0xE | |
+ | Tristate | 0xF |Default|
+ */
+
+/**
+ * \brief IOMUX configuration
+ */
+typedef struct IOMUX_CONFIG_ {
+ __IO uint32_t iomux0_cr; /* peripheral is connected to the Fabric or
+ IOMUX structure */
+ __IO uint32_t iomux1_cr; /* BNK4 SDV PAD 0 to 7 */
+ __IO uint32_t iomux2_cr; /* BNK4 SDV PAD 8 to 13 */
+ __IO uint32_t iomux3_cr; /* BNK2 SDV PAD 14 to 21 */
+ __IO uint32_t iomux4_cr; /* BNK2 SDV PAD 22 to 29 */
+ __IO uint32_t iomux5_cr; /* BNK2 PAD 30 to 37 */
+ __IO uint32_t iomux6_cr; /* MMC/SD Voltage select lines are inverted on
+ entry to the IOMUX structure */
+} IOMUX_CONFIG;
+
+
+
+/*
+ pcode, ncode and drive strength for each bank is set using direct writes to
+ the SCB registers
+
+ The MSS IO pad configuration is provided by nineteen system registers
+ each configuring two IO's using 15-bits per IO
+ Theses registers are located in the MSS sysreg.
+
+ - (mssio_bank*_io_cfg_*_*_cr).
+
+ | mssio_bank*_io_cfg_*_*_cr | offset | info |
+ | field | | info |
+ |:-------------------------:|:-------------:|:-----|
+ | io_cfg_ibufmd_0 |0 | |
+ | io_cfg_ibufmd_1 |1 | |
+ | io_cfg_ibufmd_2 |2 | |
+ | io_cfg_drv_0 |3 | |
+ | Io_cfg_drv_1 |4 | |
+ | Io_cfg_drv_2 |5 | |
+ | io_cfg_drv_3 |6 | |
+ | io_cfg_clamp |7 | |
+ | io_cfg_enhyst |8 | |
+ | io_cfg_lockdn_en |9 | |
+ | io_cfg_wpd |10 | |
+ | io_cfg_wpu |11 | |
+ | io_cfg_atp_en |12 | |
+ | io_cfg_lp_persist_en |13 | |
+ | io_cfg_lp_bypass_en |14 | |
+
+*/
+
+/**
+ * \brief Bank 2 and 4 voltage settings
+ *
+ */
+typedef struct HSS_MSSIO_Bank_Config_ {
+ __IO uint32_t mssio_bank4_pcode_ncode_vs; /* bank 4- set pcode, ncode and
+ drive strength */
+ __IO uint32_t mssio_bank2_pcode_ncode_vs; /* bank 2- set pcode, ncode and
+ drive strength */
+}MSSIO_BANK_CONFIG;
+
+/**
+ * \brief MSS IO Bank 4 configuration
+ */
+typedef struct MSSIO_Bank4_IO_Config_ {
+ __IO uint32_t mssio_bank4_io_cfg_0_cr; /* x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ __IO uint32_t mssio_bank4_io_cfg_1_cr;
+ __IO uint32_t mssio_bank4_io_cfg_2_cr;
+ __IO uint32_t mssio_bank4_io_cfg_3_cr;
+ __IO uint32_t mssio_bank4_io_cfg_4_cr;
+ __IO uint32_t mssio_bank4_io_cfg_5_cr;
+ __IO uint32_t mssio_bank4_io_cfg_6_cr;
+
+}MSSIO_BANK4_CONFIG;
+
+/**
+ * \brief MSS IO Bank 2 configuration
+ */
+typedef struct MSSIO_Bank2_IO_Config_ {
+ __IO uint32_t mssio_bank2_io_cfg_0_cr; /* x_vddi Ratio Rx<0-2> == 001
+ drv<3-6> == 1111
+ 7:clamp == 0
+ enhyst == 0
+ lockdn_en == 1
+ 10:wpd == 0
+ atp_en`== 0
+ lpmd_ibuf == 0
+ lpmd_obuf == 0
+ persist == 0
+ */
+ __IO uint32_t mssio_bank2_io_cfg_1_cr;
+ __IO uint32_t mssio_bank2_io_cfg_2_cr;
+ __IO uint32_t mssio_bank2_io_cfg_3_cr;
+ __IO uint32_t mssio_bank2_io_cfg_4_cr;
+ __IO uint32_t mssio_bank2_io_cfg_5_cr;
+ __IO uint32_t mssio_bank2_io_cfg_6_cr;
+ __IO uint32_t mssio_bank2_io_cfg_7_cr;
+ __IO uint32_t mssio_bank2_io_cfg_8_cr;
+ __IO uint32_t mssio_bank2_io_cfg_9_cr;
+ __IO uint32_t mssio_bank2_io_cfg_10_cr;
+ __IO uint32_t mssio_bank2_io_cfg_11_cr;
+}MSSIO_BANK2_CONFIG;
+
+
+/***************************************************************************//**
+ The int32_t mssio_setup(void)()
+
+ Setup the IOMUX and IO bank 2 and 4.
+ The values used in this function are set by Libero.
+ It configures the I/O mux, which detemines what peripherals are connected to
+ what pins, and the electrical properties of each bank and each I/O.
+
+ @return
+ This function returns status, 0 => OK
+
+ Example:
+ @code
+
+ error |= mssio_setup();
+
+ @endcode
+
+ */
+uint8_t
+mssio_setup
+(
+ void
+);
+
+
+/***************************************************************************//**
+ The gpio_toggle_test(void)()
+
+ Toggle a GPIO PIN on start-up
+
+ @return
+ This function returns status, 0 => OK
+
+ Example:
+ @code
+
+ error |= mssio_setup();
+
+ @endcode
+
+ */
+int32_t
+gpio_toggle_test
+(
+ void
+);
+
+/***************************************************************************//**
+ set_bank2_and_bank4_volts()
+ Sets bank 2 and 4 voltages, with Values coming from Libero
+
+ Example:
+
+ @code
+
+ set_bank2_and_bank4_volts();
+
+ @endcode
+
+ *
+ */
+void
+set_bank2_and_bank4_volts
+(
+ void
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USER_CONFIG_MSS_DDRC_MSS_IO_CONFIG_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c
new file mode 100644
index 00000000..698cceff
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_nwc_init.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief north west corner, calls required startup code
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "mss_nwc_init.h"
+#include "simulation.h"
+
+#ifdef DEBUG_DDR_INIT
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+extern mss_uart_instance_t *g_debug_uart ;
+uint32_t setup_ddr_debug_port(mss_uart_instance_t * uart);
+#endif
+
+/*******************************************************************************
+ * Local Defines
+ */
+CFG_DDR_SGMII_PHY_TypeDef * const CFG_DDR_SGMII_PHY = ((CFG_DDR_SGMII_PHY_TypeDef *) CFG_DDR_SGMII_PHY_BASE);
+DDR_CSR_APB_TypeDef * const DDRCFG = ((DDR_CSR_APB_TypeDef *) DDRCFG_BASE);
+IOSCBCFG_TypeDef * const SCBCFG_REGS = (IOSCBCFG_TypeDef *)IOSCBCFG_BASE ;
+g5_mss_top_scb_regs_TypeDef * const SCB_REGS = (g5_mss_top_scb_regs_TypeDef *) SYSREGSCB_BASE;
+
+/*******************************************************************************
+ * Local functions
+ */
+void delay(uint32_t n);
+
+/*******************************************************************************
+ * extern defined functions
+ */
+#ifdef DEBUG_DDR_INIT
+uint32_t setup_ddr_debug_port(mss_uart_instance_t * uart);
+#endif
+
+/******************************************************************************
+ * Public Functions - API
+ ******************************************************************************/
+
+/**
+ * MSS_DDR_init_simulation(void)
+ * Flow when running through full chip simulation
+ *
+ * @return
+ */
+uint8_t mss_nwc_init(void)
+{
+ uint8_t error = 0U;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+#ifdef SIMULATION_TEST_FEEDBACK
+ /*
+ * set the test version- this is read in Simulation environment
+ * x.y.z
+ * byte[0] = z
+ * byte[1] = y
+ * byte[2] = x
+ */
+ SIM_FEEDBACK0(0x33333333);
+ SYSREG->TEMP0 = (0U << 16U) | (3U << 8U) | 3U;
+ SYSREG->TEMP0 = 0x44444444U;
+ SIM_FEEDBACK0(1);
+ SIM_FEEDBACK0(0x55555555);
+ SIM_FEEDBACK0(1);
+#endif
+ /*
+ * Assumptions:
+ * 1. We enter here shortly after start-up of E51 code by the system
+ * controller.
+ * 2. We are running on the E51 and all other cores are in wfi.
+ * 3. The MSS PLL will be set to use default internal clock of 80MH
+ * 4. MSS peripherals including the I/O are in the default power on state
+ *
+ *
+ * The following implements setting of
+ * external clock reference
+ * MSS PLL, SHMII PLL, SGMII PLL, MSS Mux's
+ * IO settings and IO MUX
+ * HSIO IO calibration options
+ * SGMII configuration
+ * DDR configuration
+ * Including SEG regs
+ * MPU setup
+ * PMP setup
+ * ABP Peripheral address setup (High/Low)
+ *
+ */
+
+ /*
+ * Set based on reference clock
+ */
+ set_RTC_divisor();
+
+ /*
+ * SCB access settings
+ * Bits 15:8 Sets how long SCB request is held active after SCB bus granted.
+ * Allows SCB bus master-ship to maintained across multiple SCB access
+ * cycles
+ * Bits 7:0 Set the timeout for an SCB access in CPU cycles.
+ */
+ SCBCFG_REGS->TIMER.TIMER = MSS_SCB_ACCESS_CONFIG;
+
+ /*
+ * Release APB reset & turn on dfi clock
+ *
+ * reserved bit 31:2
+ * reset bit 1 Asserts the APB reset to the MSS corner, is asserted at
+ * MSS reset.
+ * clock_on bit 0 Turns on the APB clock to the MSS Corner, is off at
+ * reset. Once corner blocks is configured the firmware
+ * may turn off the clock, but periodically should turn
+ * back on to allow refresh of TMR registers inside
+ * the corner block.
+ *
+ */
+ SYSREG->DFIAPB_CR = 0x00000001U;
+
+ /*
+ * Dynamic APB enables for slaves
+ * APB dynamic enables determine if we can write to the associated APB
+ * registers.
+ * ACB dynamic enables determine if we can write to the associated SCB
+ * registers.
+ *
+ * bit 31:22 Reserved
+ * bit 21 DYNEN_APB_DECODER_PRESETS
+ * bit 20 DYNEN_APB_BANKCNTL
+ * bit 19 DYNEN_APB_IO_CALIB
+ * bit 18 DYNEN_APB_CFM
+ * bit 17 DYNEN_APB_PLL1
+ * bit 16 DYNEN_APB_PLL0
+ * bit 15:13 Reserved
+ * bit 12 DYNEN_SCB_BANKCNTL
+ * bit 11 DYNEN_SCB_IO_CALIB
+ * bit 10 DYNEN_SCB_CFM
+ * bit 9 DYNEN_SCB_PLL1
+ * bit 8 DYNEN_SCB_PLL0
+ * bit 7:5 Reserved
+ * bit 4 Persist_DATA
+ * bit 3 CLKOUT
+ * bit 2 PERSIST_ADD_CMD
+ * bit 1 DATA_Lockdn
+ * bit 0 ADD_CMD_Lockdn
+ */
+ CFG_DDR_SGMII_PHY->DDRPHY_STARTUP.DDRPHY_STARTUP =\
+ (0x3FU << 16U) | (0x1FU << 8U);
+ /* Enable all dynamic enables
+ When in dynamic enable more, this allows:
+ 1. writing directly using SCB
+ 2. setting using RPC on a soft reset
+ */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x01U<< 10U) | (0x7FU<<0U);
+
+ /*
+ * Configure IOMUX and I/O settings for bank 2 and 4
+ */
+ {
+#ifdef MSSIO_SUPPORT
+ error |= mssio_setup();
+#endif
+ }
+
+ /*************************************************************************/
+
+ /*
+ *
+ * In this step we enter Dynamic Enable mode.
+ * This is done by using the following sequence:
+ *
+ * Please note all dynamic enables must be enabled.
+ * If dynamic enables are not enabled, when flash valid is asserted, value
+ * of SCB registers will be immediately written to with default values
+ * rather than the RPC values.
+ *
+ * Dynamic Enable mode:
+ * Step 1:
+ * Make sure SCB dynamic enable bit is high
+ * step 2: Assert MSS core_up
+ * followed by delay
+ * step 3: Change dce[0,1,2] to 0x00
+ * followed by delay
+ * step 4: Assert flash valid
+ * followed by delay
+ * step 5: make sure all RPC registers are set to desired values
+ * (using mode and direct RPC writes to RPC)
+ * step 6: soft reset IP so SCB registers are written with RPC values.
+ * note: We will carry out step 5/6 later, once we have modified any
+ * RPC registers directly that may need tweaking or are not
+ * included in the mode write state machine, carried out in a
+ * previous step.
+ *
+ * Note 1: The SCB bus can be used to update/write new values to
+ * the SCB registers through the SCB bus interface while in Dynamic
+ * enable mode
+ * Note 2: The MSS top block assertion of core_up and flash_valid
+ * have no effect in themselves if MSS custom SCB register values
+ * if the custom SCB slaves are not being reset at the same time.
+ * If the custom SCB slaves are reset whilst core_up and
+ * flash_valid are high, then the SCB registers get asynchronously
+ * loaded with the values of their corresponding RPC bits. These
+ * values remain even after negation of reset but may be
+ * subsequently overwritten by SCB writes.
+ *
+ * reg MSS_LOW_POWER_CR
+ *
+ * bit 12 flash_valid Sets the value driven out on
+ * mss_flash_valid_out
+ * bit 11 core_up Sets the value driven out on
+ * mss_core_up_out
+ * bit 10:8 dce S Sets the value driven out on mss_dce_out
+ * unless G5C asserts its overrides
+ * bit 7 lp_stop_clocks_in Read back of lp_stop_clocks input
+ * bit 6 lp_stop_clocks_out Direct control of MSS Corner LP state
+ * control
+ * bit 5 p_pll_locked Direct control of MSS Corner
+ * LP state control
+ * bit 4 lp_state_bypass Direct control of MSS Corner LP
+ * state control
+ * bit 3 lp_state_persist
+ * bit 2 lp_state_op
+ * bit 1 lp_state_ip
+ * bit 0 lp_state_mss
+ *
+ * In order to re-flash/update the APB RPC register values into the
+ * registers of a specific SCB slave,the following sequence must be
+ * followed:
+ * 1) Embedded software running on E51 must force the mss_core_up and
+ * mss_flash valid must be high
+ * 2) Then do a soft reset of the specific SCB slave that will be
+ * re-flashed/updated.
+ *
+ * The APB RPC registers are used in the following ways to configure
+ * the MSS periphery
+ * 1) Load values to SCB registers.
+ * core_up" and "flash_valid" determines if the SCB registers get
+ * either:
+ * a. Reset to their hardware default
+ * (when core_up/flash_valis low)
+ * b. Loaded with the APB RPC register.
+ * (when core_up/flash_valid high)
+ * 2) IO configuration settings
+ * These are fed directly to the static configuration of IOA cells
+ * within the IOG lanes of the DDR and SGMII PHYs, as long as
+ * "core_up" and "flash_valid" are high.
+ * a. To avoid unwanted/intermediate states on IOs, the "core_up"
+ * and "flash_valid" should be initially 0 on MSS reset. This will
+ * select the safe hardware defaults. The RPC registers are written
+ * in the background and then simultaneously "flashed" as the new
+ * IO configuration by assertion of "core_up" and "flash_valid"
+ * being asserted.
+ * 3) Training IP settings
+ * These allow the direct control of the training IP via the APB
+ * registers.
+ *
+ * Notes:
+ * 1) When the MSS is reset, the SCB slaves won't take on the RPC
+ * values. They will be reset to their hardware default values.
+ *
+ * 2) Although RPC registers are writable in APB space,
+ * they only take effect on the SCB registers whenever there is a
+ * "virtual re-flash" operation, which involves performing
+ * a soft reset of an SCB slave (i.e. writing to the NV_MAP register
+ * bit in the SOFT_RESET register in the SCB slave).
+ * This mechanism would only be used if a full new configuration is to
+ * be applied to the full SCB slave and wouldn't be used, for example
+ * to change just a clock mux configuration.
+ *
+ * 3) To make configuration changes to individual registers, without
+ * "re-flashing" all registers in an MSS custom SCB slave, it is
+ * necessary to write directly to the SCB registers (via SCB space) in
+ * that slave, rather than writing RPC registers via APB space
+ *
+ */
+
+ /*
+ lp_state_mss :1;
+ lp_state_ip_mss :1;
+ lp_state_op_mss :1;
+ lp_state_persist_mss :1;
+ lp_state_bypass_mss :1;
+ lp_pll_locked_mss :1;
+ lp_stop_clocks_out_mss :1;
+ lp_stop_clocks_in_mss :1;
+ mss_dce :3;
+ mss_core_up :1;
+ mss_flash_valid :1;
+ mss_io_en :1;
+ */
+ /* DCE:111, CORE_UP:1, FLASH_VALID:0, mss_io_en:0 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x07U<<8U)|(0x01U<<11U)|(0x00U<<12U)|(0x00U<<13U);
+ delay((uint32_t) 10U);
+ /* DCE:000, CORE_UP:1, FLASH_VALID:0, mss_io_en:0 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x00U<<8U)|(0x01U<<11U)|(0x00U<<12U)|(0x00U<<13U);
+ delay((uint32_t) 10U);
+ /* DCE:000, CORE_UP:1, FLASH_VALID:1, mss_io_en:0 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x00U<<8U)|(0x01U<<11U)|(0x01U<<12U)|(0x00U<<13U);
+ delay((uint32_t) 10U);
+ /* DCE:000, CORE_UP:1, FLASH_VALID:1, mss_io_en:1 */
+ SCB_REGS->MSSIO_CONTROL_CR.MSSIO_CONTROL_CR =\
+ (0x00U<<8U)|(0x01U<<11U)|(0x01U<<12U)|(0x01U<<13U);
+
+ /*
+ * Setup SGMII
+ * The SGMII set-upset configures the external clock reference so this must
+ * be called before configuring the MSS PLL
+ */
+ SIM_FEEDBACK0(2);
+ sgmii_setup();
+
+ /*
+ * Setup the MSS PLL
+ */
+ SIM_FEEDBACK0(3);
+ mss_pll_config();
+
+ {
+#ifdef DDR_SUPPORT
+#ifdef DEBUG_DDR_INIT
+ {
+ (void)setup_ddr_debug_port(g_debug_uart);
+ }
+#endif
+
+ uint32_t ddr_status;
+ ddr_status = ddr_state_machine(DDR_SS__INIT);
+
+ while((ddr_status & DDR_SETUP_DONE) != DDR_SETUP_DONE)
+ {
+ ddr_status = ddr_state_machine(DDR_SS_MONITOR);
+ }
+ if ((ddr_status & DDR_SETUP_FAIL) == DDR_SETUP_FAIL)
+ {
+ error |= (0x1U << 2U);
+ }
+ //todo: remove, just for sim test ddr_recalib_io_test();
+#endif
+ }
+
+#endif /* end of !define SIFIVE_HIFIVE_UNLEASHED */
+ SIM_FEEDBACK0(0x12345678U);
+ SIM_FEEDBACK0(error);
+ SIM_FEEDBACK0(0x87654321U);
+ return error;
+}
+
+
+/*-------------------------------------------------------------------------*//**
+ * delay()
+ * Not absolute. Dependency on current clk rate
+ * @param n Number of iterations to wait.
+ */
+void delay(uint32_t n)
+{
+ volatile uint32_t count = n;
+ while(count!=0U)
+ {
+ count--;
+ }
+}
+
+/*-------------------------------------------------------------------------*//**
+ * mtime_delay()
+ * waits x microseconds
+ * Assumption 1 is we have ensured clock is 1MHz
+ * Assumption 2 is we have not setup tick timer when using this function. It is
+ * only used by the startup code
+ * @param microseconds microseconds to delay
+ */
+
+void mtime_delay(uint32_t microseconds)
+{
+ CLINT->MTIME = 0ULL;
+ volatile uint32_t count = 0ULL;
+
+ while(CLINT->MTIME < microseconds)
+ {
+ count++;
+ }
+ return;
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_nwc_init.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_nwc_init.h
new file mode 100644
index 00000000..b759b82c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_nwc_init.h
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_nwc_init.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief defines for mss_nwc_init.c
+ *
+ */
+
+/*=========================================================================*//**
+ @page MPFS MSS NWC configuration
+ ==============================================================================
+ @section intro_sec Introduction
+ ==============================================================================
+ The MPFS microcontroller subsystem (MSS) includes a number of hard core
+ components physically located in the north west corner of the MSS on the die.
+
+ ==============================================================================
+ @section Items located in the north west corner
+ ==============================================================================
+ MSS PLL
+ SGMII
+ DDR phy
+ MSSIO
+
+ ==============================================================================
+ @section Flow diagram
+ ==============================================================================
+ todo: remove, added line here as test *****
+ Simplified flow diagram
+ +-----------------+
+ | start |
+ | NWC setup |
+ +-------+---------+
+ v
+ +-----------------+
+ | set SCB access|
+ | Parameters |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Release APB NWC |
+ | Turn on APB clk |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Set Dynamic |
+ | enable bits |
+ +-------++--------+
+ |
+ +-------v---------+
+ | Setup signals |
+ | DCE,CORE_UP, |
+ | Flash_Valid, |
+ | MSS_IO_EN |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Setup SGMII |
+ | |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Setup DDR |
+ | |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Setup MSSIO |
+ | |
+ +-------+---------+
+ |
+ +-------v---------+
+ | Finished |
+ +-----------------+
+
+ *//*=========================================================================*/
+#ifndef __MSS_NWC_INIT_H_
+#define __MSS_NWC_INIT_H_ 1
+
+
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************************************************************//**
+ MSS_SCB_ACCESS_CONFIG_ON_RESET
+
+ SCB access settings on reset.
+ Bits 15:8 Sets how long SCB request is held active after SCB bus granted.
+ Allows SCB bus master-ship to maintained across multiple SCB access
+ cycles
+ Bits 7:0 Set the timeout for an SCB access in CPU cycles.
+
+ Note: These settings are used even after we change the MSS clock from SCB
+ 80MHz default setting. todo: This needs to be confirmed as OK, there will be
+ no potential timing issues:
+ Min 143 Hclk cycles for simulation set-up, making 160
+ todo: review setting
+ */
+
+#define MSS_SCB_ACCESS_CONFIG ((160UL<<8U)|(0x80U))
+
+
+/***************************************************************************//**
+ mss_nwc_init()
+ Called on start-up, initializes clocks, sgmii, ddr, mssio
+ */
+uint8_t
+mss_nwc_init
+(
+ void
+);
+
+
+/***************************************************************************//**
+ mtime_delay(x) delay function, passes microseconds
+ waits x microseconds
+ Assumption 1 is we have ensured clock is 1MHz
+ Assumption 2 is we have not setup tick timer when using this function. It is
+ only used by the startup code.
+
+ Example:
+ @code
+
+ mtime_delay(100UL);
+
+ @endcode
+
+ */
+void
+mtime_delay
+(
+ uint32_t microseconds
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_DDRC_H_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_pll.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_pll.c
new file mode 100644
index 00000000..df1ecc6f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_pll.c
@@ -0,0 +1,724 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_pll.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPSS PLL setup
+ *
+ */
+
+#include "mpfs_hal/mss_hal.h"
+#include "mss_pll.h"
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+/**
+ * We do it this way to avoid multiple LDRA warnings
+ * alternate it to
+ * #define MSS_SCB_MSS_PLL (IOSCB_CFM_MSS *) )x7xxxxxxx The actual
+ * address * but above results in error every time we use the function
+ */
+
+PLL_TypeDef * const MSS_SCB_MSS_PLL = ((PLL_TypeDef *) MSS_SCB_MSS_PLL_BASE);
+PLL_TypeDef * const MSS_SCB_DDR_PLL = ((PLL_TypeDef *) MSS_SCB_DDR_PLL_BASE);
+PLL_TypeDef * const MSS_SCB_SGMII_PLL = ((PLL_TypeDef *) MSS_SCB_SGMII_PLL_BASE);
+IOSCB_CFM_MSS * const MSS_SCB_CFM_MSS_MUX =\
+ ((IOSCB_CFM_MSS *) MSS_SCB_MSS_MUX_BASE);
+IOSCB_CFM_SGMII * const MSS_SCB_CFM_SGMII_MUX =\
+ ((IOSCB_CFM_SGMII *) MSS_SCB_SGMII_MUX_BASE);
+IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_SGMII =\
+ (IOSCB_IO_CALIB_STRUCT *)IOSCB_IO_CALIB_SGMII_BASE;
+IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_DDR =\
+ (IOSCB_IO_CALIB_STRUCT *)IOSCB_IO_CALIB_DDR_BASE;
+
+
+/*******************************************************************************-
+ * Symbols from the linker script used to locate the text, data and bss
+ * sections.
+ ******************************************************************************/
+#ifndef MPFS_HAL_HW_CONFIG
+uint32_t __sc_load;
+uint32_t __sc_start;
+uint32_t __sc_end;
+#else
+extern uint32_t __sc_load;
+extern uint32_t __sc_start;
+extern uint32_t __sc_end;
+
+/*******************************************************************************
+ * Local Defines *
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Local function declarations
+ */
+__attribute__((weak)) void copy_switch_code(void);
+
+
+/*******************************************************************************
+ * Instance definitions *
+ ******************************************************************************/
+
+void sgmii_mux_config(uint8_t option);
+
+/*******************************************************************************
+ Local functions *
+*******************************************************************************/
+
+
+/***************************************************************************//**
+ * set_RTC_divisor()
+ * Set the RTC divisor based on MSS Configurator setting
+ * Note: This will always be calculated so RTC clock is 1MHz.
+ */
+void set_RTC_divisor(void)
+{
+
+ SYSREG->RTC_CLOCK_CR &= ~(0x01U<<16); /* disable RTC clock */
+
+ SYSREG->RTC_CLOCK_CR = (LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK / \
+ LIBERO_SETTING_MSS_RTC_TOGGLE_CLK);
+
+ SYSREG->RTC_CLOCK_CR |= (0x01U<<16); /* enable RTC clock */
+
+}
+
+
+/***************************************************************************//**
+ * mss_mux_pre_mss_pll_config()
+ *
+ * Feed through required reference clks to PLL, configure PLL and wait for lock
+ ******************************************************************************/
+static void mss_mux_pre_mss_pll_config(void)
+{
+ /*
+ * PLL RF clk mux selections
+ * [31:15] Reserved
+ * [14:10] pll1_fdr_sel
+ * [9:8] pll1_rfclk1_sel
+ * [7:6] pll1_rfclk0_sel
+ * [5:4] pll0_rfclk1_sel
+ * [3:2] pll0_rfclk0_sel
+ * [1:0] clk_in_mac_tsu_sel
+ *
+ * Each mux uses 2 configuration bits. These are decoded as follows:
+ * 00 vss
+ * 01 refclk_p,refclk_n
+ * 10 scb_clk
+ * 10 serdes_refclk_crn_mss<0>, serdes_refclk_crn_mss<1>
+ *
+ * e.g.
+ * PLL_CKMUX = 0x00000154
+ * pll0_rfclk0_sel = 1 => refclk_p is used for pll0 ref0 and refclk_n is
+ * fed to MSS PLL ref1
+ */
+ /* CFM_MSS 0x3E002000 - 0x08 */
+ MSS_SCB_CFM_MSS_MUX->PLL_CKMUX = LIBERO_SETTING_MSS_PLL_CKMUX;
+ /*
+ * MSS Clock mux selections
+ * [31:5] Reserved
+ * [4] clk_standby_sel
+ * [3:2] mssclk_mux_md
+ * step 7: 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the
+ * MSS PLL clock.
+ * [1:0] mssclk_mux_sel MSS glitchless mux select
+ * 00 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=clk_standby
+ * 01 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=clk_standby
+ * 10 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=pllout1
+ * 11 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=pllout1
+ *
+ *
+ */
+ /*
+ * We will not set as already set to 0, we feed through after we have setup
+ * clock
+ * MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = LIBERO_SETTING_MSS_MSSCLKMUX;
+ */
+
+ /*
+ * Clock_Receiver
+ * [13] en_rdiff
+ * [12] clkbuf_en_pullup
+ * [11:10] en_rxmode_n
+ * [9:8] en_term_n
+ * [7] en_ins_hyst_n
+ * [6] en_udrive_n
+ * [5:4] en_rxmode_p
+ * [3:2] en_term_p
+ * [1] en_ins_hyst_p
+ * [0] en_udrive_p
+ */
+ MSS_SCB_CFM_SGMII_MUX->CLK_XCVR = LIBERO_SETTING_SGMII_CLK_XCVR;
+
+ /*
+ * 29:25 bclk5_sel
+ * 24:20 bclk4_sel
+ * 19:15 bclk3_sel
+ * 14:10 bclk2_sel
+ * 9:5 bclk1_sel
+ * 4:0 bclk0_sel
+ *
+ * From SAC spec:
+ * Table 9 1: Each gbim bank clock mux programming in MSS corner
+ * The DDRPHY bank clocks bclk_horz<5:0> and bclk_vert<5:0> are driven
+ * from mux's gbim<5:0> in the MSS corner. Each mux uses 5 configuration
+ * bits.
+ *
+ * BCLK mux selections
+ * bclk0_sel=0x8 (pll0_out_1k<2> selected)
+ * bclk1_sel=0x10 (pll0_out_1k<3> selected)
+ * bclk2_sel=0x1 (vss selected)
+ * bclk3_sel=0x1 (vss selected)
+ * bclk4_sel=0x1 (vss selected)
+ * bclk5_sel=0x1 (vss selected)
+ *
+ */
+ MSS_SCB_CFM_MSS_MUX->BCLKMUX = LIBERO_SETTING_MSS_BCLKMUX;
+
+ /* MSS_SCB_CFM_MSS_MUX->SPARE0 = BCLKMUX_USER_CONFIG; */
+ MSS_SCB_CFM_MSS_MUX->FMETER_ADDR = LIBERO_SETTING_MSS_FMETER_ADDR;
+
+ MSS_SCB_CFM_MSS_MUX->FMETER_DATAW = LIBERO_SETTING_MSS_FMETER_DATAW;
+
+ MSS_SCB_CFM_MSS_MUX->FMETER_DATAR = LIBERO_SETTING_MSS_FMETER_DATAR;
+
+ /*
+ *
+ */
+ volatile uint32_t i;
+ for(i = 0U; i < 400U; i++)
+ {
+ i++;
+ }
+}
+
+
+/***************************************************************************//**
+ * mss_mux_post_mss_pll_config(void)
+ *
+ * Once MSS locked, feed through to MSS
+ * We must run this code from RAM, as we need to modify the clock of the eNVM
+ * The first thing we do is change the eNVM clock, to prevent L1 cache accessing
+ * eNVM as it will do as we approach the return instruction
+ * The mb() makes sure order of processing is not changed by the compiler
+ ******************************************************************************/
+__attribute__((section(".ram_codetext"))) \
+ static void mss_mux_post_mss_pll_config(void)
+{
+ /*
+ * Modify the eNVM clock, so it now matches new MSS clock
+ *
+ * [5:0]
+ * Sets the number of AHB cycles used to generate the PNVM clock,.
+ * Clock period = (Value+1) * (1000/AHBFREQMHZ)
+ * Value must be 1 to 63 (0 defaults to 15)
+ * e.g.
+ * 7 will generate a 40ns period 25MHz clock if the AHB clock is 200MHz
+ * 11 will generate a 40ns period 25MHz clock if the AHB clock is 250MHz
+ * 15 will generate a 40ns period 25MHz clock if the AHB clock is 400MHz
+ *
+ */
+ SYSREG->ENVM_CR = LIBERO_SETTING_MSS_ENVM_CR;
+
+ mb(); /* make sure we change clock in eNVM first so ready by the time we
+ leave */
+
+ /*
+ * When you're changing the eNVM clock frequency, there is a bit
+ * (ENVM_CR_clock_okay) in the eNVM_CR which can be polled to check that
+ * the frequency change has happened before bumping up the AHB frequency.
+ */
+ volatile uint32_t wait_for_true = 0U;
+ while ((SYSREG->ENVM_CR & ENVM_CR_CLOCK_OKAY_MASK) !=\
+ ENVM_CR_CLOCK_OKAY_MASK)
+ {
+#ifdef RENODE_DEBUG
+ break;
+#endif
+ wait_for_true++; /* need something here to stop debugger freezing */
+ }
+
+ /*
+ * Change the MSS clock as required.
+ *
+ * CLOCK_CONFIG_CR
+ * [5:0]
+ * Sets the master synchronous clock divider
+ * bits [1:0] CPU clock divider
+ * bits [3:2] AXI clock divider
+ * bits [5:4] AHB/APB clock divider
+ * 00=/1 01=/2 10=/4 11=/8 (AHB/APB divider may not be set to /1)
+ * Reset = 0x3F
+ *
+ * SYSREG->CLOCK_CONFIG_CR = (0x0U<<0U) | (0x1U<<2U) | (0x2U<<4U);
+ * MSS clk= 80Mhz, implies CPU = 80Mhz, AXI = 40Mhz, AHB/APB = 20Mhz
+ * Until we switch in MSS PLL clock (MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = 0x01)
+ * e.g. If MSS clk 800Mhz
+ * MSS clk= 800Mhz, implies CPU = 800Mhz, AXI = 400Mhz, AHB/APB = 200Mhz
+ */
+ SYSREG->CLOCK_CONFIG_CR = LIBERO_SETTING_MSS_CLOCK_CONFIG_CR;
+
+ /*
+ * Feed clock from MSS PLL to MSS, using glitch-less mux
+ *
+ * MSS Clock mux selections
+ * [31:5] Reserved
+ * [4] clk_standby_sel
+ * [3:2] mssclk_mux_md
+ * step 7: 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the
+ * MSS PLL clock.
+ * [1:0] mssclk_mux_sel MSS glitchless mux select
+ * 00 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=clk_standby
+ * 01 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=clk_standby
+ * 10 - msspll_fdr_0=clk_standby
+ * msspll_fdr_1=pllout1
+ * 11 - msspll_fdr_0=pllout0
+ * msspll_fdr_1=pllout1
+ *
+ *
+ */
+ MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = LIBERO_SETTING_MSS_MSSCLKMUX;
+
+ /*
+ * Change the RTC clock divisor, so RTC clock is 1MHz
+ */
+ set_RTC_divisor();
+}
+
+/***************************************************************************//**
+ * sgmii_mux_config(uint8_t option)
+ * @param option 1 => soft reset, load RPC settings
+ * 0 => write values using SCB
+ ******************************************************************************/
+void sgmii_mux_config(uint8_t option)
+{
+ switch(option)
+ {
+ default:
+ case SCB_UPDATE: /* write to SCB register */
+
+ /*
+ * SCB address: 0x3E20 0008
+ * MSS Clock mux selections
+ *
+ * [31:0] SGMII_CLKMUX
+ */
+ /* CFM_ETH - 0x3E200000 - - 0x08 */
+ MSS_SCB_CFM_SGMII_MUX->SGMII_CLKMUX =\
+ LIBERO_SETTING_SGMII_SGMII_CLKMUX;
+ /*
+ * SCB address: 0x3E20 0010
+ * Clock_Receiver
+ *
+ * [13] en_rdiff
+ * [12] clkbuf_en_pullup
+ * [11:10] en_rxmode_n
+ * [9:8] en_term_n
+ * [7] en_ins_hyst_n
+ * [6] en_udrive_n
+ * [5:4] en_rxmode_p
+ * [3:2] en_term_p
+ * [1] en_ins_hyst_p
+ * [0] en_udrive_p
+ */
+ MSS_SCB_CFM_SGMII_MUX->CLK_XCVR =\
+ LIBERO_SETTING_SGMII_CLK_XCVR; /* 0x2011 */
+ /*
+ * SCB address: 0x3E20 0004
+ * PLL RF clk mux selections
+ *
+ * [3:2] pll0_rfclk1_sel
+ * 00 => vss
+ * 01 => refclk_p muxed to DDR PLL
+ * and SGMII PLL ( see
+ * 10 => scb_clk
+ * 11 => serdes_refclk_crn_mss<1>
+ * [1:0] pll0_rfclk0_sel
+ * 00 => vss
+ * 01 => refclk_n muxed to DDR PLL
+ * and SGMII PLL
+ * 10 => scb_clk
+ * 11 => serdes_refclk_crn_mss<1>
+ *
+ *
+ */
+ /* 0x05 => ref to SGMII and DDR */
+ MSS_SCB_CFM_SGMII_MUX->RFCKMUX =\
+ LIBERO_SETTING_SGMII_REFCLKMUX;
+ break;
+
+ case RPC_REG_UPDATE:
+ /*
+ * set the NV map reset
+ * This will load the APB registers, set via SGMII TIP.
+ * */
+ MSS_SCB_CFM_SGMII_MUX->SOFT_RESET = 1U;
+ break;
+ }
+}
+
+/***************************************************************************//**
+ *
+ * On startup, MSS supplied with 80MHz SCB clock
+
+ 9.2 Power on procedure for the MSS PLL clock
+
+ During POR:
+ Keep PLL in power down mode. powerdown_int_b=0
+
+ After POR, Power-On steps:
+ 1) mssclk_mux_sel_int<0>=0 & powerdown_int_b=0 & clk_standby_sel=0
+ MSS PLL is powered down and selects clk_standby=scb_clk
+ 2) PFC Processor writes powerdown_int_b=1 & divq0_int_en=1
+ MSS PLL powers up, then lock asserts when locked.
+ 3) PFC Processor switches mssclk_mux_sel_int<0>=1
+ MSS PLL clock is now sent to MSS.
+ 4) When BOOT authentication is complete
+ a. PFC processor writes mssclk_mux_sel_int<0>=0 to select clk_standby.
+ b. PFC Processor writes powerdown_int_b=0 to power down the PLL
+ >>>>>>>> G5 Soc User code >>>>>>>>>>>>>>
+ c. MSS Processor writes new parameters to the MSS PLL
+ 5) MSS Processor writes powerdown_int_b=1
+ Start up the PLL with NEW parameters.
+ Wait for LOCK
+ 6) MSS Processor enables all 4 PLL outputs.
+ 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the MSS PLL
+ clock.
+ *
+ ******************************************************************************/
+void mss_pll_config(void)
+{
+ copy_switch_code(); /* copy switch code to RAM */
+
+ MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+ MSS_SCB_MSS_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+
+ /*
+ Enable the PLL by removing the reset-
+ PERIPH / periph_reset_b - This asserts the functional reset of the
+ block.
+ It is asserted at power up. When written is stays asserted until written
+ to 0.
+ */
+ /*
+ * 4. c. MSS Processor writes new parameters to the MSS PLL
+ */
+ /*
+ * [0] REG_BYPASS_GO_B
+ * [0] BYPCK_SEL
+ * [0] RESETONLOCK
+ * [0] REG_RFCLK_SEL
+ * [0] REG_DIVQ3_EN
+ * [0] REG_DIVQ2_EN
+ * [0] REG_DIVQ1_EN
+ * [0] REG_DIVQ0_EN
+ * [0] REG_RFDIV_EN
+ * [0] REG_POWERDOWN_B
+ */
+
+ MSS_SCB_MSS_PLL->PLL_CTRL = LIBERO_SETTING_MSS_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
+
+ /*
+ * PLL calibration register
+ * This value is factory set, do not overwrite
+ * MSS_SCB_MSS_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
+ *
+ */
+
+ MSS_SCB_MSS_PLL->PLL_REF_FB = LIBERO_SETTING_MSS_PLL_REF_FB;
+
+ MSS_SCB_MSS_PLL->PLL_DIV_0_1 = LIBERO_SETTING_MSS_PLL_DIV_0_1;
+
+ MSS_SCB_MSS_PLL->PLL_DIV_2_3 = LIBERO_SETTING_MSS_PLL_DIV_2_3;
+
+ MSS_SCB_MSS_PLL->PLL_CTRL2 = LIBERO_SETTING_MSS_PLL_CTRL2;
+
+ MSS_SCB_MSS_PLL->PLL_FRACN = LIBERO_SETTING_MSS_PLL_FRACN;
+ MSS_SCB_MSS_PLL->SSCG_REG_0 = LIBERO_SETTING_MSS_SSCG_REG_0;
+ MSS_SCB_MSS_PLL->SSCG_REG_1 = LIBERO_SETTING_MSS_SSCG_REG_1;
+
+ MSS_SCB_MSS_PLL->SSCG_REG_2 = LIBERO_SETTING_MSS_SSCG_REG_2;
+ MSS_SCB_MSS_PLL->SSCG_REG_3 = LIBERO_SETTING_MSS_SSCG_REG_3;
+
+ /* PLL phase registers */
+ MSS_SCB_MSS_PLL->PLL_PHADJ = LIBERO_SETTING_MSS_PLL_PHADJ;
+
+ /*
+ * 5) MSS Processor writes powerdown_int_b=1
+ * Start up the PLL with NEW parameters.
+ Wait for LOCK
+ */
+ mss_mux_pre_mss_pll_config(); /* feed required inputs */
+ /* bit 0 == REG_POWERDOWN_B */
+ MSS_SCB_MSS_PLL->PLL_CTRL = (LIBERO_SETTING_MSS_PLL_CTRL) | 0x01U;
+ /*
+ * Start up the PLL with NEW parameters.
+ * Wait for LOCK
+ * todo: make wait clock based
+ */
+ volatile uint32_t timer_out=0x000000FFU;
+ while((MSS_SCB_MSS_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == 0U)
+ {
+#ifdef RENODE_DEBUG
+ break;
+#endif
+ if (timer_out != 0U)
+ {
+ timer_out--;
+ }
+ else
+ {
+ //todo: add failure mode
+ }
+ }
+
+ /*
+ * 6) MSS Processor enables all 4 PLL outputs.
+ * 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the MSS PLL
+ * clock.
+ */
+ mss_mux_post_mss_pll_config();
+}
+
+/**
+ *
+ * @param option choose between SCB or RPC and soft reset update method.
+ */
+void ddr_pll_config(REG_LOAD_METHOD option)
+{
+
+ switch(option)
+ {
+ default:
+ case SCB_UPDATE: /* write to SCB register */
+ /* PERIPH / periph_reset_b - This asserts the functional reset of
+ * the block. It is asserted at power up. When written is stays
+ * asserted until written to 0.
+ * First set periph_reset_b, than remove reset. As may be called
+ * more than one.
+ * */
+ MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+
+ MSS_SCB_DDR_PLL->PLL_CTRL = LIBERO_SETTING_DDR_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
+ /* PLL calibration register */
+
+ /*
+ * PLL calibration register
+ * This value is factory set, do not overwrite
+ * MSS_SCB_DDR_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
+ *
+ */
+
+ MSS_SCB_DDR_PLL->PLL_REF_FB = LIBERO_SETTING_DDR_PLL_REF_FB;
+
+
+ MSS_SCB_DDR_PLL->PLL_DIV_0_1 = LIBERO_SETTING_DDR_PLL_DIV_0_1;
+
+ MSS_SCB_DDR_PLL->PLL_DIV_2_3 = LIBERO_SETTING_DDR_PLL_DIV_2_3;
+
+
+ MSS_SCB_DDR_PLL->PLL_CTRL2 = LIBERO_SETTING_DDR_PLL_CTRL2;
+
+ MSS_SCB_DDR_PLL->PLL_FRACN = LIBERO_SETTING_DDR_PLL_FRACN;
+ MSS_SCB_DDR_PLL->SSCG_REG_0 = LIBERO_SETTING_DDR_SSCG_REG_0;
+ MSS_SCB_DDR_PLL->SSCG_REG_1 = LIBERO_SETTING_DDR_SSCG_REG_1;
+
+ MSS_SCB_DDR_PLL->SSCG_REG_2 = LIBERO_SETTING_DDR_SSCG_REG_2;
+ MSS_SCB_DDR_PLL->SSCG_REG_3 = LIBERO_SETTING_DDR_SSCG_REG_3;
+
+ /* PLL phase registers */
+
+ MSS_SCB_DDR_PLL->PLL_PHADJ = LIBERO_SETTING_MSS_PLL_PHADJ;
+
+ MSS_SCB_DDR_PLL->PLL_CTRL = (LIBERO_SETTING_DDR_PLL_CTRL)\
+ | 0x01U; /* bit 0 == REG_POWERDOWN_B */
+
+ break;
+
+ case RPC_REG_UPDATE:
+ /* CFG_DDR_SGMII_PHY->SOFT_RESET_MAIN_PLL; */
+ CFG_DDR_SGMII_PHY->PLL_CTRL_MAIN.PLL_CTRL_MAIN =\
+ LIBERO_SETTING_DDR_PLL_CTRL | 0x01U;
+ CFG_DDR_SGMII_PHY->PLL_REF_FB_MAIN.PLL_REF_FB_MAIN =\
+ LIBERO_SETTING_DDR_PLL_REF_FB;
+ /* Read only in RPC
+ * CFG_DDR_SGMII_PHY->PLL_FRACN_MAIN.PLL_FRACN_MAIN =\
+ * LIBERO_SETTING_DDR_PLL_FRACN; */
+ CFG_DDR_SGMII_PHY->PLL_DIV_0_1_MAIN.PLL_DIV_0_1_MAIN =\
+ LIBERO_SETTING_DDR_PLL_DIV_0_1;
+ CFG_DDR_SGMII_PHY->PLL_DIV_2_3_MAIN.PLL_DIV_2_3_MAIN =\
+ LIBERO_SETTING_DDR_PLL_DIV_2_3;
+ CFG_DDR_SGMII_PHY->PLL_CTRL2_MAIN.PLL_CTRL2_MAIN =\
+ LIBERO_SETTING_DDR_PLL_CTRL2;
+ /* Read only in RPC todo: verify this is correct
+ * CFG_DDR_SGMII_PHY->PLL_CAL_MAIN.PLL_CAL_MAIN =\
+ * LIBERO_SETTING_DDR_PLL_CAL; */
+ CFG_DDR_SGMII_PHY->PLL_PHADJ_MAIN.PLL_PHADJ_MAIN =\
+ LIBERO_SETTING_DDR_PLL_PHADJ;
+ /*__I CFG_DDR_SGMII_PHY_SSCG_REG_0_MAIN_TypeDef SSCG_REG_0_MAIN; */
+ /*__I CFG_DDR_SGMII_PHY_SSCG_REG_1_MAIN_TypeDef SSCG_REG_1_MAIN; */
+ CFG_DDR_SGMII_PHY->SSCG_REG_2_MAIN.SSCG_REG_2_MAIN =\
+ LIBERO_SETTING_DDR_SSCG_REG_2;
+ /*__I CFG_DDR_SGMII_PHY_SSCG_REG_3_MAIN_TypeDef SSCG_REG_3_MAIN; */
+ /*
+ * set the NV map reset
+ * This will load the APB registers, set via SGMII TIP.
+ * */
+ /* bit 0 == REG_POWERDOWN_B */
+ MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+ break;
+ }
+}
+
+/**
+ * ddr_pll_lock_scb(void)
+ * checks to see if lock has occurred
+ * @return => lock has occurred, 1=> no lock
+ */
+uint8_t ddr_pll_lock_scb(void)
+{
+ uint8_t result = 1U;
+#ifndef RENODE_DEBUG
+ if((MSS_SCB_DDR_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == PLL_CTRL_LOCK_BIT)
+ {
+ result = 0U; /* PLL lock has occurred */
+ }
+#else
+ result = 0U;
+#endif
+ return (result);
+}
+
+/***************************************************************************//**
+ *
+ ******************************************************************************/
+void ddr_pll_config_scb_turn_off(void)
+{
+ /* PERIPH / periph_reset_b */
+ MSS_SCB_DDR_PLL->PLL_CTRL &= (uint32_t)~0x00000001UL;
+}
+
+
+/***************************************************************************//**
+ * sgmii_pll_config_scb(uint8_t option)
+ * @param option 1 => soft reset, load RPC settings
+ * 0 => write values using SCB
+ ******************************************************************************/
+void sgmii_pll_config_scb(uint8_t option)
+{
+
+ switch(option)
+ {
+ default:
+ case SCB_UPDATE: /* write to SCB register */
+ /* PERIPH / periph_reset_b - This asserts the functional reset of
+ * the block. It is asserted at power up. When written is stays
+ * asserted until written to 0.
+ * First set periph_reset_b, than remove reset. As may be called
+ * more than one.
+ * */
+ MSS_SCB_SGMII_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
+
+ MSS_SCB_SGMII_PLL->PLL_CTRL = LIBERO_SETTING_SGMII_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
+ /* PLL calibration register */
+
+ /*
+ * PLL calibration register
+ * This value is factory set, do not overwrite
+ * MSS_SCB_SGMII_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
+ *
+ */
+
+ MSS_SCB_SGMII_PLL->PLL_REF_FB = LIBERO_SETTING_SGMII_PLL_REF_FB;
+
+
+ MSS_SCB_SGMII_PLL->PLL_DIV_0_1 = LIBERO_SETTING_SGMII_PLL_DIV_0_1;
+
+ MSS_SCB_SGMII_PLL->PLL_DIV_2_3 = LIBERO_SETTING_SGMII_PLL_DIV_2_3;
+
+
+ MSS_SCB_SGMII_PLL->PLL_CTRL2 = LIBERO_SETTING_SGMII_PLL_CTRL2;
+
+ MSS_SCB_SGMII_PLL->PLL_FRACN = LIBERO_SETTING_SGMII_PLL_FRACN;
+ MSS_SCB_SGMII_PLL->SSCG_REG_0 = LIBERO_SETTING_SGMII_SSCG_REG_0;
+ MSS_SCB_SGMII_PLL->SSCG_REG_1 = LIBERO_SETTING_SGMII_SSCG_REG_1;
+
+ MSS_SCB_SGMII_PLL->SSCG_REG_2 = LIBERO_SETTING_SGMII_SSCG_REG_2;
+ MSS_SCB_SGMII_PLL->SSCG_REG_3 = LIBERO_SETTING_SGMII_SSCG_REG_3;
+
+ /* PLL phase registers */
+
+ MSS_SCB_SGMII_PLL->PLL_PHADJ = LIBERO_SETTING_SGMII_PLL_PHADJ;
+
+ MSS_SCB_SGMII_PLL->PLL_CTRL = (LIBERO_SETTING_SGMII_PLL_CTRL)\
+ | 0x01U; /* bit 0 == REG_POWERDOWN_B */
+
+ break;
+
+ case RPC_REG_UPDATE:
+ /*
+ * set the NV map reset
+ * This will load the APB registers, set via SGMII TIP.
+ * */
+ /* bit 0 == REG_POWERDOWN_B */
+ MSS_SCB_SGMII_PLL->SOFT_RESET = 0x01U;
+ break;
+ }
+}
+
+/**
+ * sgmii_pll_lock_scb(void)
+ * checks to see if lock has occurred
+ * @return => lock has occurred, 1=> no lock
+ */
+uint8_t sgmii_pll_lock_scb(void)
+{
+ uint8_t result = 1U;
+#ifndef RENODE_DEBUG
+ if((MSS_SCB_SGMII_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == PLL_CTRL_LOCK_BIT)
+ {
+ result = 0U; /* PLL lock has occurred */
+ }
+#else
+ result = 0U;
+#endif
+ return (result);
+}
+
+
+/***************************************************************************//**
+ * Copy switch code routine to RAM.
+ * Copy locations have been defined in the linker script
+ ******************************************************************************/
+__attribute__((weak)) void copy_switch_code(void)
+{
+ uint32_t * sc_lma = &__sc_load;
+ uint32_t * end_sc_vma = &__sc_end;
+ uint32_t * sc_vma = &__sc_start;
+
+ if ( sc_vma != sc_lma )
+ {
+ while ( sc_vma < end_sc_vma )
+ {
+ *sc_vma = *sc_lma;
+ sc_vma++ ; sc_lma++;
+ }
+ }
+}
+
+#endif /* MPFS_HAL_HW_CONFIG */
+#endif
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_pll.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_pll.h
new file mode 100644
index 00000000..3581e6a8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_pll.h
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_pll.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PLL defines
+ *
+ */
+
+/*=========================================================================*//**
+ @page PolarFire SoC MSS Clock Setup
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor subsystem (MSS) has three PLL's, the MSS, DDR
+ and MSS SGMII's.
+ Two CFM IP blocks are used to mux the PLL input and outputs.
+
+ ==============================================================================
+ PLL Inputs
+ ==============================================================================
+ Each of the three PLL's can be configured with the following inputs:
+ - VSS ( default on reset )
+ - external ref clock in SGMII IO Block
+ - SCB Clock (80MHz)
+ - North West corner clock mux structure ICB
+
+ There are two bits associated with setting clk source
+
+ Note on North West corner clock mux structure ICB
+ The Fabric reference clock inputs source come from the clock mux's in the
+ upper left corner (regular FPGA corner) that provided clocks that can be
+ routed in from various places that will include from IOs, from the FPGA
+ fabric, etc.
+
+
+
+ ==============================================================================
+ MSS PLL Outputs
+ ==============================================================================
+ Each PLL has four outputs. These are generally gated through a mux
+ MSS PLL Outputs
+
+ | Output(0-3) | Detail | Mux | Muxed with |
+ | ------------- |:-------------:|:-------------:| -----------:|
+ | msspll_fdr_0 | clk_in_mss | no | - |
+ | msspll_fdr_1 | clk_in_crypto | no | - |
+ | msspll_fdr_2 | clk_in_emmc | glitch-less | SCB clk |
+ | msspll_fdr_3 | clk_in_can | glitch-less | SCB clk |
+
+ ==============================================================================
+ SCB bus timing
+ ==============================================================================
+ When the MSS is using the SCB bus, there is a timing relationship.
+ The defaults should be OK here. In necessary, the timing used by the MSS SCB
+ access is adjusted using the MSS system register TIMER.
+ (SCBCFG_REGS->TIMER.TIMER)
+ - Bits 15:8 Sets how long SCB request is held active after SCB bus granted.
+ - Allows SCB bus master-ship to maintained across multiple SCB access
+ cycles
+ - Bits 7:0 Set the timeout for an SCB access in CPU cycles.
+
+ ==============================================================================
+ eNVM timing
+ ==============================================================================
+ The clk used by the eNVM is adjusted using the following register:
+ SYSREG->ENVM_CR
+ [5:0]
+ Sets the number of AHB cycles used to generate the PNVM clock,.
+ Clock period = (Value+1) * (1000/AHBFREQMHZ)
+ Value must be 1 to 63 (0 defaults to 15)
+ e.g.
+ 11 will generate a 40ns period 25MHz clock if the AHB clock is 250MHz
+ 15 will generate a 40ns period 25MHz clock if the AHB clock is 400MHz
+
+ ==============================================================================
+ MSS clocks at reset
+ ==============================================================================
+ When the MSS comes out of reset, the MSS will be running on the SCB supplied
+ 80MHz clock.
+
+
+
+ ==============================================================================
+ MSS clock setup - Use case one - using external reference from SGMII I/O Blk
+ ==============================================================================
+ Use case one will be used in the majority of cases.
+ This is where the MSS PLL reference clk will be supplied from an external
+ reference through the external ref clock in SGMII IO Block.
+
+
+ scb clk
+ 01=>ext clk ref +
+ +----------+ +--------+ | 0=>SCB
+ crn | | | MSS | | 1=>PLL
+ +--->| | | PLL | | +------+
+ +-----+ scb | | | | +>| |mss
+ | | +---- | | | | mux +-->
+ | ext + p | mux +-->|ref0 0+--->| |clk
+ | clk +--------->| | | | +------+
+ | ref | n vss | | | | 0=>SCB
+ | +---+ ->| | | | 1=>PLL
+ | | | | | | | +------+
+ | | | | | | |scb-| |crypto
+ +-----+ | +----------+ | | | mux +-->
+ | | 1+--->| |clk
+ | 01=>ext clk ref | | +------+
+ | +----------+ | |
+ | crn| | | | +------+
+ | +-->| | | | | |
+ | scb| | | 2+--->| eMMC +
+ | +-->| | | | | |
+ | | mux +-->|ref1 | +------+
+ +----->| | | |
+ vss| | | | +------+
+ +-->| | | | | |
+ | | | 3+--->| CAN +
+ | | | | | |
+ +----------+ +--------+ +------+
+
+ Steps to setup ext clk:
+ 1. The external clock reference is setup- In SGMII setup
+ 2. The input mux is set to take input from ext ref clk
+ 3. MSS PLL clock is setup with required settings
+ 4. PLL is checked until locked
+ 5. MSS PLL output is switched through to MSS ( switch code run from ram )
+ 6. eNVM clcock is changed as required
+ 7. return from RAM routine and continue
+
+ ==============================================================================
+ MSS clock dividers
+ ==============================================================================
+ The three dividers generating the MSS master clocks are controllable via the
+ system register (CLOCK_CONFIG_CR).
+ CPU clock dividers are set in the function mss_mux_post_mss_pll_config(void)
+
+ | Divider | Config bits | Reset | MAX feq. * |
+ | ------------- |:-------------:|:----------:| -----------:|
+ | CPU | 1:0 | 00 | 625 |
+ | AXI | 3:2 | 01 | 312.5 |
+ | AHB/APB | 5:4 | 10 | 156.25 |
+
+ settings = 00=/1, 01=/2, 01=/4, 01=/8
+ * verify MAX feq. setting with particular silicon variant data sheet
+ - The CPU clock must not exceed 625MHz
+ - The AXI clock must not exceed 312.5MHz
+ - The AHB clock must not exceed 156.25MHz
+ - The CPU clock must be greater or equal to the AXI clock
+ - The AHB/APB clocks cannot be divided by 1. Divide by 1 will divide the
+ clock by 2.
+ - The clock divider register may be changed from any value to any value in
+ one go.
+ - When the USB block is in-use the AHB clock must be greater than 66 MHz.
+
+
+ +---------------------+ +-------------+
+ | +----------+ | | |
+ | +--> /1/2/4/8 +-->+--------->| CPU cores |
+ +-----------+ | | +----------+ | | |
+ | | | | | +-------------+
+ | MSS CLK | | | |
+ | | | | | +-------------+
+ | +---------+---+ +---------+ | | dfi_apb_pclk|
+ | | | +->|/4/8/16 +--->+----------> |
+ | | | | +---------+ | | |
+ | | | | | +-------------+
+ +-----------+ | | |
+ | | |
+ | | | +-------------+
+ | | +---------+ | | MSS AXI |
+ | +--> 1/2/4/8 +--->+--------->| Buses and |
+ | | +---------+ | | peripherals |
+ | | | +-------------+
+ | | |
+ | | |
+ | | | +-------------+
+ | | +-------+ | | MSS APB/AHB |
+ | +->| 2/4/8 +----->+--------->| Buses and
+ | +-------+ | | peripherals |
+ +---------------------+ +-------------+
+
+
+ *//*=========================================================================*/
+#ifndef MSS_DDR_SGMII_MSS_PLL_H_
+#define MSS_DDR_SGMII_MSS_PLL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PLL_CTRL_LOCK_BIT ((0x01U) << 25U)
+/*
+ * bit0 1: This when asserted resets all the non-volatile register bits
+ * e.g. RW-P bits, the bit self clears i.e. is similar to a W1P bit
+ * bit1 1: This when asserted resets all the register bits apart from the
+ * non-volatile registers, the bit self clears. i.e. is similar to a
+ * W1P bit
+ */
+#define PLL_INIT_AND_OUT_OF_RESET 0x00000003UL
+
+#define PLL_CTRL_REG_POWERDOWN_B_MASK 0x00000001UL
+
+typedef enum RTC_CLK_SOURCE_
+{
+ SCB_80M_CLOCK = 0x00, /*!< 0 SCB clock source */
+ MSS_PLL_CLOCK = 0x01, /*!< 1 MSS PLL clock source */
+} RTC_CLK_SOURCE;
+
+typedef enum REG_LOAD_METHOD_
+{
+ SCB_UPDATE = 0x00, /*!< 0 SCB direct load */
+ RPC_REG_UPDATE = 0x01, /*!< 1 RPC -> SCB load */
+} REG_LOAD_METHOD;
+
+
+
+/***************************************************************************//**
+ ddr_pll_config() configure DDR PLL
+
+ Example:
+ @code
+
+ ddr_pll_config();
+
+ @endcode
+
+ */
+void ddr_pll_config(REG_LOAD_METHOD option);
+
+/***************************************************************************//**
+ ddr_pll_lock_scb() Checks if PLL locked
+
+ @return
+ 0U if locked
+
+ Example:
+ @code
+ if (ddr_pvt_calibration() == 0U)
+ {
+ PLL is locked
+ }
+ @endcode
+
+ */
+uint8_t ddr_pll_lock_scb(void);
+
+/***************************************************************************//**
+ sgmii_pll_config_scb() configure sgmii PLL
+
+ @param option 1 => soft reset, load RPC settings
+ 0 => write values using SCB
+
+ Example:
+ @code
+
+ sgmii_pll_config_scb(1U);
+
+ @endcode
+
+ */
+void sgmii_pll_config_scb(uint8_t option);
+
+/***************************************************************************//**
+ sgmii_pll_lock_scb() Checks if PLL is locked
+
+ @return
+ 0U if locked
+
+ Example:
+ @code
+ if (ddr_pvt_calibration() == 0U)
+ {
+ PLL is locked
+ }
+ @endcode
+
+ */
+uint8_t sgmii_pll_lock_scb(void);
+
+/***************************************************************************//**
+ ddr_pll_config_scb_turn_off() Puts PLL in reset
+
+ Example:
+ @code
+
+ ddr_pll_config_scb_turn_off();
+
+ @endcode
+
+ */
+void ddr_pll_config_scb_turn_off(void);
+
+/***************************************************************************//**
+ set_RTC_divisor() Sets the RTC divisor based on values from Libero
+ It is assumed the RTC clock is set to 1MHz
+ Example:
+ @code
+
+ set_RTC_divisor();
+
+ @endcode
+
+ */
+void set_RTC_divisor(void);
+
+/***************************************************************************//**
+ sgmii_mux_config_via_scb() configures mux for SGMii
+
+ Example:
+ @code
+
+ sgmii_mux_config_via_scb();
+
+ @endcode
+
+ */
+void sgmii_mux_config_via_scb(uint8_t option);
+
+/***************************************************************************//**
+ pre_configure_sgmii_and_ddr_pll_via_scb()
+
+ @param option 1 => soft reset, load RPC settings
+ 0 => write values using SCB
+
+ Example:
+ @code
+
+ ddr_pvt_calibration(1U);
+
+ @endcode
+
+ */
+void pre_configure_sgmii_and_ddr_pll_via_scb(uint8_t option);
+
+/******************************************************************************
+ * Public Functions - API *
+ ******************************************************************************/
+void mss_pll_config(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_SGMII_MSS_PLL_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_scb_nwc_regs.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_scb_nwc_regs.h
new file mode 100644
index 00000000..8b908397
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_scb_nwc_regs.h
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_scb_nwc_regs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief SCB registers and associated structures relating to the NWC
+ *
+ */
+
+
+#ifndef MSS_DDR_SGMII_MSS_SCB_NWC_REGS_H_
+#define MSS_DDR_SGMII_MSS_SCB_NWC_REGS_H_
+
+#include "mpfs_hal/mss_hal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __I
+#define __I const volatile
+#endif
+#ifndef __IO
+#define __IO volatile
+#endif
+#ifndef __O
+#define __O volatile
+#endif
+
+/*------------ NWC PLL definition -----------*/
+typedef struct
+{
+ __IO uint32_t SOFT_RESET; /*!< Offset: 0x0 */
+ __IO uint32_t PLL_CTRL; /*!< Offset: 0x4 */
+ __IO uint32_t PLL_REF_FB; /*!< Offset: 0x8 */
+ __IO uint32_t PLL_FRACN; /*!< Offset: 0xc */
+ __IO uint32_t PLL_DIV_0_1; /*!< Offset: 0x10 */
+ __IO uint32_t PLL_DIV_2_3; /*!< Offset: 0x14 */
+ __IO uint32_t PLL_CTRL2; /*!< Offset: 0x18 */
+ __IO uint32_t PLL_CAL; /*!< Offset: 0x1c */
+ __IO uint32_t PLL_PHADJ; /*!< Offset: 0x20 */
+ __IO uint32_t SSCG_REG_0; /*!< Offset: 0x24 */
+ __IO uint32_t SSCG_REG_1; /*!< Offset: 0x28 */
+ __IO uint32_t SSCG_REG_2; /*!< Offset: 0x2c */
+ __IO uint32_t SSCG_REG_3; /*!< Offset: 0x30 */
+} PLL_TypeDef;
+
+/*------------ NWC PLL MUX definition -----------*/
+
+typedef struct
+{
+ __IO uint32_t SOFT_RESET; /*!< Offset: 0x0 */
+ __IO uint32_t BCLKMUX; /*!< Offset: 0x4 */
+ __IO uint32_t PLL_CKMUX; /*!< Offset: 0x8 */
+ __IO uint32_t MSSCLKMUX; /*!< Offset: 0xc */
+ __IO uint32_t SPARE0; /*!< Offset: 0x10 */
+ __IO uint32_t FMETER_ADDR; /*!< Offset: 0x14 */
+ __IO uint32_t FMETER_DATAW; /*!< Offset: 0x18 */
+ __IO uint32_t FMETER_DATAR; /*!< Offset: 0x1c */
+ __IO uint32_t TEST_CTRL; /*!< Offset: 0x20 */
+} IOSCB_CFM_MSS;
+
+typedef struct
+{
+ __IO uint32_t SOFT_RESET; /*!< Offset: 0x0 */
+ __IO uint32_t RFCKMUX; /*!< Offset: 0x4 */
+ __IO uint32_t SGMII_CLKMUX; /*!< Offset: 0x8 */
+ __IO uint32_t SPARE0; /*!< Offset: 0xc */
+ __IO uint32_t CLK_XCVR; /*!< Offset: 0x10 */
+ __IO uint32_t TEST_CTRL; /*!< Offset: 0x14 */
+} IOSCB_CFM_SGMII;
+
+
+typedef struct
+{
+ __IO uint32_t SOFT_RESET_IOCALIB; /*!< Offset: 0x00 */
+ __IO uint32_t IOC_REG0; /*!< Offset: 0x04 */
+ __I uint32_t IOC_REG1; /*!< Offset: 0x08 */
+ __I uint32_t IOC_REG2; /*!< Offset: 0x0c */
+ __I uint32_t IOC_REG3; /*!< Offset: 0x10 */
+ __I uint32_t IOC_REG4; /*!< Offset: 0x14 */
+ __I uint32_t IOC_REG5; /*!< Offset: 0x18 */
+ __IO uint32_t IOC_REG6; /*!< Offset: 0x1c */
+} IOSCB_IO_CALIB_STRUCT;
+
+
+#define MSS_SCB_MSS_PLL_BASE (0x3E001000U) /*!< ( MSS_SCB_MSS_PLL_BASE ) Base Address */
+#define MSS_SCB_DDR_PLL_BASE (0x3E010000U) /*!< ( MSS_SCB_DDR_PLL_BASE ) Base Address */
+#define MSS_SCB_SGMII_PLL_BASE (0x3E080000U) /*!< ( MSS_SCB_SGMII_PLL_BASE ) Base Address */
+
+#define MSS_SCB_MSS_MUX_BASE (0x3E002000U) /*!< ( MSS_SCB_MSS_MUX_BASE ) Base Address */
+#define MSS_SCB_SGMII_MUX_BASE (0x3E200000U) /*!< ( MSS_SCB_SGMII_PLL_BASE ) Base Address */
+
+#define IOSCB_IO_CALIB_SGMII_BASE (0x3E800000U) /*!< ( IOSCB_IO_CALIB_SGMII_BASE ) Base Address */
+#define IOSCB_IO_CALIB_DDR_BASE (0x3E040000U) /*!< ( IOSCB_IO_CALIB_SGMII_BASE ) Base Address */
+
+
+extern PLL_TypeDef * const MSS_SCB_MSS_PLL;
+extern PLL_TypeDef * const MSS_SCB_DDR_PLL;
+extern PLL_TypeDef * const MSS_SCB_SGMII_PLL;
+extern IOSCB_CFM_MSS * const MSS_SCB_CFM_MSS_MUX;
+extern IOSCB_CFM_SGMII * const MSS_SCB_CFM_SGMII_MUX;
+extern IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_SGMII;
+extern IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_DDR;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_DDR_SGMII_MSS_SCB_NWC_REGS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_sgmii.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_sgmii.c
new file mode 100644
index 00000000..a84396be
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_sgmii.c
@@ -0,0 +1,657 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_sgmii.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief sgmii related functions
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "simulation.h"
+
+#ifdef MPFS_HAL_HW_CONFIG
+
+static PART_TYPE silicon_variant = PART_NOT_DETERMINED;
+
+/*
+ * local functions
+ */
+static void setup_sgmii_rpc_per_config(void);
+#ifdef SGMII_SUPPORT
+static uint32_t sgmii_channel_setup(void);
+#endif
+
+/*
+ * local variable
+ */
+static uint32_t sro_dll_90_code;
+
+/*
+ * local functions
+ */
+static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold);
+
+/*
+ * extern functions
+ */
+extern void sgmii_mux_config(uint8_t option);
+
+
+uint32_t sgmii_setup(void)
+{
+#ifdef SGMII_SUPPORT
+ /*
+ * Check if any tx/Rx channels enabled
+ */
+ if((LIBERO_SETTING_SGMII_MODE & (TX_RX_CH_EN_MASK<SOFT_RESET_SGMII.SOFT_RESET_SGMII = \
+ (0x01 << 8U) | 1U; /* PERIPH soft reset */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;
+ setup_sgmii_rpc_per_config(); /* load RPC SGMII_MODE register ext */
+
+ /* Enable the Bank controller */
+ /*
+ * Set soft reset on IP to load RPC to SCB regs (dynamic mode)
+ * Bring the sgmii bank controller out of reset =- ioscb_bank_ctrl_sgmii
+ */
+ IOSCB_BANK_CNTL_SGMII->soft_reset = 1U; /* DPC_BITS NV_MAP reset */
+ sgmii_training_state = SGMII_IO_EN;
+ break;
+
+ case SGMII_IO_EN:
+ /*
+ * Check the IO_EN signal here.
+ * This is an output from the bank controller power detector, which are
+ * turned on using MSS_IO_EN
+ */
+ /* aro_ioen_bnk - PVT calibrator IOEN */
+ timer_out++;
+ if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (0x01U<<6U)) != 0U)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_RAMP_TIMER;
+ }
+ break;
+
+ case SGMII_RAMP_TIMER:
+ /*
+ * IO power ramp wait time
+ * After IOEN is received from power detectors DDR and SGMii, extra time
+ * required for voltage to ramp.
+ * This time will come from the user- Dependent on ramp time of power
+ * supply
+ * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
+ *
+ */
+ timer_out++;
+ if(timer_out >= 0xFU)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_IO_SETUP;
+ }
+ break;
+
+ case SGMII_IO_SETUP:
+ /*
+ * fixme- not sure if we should be setting this register
+ * From regmap detail:
+ * bit 8 of MSS_RESET_CR
+ * Asserts a reset the SGMII block containing the MSS reference clock
+ * input.
+ * Warning that setting this bit causes the external reference clock
+ * input to the
+ * MSS PLL to disappear.
+ * It is advisable to use the SGMII channel soft resets in the PHY
+ * instead of this bit.
+ * However if E51 software wants to set this bit, the MSS clock source
+ * should be switched over to the standby source in advance.
+ */
+ SCB_REGS->MSS_RESET_CR.MSS_RESET_CR = 0;
+
+ /*
+ * I ran the sim past the place where we set the nvmap_reset in the
+ * SOFT_RESET_SGMII register and it did not result in any
+ * change from the DLL default bits.
+ * But I traced the 'flashing' signal on one of these regs back to
+ * 'dll0_soft_reset_nv_map' (not 'pll0_soft_reset_periph').
+ * Now the only place I can find 'dll0_soft_reset_nv_map' is in SCB
+ * space...ie 0x3e10_0000 SOFT_RESET register.
+ *
+ */
+ /*
+ * so we have to use scb register to reset as no APB register available
+ * to soft reset the IP
+ * ioscb_dll_sgmii
+ * */
+ IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U); /* reset sgmii DLL */
+
+ /*
+ * I have discovered the problem with the tx channels (soft reset issue)
+ * So we require the:
+ *
+ * sgmiiphy_lane 01 soft-reset register (0x3650_0000) to be written to
+ * with 0x1 (to set the nv_map bit[0] =1 (self clears))
+ * same for sgmiiphy_lane 23 soft-reset register (0x3651_0000).
+ *
+ * This will result in the rpc bits for the Lane controls to get loaded.
+ * Not happening currently.
+ *
+ * The soft_reset_sgmii occurs in the mss_ddr.c line 436, so I suppose
+ * we put the 2 new soft reset writes after that.
+ *
+ */
+ {
+ /* sgmiiphy_lane 01 soft-reset register (0x3650_0000) */
+ SGMIIPHY_LANE01->soft_reset = 0x000000001U;
+ /* sgmiiphy_lane 23 soft-reset register (0x3650_0000) */
+ SGMIIPHY_LANE23->soft_reset = 0x000000001U;
+ }
+
+ /*
+ * Kick-off calibration, by taking calibration IP out of reset
+ */
+ /*
+ * Soft reset
+ */
+ {
+ /* PVT soft reset - APB*/
+ /* reg_pvt_soft_reset_periph */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x01U<< 10U) | (0x7FU<<0U);
+ /* reg_pvt_soft_reset_periph */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x7FU<<0U);
+ /* PVT soft reset - SCB */
+ /* make sure out of reset */
+ IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB = 0x1U;
+ /* make sure out of reset */
+ IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB = 0x0U;
+ }
+ sgmii_training_state = SGMII_WAIT_FOR_CALIB_COMPLETE;
+ break;
+
+ case SGMII_WAIT_FOR_CALIB_COMPLETE:
+ /*
+ * Verify calibration
+ * Bank 5 PVT calibrator can be controlled by MSS firmware through APB
+ * registers to do initial calibration and re-calibration. During startup,
+ * the initial calibration can be started by default when MSS releases SGMII
+ * reset. Re-calibration is enabled by default with reg_pvt_calib_start/lock
+ * bits being set to 1 before startup, and MSS firmware can start
+ * re-calibration after startup by toggling pvt_calib_start/lock bits per
+ * PVT calibrator spec.
+ *
+ */
+ if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (1U << 14U)) == (1U << 14U))
+ {
+ sgmii_training_state = SGMII_ASSERT_CALIB_LOCK;
+ }
+ break;
+
+ case SGMII_ASSERT_CALIB_LOCK:
+ /*
+ * now assert calib lock
+ * calibrated pcode and ncode will be written.
+ * */
+
+ CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT |= 0x40000000UL;
+ IOSCB_IO_CALIB_SGMII->IOC_REG0 |= (0x01U<<14U);
+ sgmii_training_state = SGMII_SET_UP_PLL;
+ break;
+
+ case SGMII_SET_UP_PLL:
+ /*
+ * SGMii Step 3) Wait for PLL and DLL lock
+ * Delay codes generated
+ */
+
+ /* 0U => configure using scb, 1U => NVMAP reset */
+ sgmii_mux_config(RPC_REG_UPDATE);
+ /* 0U => configure using scb, 1U => NVMAP reset */
+ sgmii_pll_config_scb(RPC_REG_UPDATE);
+
+ timer_out=0U;
+ sgmii_training_state = SGMII_WAIT_FOR_MSS_LOCK;
+ break;
+
+ case SGMII_WAIT_FOR_MSS_LOCK:
+ if (CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL & (1U<<7U))
+ {
+ sgmii_training_state = SGMII_WAIT_FOR_DLL_LOCK;
+ }
+ break;
+
+ case SGMII_WAIT_FOR_DLL_LOCK:
+ if (CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL & (1U<<23U))
+ {
+ sgmii_training_state = SGMII_TURN_ON_MACS;
+ }
+ break;
+
+ case SGMII_TURN_ON_MACS:
+ /*
+ * Provide mac clocks
+ * The nw_config register for mac0 (0x2011_0004): I am forcing 'gigabit' and
+ * 'tbi' bits = 11.
+ * The same for Mac1.
+ * This starts up the tx_mac_clocks for the 2 macs.
+ *
+ */
+ /* the mac clocks need to be turned on when setting up the sgmii */
+ (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ GEM_A_LO->network_config |= (0x01U << 10U) | (0x01U << 11U); /* GEM0 */
+ GEM_B_LO->network_config |= (0x01U << 10U) | (0x01U << 11U); /* GEM1 */
+ sgmii_training_state = SGMII_DETERMINE_SILICON_VARIANT;
+ break;
+
+ case SGMII_DETERMINE_SILICON_VARIANT:
+ /*
+ * Determine Silicon variant from generated dll generated sro_dll_90_code
+ */
+ sro_dll_90_code = ((CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL >> 16U) & 0x7FU);
+
+ if(CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & (01U<<31U)) /* bit31 == 1 => post rev B silicon */
+ {
+ silicon_variant = PART_REVC_OR_LATER;
+ set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST, EARLY_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST);
+ }
+ else
+ {
+ /*
+ * SS part expect < 13
+ * typical-typical or FF expect > 13
+ */
+ if(sro_dll_90_code < MIN_DLL_90_CODE_VALUE_INDICATING_TT_PART_REVB) /* SS part */
+ {
+ silicon_variant = SS_PART_REVB;
+ set_early_late_thresholds(LATE_EYE_WIDTH_SS_PART_REVB, EARLY_EYE_WIDTH_SS_PART_REVB);
+ }
+ else
+ {
+ silicon_variant = TT_PART_REVB;
+ set_early_late_thresholds(LATE_TT_PART_REVB, EARLY_TT_PART_REVB);
+ }
+ }
+ sgmii_training_state = SGMII_RESET_CHANNELS;
+ break;
+
+ case SGMII_RESET_CHANNELS:
+ /*
+ * DLL soft reset - Already configured
+ * PVT soft reset - Already configured
+ * Bank controller soft reset - Already configured
+ * CLKMUX soft reset - Already configured
+ * Lane0 soft reset - must be soft reset here
+ * Lane1 soft reset - must be soft reset here
+ *
+ * __IO uint32_t reg_lane0_soft_reset_periph :1; bit 13
+ * __IO uint32_t reg_lane1_soft_reset_periph :1; bit 14
+ */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
+ if(silicon_variant == PART_REVC_OR_LATER)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_WAIT_10MS;
+ }
+ else
+ {
+ sgmii_training_state = SGMII_CHANNELS_UP;
+ }
+ break;
+
+ case SGMII_WAIT_10MS:
+ timer_out++;
+ if(timer_out >= 0xFFFU)
+ {
+ timer_out=0U;
+ sgmii_training_state = SGMII_CHECK_REVC_RESULT;
+ }
+ break;
+
+ case SGMII_CHECK_REVC_RESULT:
+ if ( (CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & ARO_REF_PCODE_MASK) > ARO_REF_PCODE_REVC_THRESHOLD )
+ {
+ /* OK, we are good */
+ sgmii_training_state = SGMII_CHANNELS_UP;
+ }
+ else
+ {
+ /* need to adjust eye values */
+ set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER, EARLY_EYE_WIDTH_PART_REVC_OR_LATER);
+ /*
+ * Now reset the channels
+ */
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
+ CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
+ /* OK, we are good */
+ sgmii_training_state = SGMII_CHANNELS_UP;
+ }
+ break;
+
+ case SGMII_CHANNELS_UP:
+ /*
+ * SGMii Step 4) Monitor the DLL codes for Voltage and Temp variation
+ * MSS E51 software sets the magnitude value of variation to flag.
+ * MSS E51 software can poll this flag.
+ * Re-calibration, if needed, is controlled by E51 software if needed.
+ * ML step 4- This is a monitoring step- to be run constantly in the back
+ * ground
+ */
+ status = SGMII_FINISHED_SETUP;
+ break;
+ } /* end of switch statement */
+
+ return(status);
+}
+#endif
+
+/**
+ * setup_sgmii_rpc_per_config
+ * Configures SGMII RPC TIP registers
+ */
+static void setup_sgmii_rpc_per_config(void)
+{
+ CFG_DDR_SGMII_PHY->SGMII_MODE.SGMII_MODE = (LIBERO_SETTING_SGMII_MODE & ~REG_CDR_MOVE_STEP);
+ CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL = LIBERO_SETTING_CH0_CNTL;
+ CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL = LIBERO_SETTING_CH1_CNTL;
+ CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL = LIBERO_SETTING_RECAL_CNTL;
+ CFG_DDR_SGMII_PHY->CLK_CNTL.CLK_CNTL = LIBERO_SETTING_CLK_CNTL;
+ /* ibuffmx_p and _n rx1, bit 22 and 23 , rx0, bit 20 and 21 */
+ CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL = LIBERO_SETTING_SPARE_CNTL;
+ CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL = LIBERO_SETTING_PLL_CNTL;
+}
+
+/**
+ * SGMII Off mode
+ */
+void sgmii_off_mode(void)
+{
+ /*
+ * do soft reset of SGMII TIP
+ */
+ CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = (0x01 << 8U) | 1U;
+ CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;
+
+ /*
+ *
+ */
+ setup_sgmii_rpc_per_config();
+
+ /*
+ * Resetting the SCB register only required in already in dynamic mode. If
+ * not reset, IO will not be configured.
+ */
+ IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U); /* reset sgmii */
+
+}
+
+/**
+ *
+ */
+void ddr_pvt_calibration(void)
+{
+ /*
+ * R3.1
+ * PVT calibration
+ * Wait for IOEN from power detectors DDR and SGMII - IO enable signal from
+ * System Control powers on
+ *
+ * From DDR phy SAC spec:
+ * MSS processor releases dce bus to send RPC bits to IO buffer,
+ * setting each to it's programmed mode and then asserts
+ * ioen high at end of this state.
+ *
+ *
+ * Following verification required for MSS IO Calibration (DDRPHY,
+ * SGMII and MSSIO)
+ * Auto-calibration supply ramp time settings
+ * Calibration in reset until ioen_bnk goes high, timer complete
+ * and setup of bits complete
+ * scbclk divider setting (/1)
+ * calibration clkdiv setting
+ * VS bit settings
+ * Initial non-calibrated codes to IOs (functional max codes)
+ * Calibration signal transitions
+ * pvt_calib_status , r in reg DYN_CNTL
+ * reg_calib_reset, w/r in reg IOC_REG6
+ * calib_clkdiv, w/r in reg IOC_REG6
+ * soft_reset_periph_b,
+ * calib_lock, w/r in reg IOC_REG0
+ * calib_start, w/r in reg IOC_REG0
+ * calib_intrpt r in reg
+ * Final calibration codes
+ * Lane latching of codes
+ * IO Glitching
+ */
+ volatile uint32_t timer_out=0U;
+
+ #ifndef RENODE_DEBUG
+ /* sro_ioen_out */
+ while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & (1U<<4U)) == 0U)
+ {
+ timer_out++;
+ /*todo: add a fail break */
+ }
+ #endif
+
+ /*
+ * R3.2 Trigger timer and wait for completion
+ * PVT calibration
+ * After IOEN is received from power detectors DDR and SGMII, extra time
+ * required for voltage to ramp.
+ * This time will come from the user- Dependent on ramp time of power supply
+ * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
+ *
+ */
+ /*todo: implement proper timer- user will supply ramp time */
+ timer_out=0U;
+ while(timer_out < 0xFU)
+ {
+ timer_out++;
+ }
+
+ /*
+ * R3.2 Initiate calibration:
+ *
+ * IOC_REG6
+ * bit 2:1 reg_calib_clkdiv
+ * bit 0 reg_calib_reset
+ *
+ * DDRIO: calib_reset: 1 -> 0
+ * mss_write(0x20007000 + 0x21C,0x00000004);
+ * DDRIO: calib_rst_b: 0 -> 1
+ * mss_write(0x20007000 + 0x220,0x00000000);
+ * SGMII: calib_rst_b: 0 -> 1
+ * mss_write(0x20007000 + 0xC1C,0x00000000);
+ *
+ */
+ /*
+ * Soft reset
+ */
+ /* PVT soft reset - APB*/
+ /* DDRIO: calib_reset: 1 -> 0, clk divider changed - from 2 - to 3 */
+ CFG_DDR_SGMII_PHY->IOC_REG6.IOC_REG6 = 0x00000006U;
+
+ /* PVT soft nv reset - SCB, should load from RPC */
+ IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB = 0x1U; /* make sure reset */
+ IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB = 0x0U; /* make sure reset */
+
+ /*
+ * R3.4 Wait for PVT calibration to complete
+ * Check:
+ * bit 2 sro_calib_status
+ *
+ * The G5 Memory controller needs to see that the IO calibration has
+ * completed before kicking off DDR training.
+ * It uses the calib_status signal as a flag for this.
+ */
+ timer_out=0U;
+ #ifndef RENODE_DEBUG
+ {
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ }
+ #endif
+ /*
+ * now assert calib lock
+ *
+ * */
+ {
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<14U);
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<14U);
+ }
+}
+
+
+/**
+ *
+ */
+void ddr_pvt_recalibration(void)
+{
+ volatile uint32_t timer_out=0U;
+
+ /*
+ * now assert calib start
+ *
+ * */
+ {
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<13U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<13U);
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<13U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<13U);
+ }
+
+ /*
+ * R3.4 Wait for PVT calibration to complete
+ * Check:
+ * bit 2 sro_calib_status
+ *
+ * The G5 Memory controller needs to see that the IO calibration has
+ * completed before kicking off DDR training.
+ * It uses the calib_status signal as a flag for this.
+ */
+ timer_out=0U;
+ #ifndef RENODE_DEBUG
+ {
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ /* PVT I/O - sro_calib_status - wait for calibration to complete */
+ while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
+ {
+ timer_out++;
+ }
+ }
+ #endif
+ /*
+ * now assert calib lock
+ *
+ * */
+ {
+#if 0 /*
+ * fixme: this appears to cause wite calibration to fail, investigating
+ */
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<14U);
+ CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<14U);
+ IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<14U);
+#endif
+ }
+}
+
+/**
+ * Set eye thresholds
+ * @param n_late_threshold
+ * @param p_early_threshold
+ */
+static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold)
+{
+ uint32_t n_eye_values;
+ uint32_t p_eye_value;
+
+ /*
+ * Set the N eye width value
+ * bits 31:29 for CH1, bits 28:26 for CH0 in spare control (N eye width value)
+ */
+ n_eye_values = (n_late_threshold << SHIFT_TO_CH0_N_EYE_VALUE);
+ n_eye_values |= (n_late_threshold << SHIFT_TO_CH1_N_EYE_VALUE);
+
+ CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL = (LIBERO_SETTING_SPARE_CNTL & N_EYE_MASK) | n_eye_values;
+
+ /*
+ * Set P values
+ */
+ p_eye_value = (p_early_threshold << SHIFT_TO_REG_RX0_EYEWIDTH);
+ CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL = ((LIBERO_SETTING_CH0_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX0_EN_FLAG_N;
+ CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL = ((LIBERO_SETTING_CH1_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX1_EN_FLAG_N;
+
+}
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_sgmii.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_sgmii.h
new file mode 100644
index 00000000..75b3f80f
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/common/nwc/mss_sgmii.h
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_sgmii.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief SGMII defines
+ *
+ */
+
+#ifndef SRC_PLATFORM_MPFS_HAL_NWC_MSS_SGMII_H_
+#define SRC_PLATFORM_MPFS_HAL_NWC_MSS_SGMII_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define REG_RX0_EN_OFFSET (1U<<5U)
+#define REG_RX1_EN_OFFSET (1U<<7U)
+#define TX_RX_CH_EN_MASK 0xFU
+#define TX_RX_CH_EN_OFFSET 0x4U
+#define REG_CDR_MOVE_STEP (1U<<22U) /* delay taps 1 => 3 taps moved, 0 => 2 taps move. */
+ /* 2 taps best for small PPM values, best results observed. */
+
+#define SHIFT_TO_CH0_N_EYE_VALUE 26U /* 26-28 */
+#define SHIFT_TO_CH1_N_EYE_VALUE 29U /* 29-31 */
+#define N_EYE_MASK 0x03FFFFFFUL
+
+#define SHIFT_TO_REG_RX0_EYEWIDTH 21U
+#define REG_RX0_EYEWIDTH_P_MASK (~(0x7U<TEMP0 = (uint32_t)x)
+#define SIM_FEEDBACK1(x) (SYSREG->TEMP1 = (uint32_t)x)
+#else
+#define SIM_FEEDBACK0(x)
+#define SIM_FEEDBACK1(x)
+#endif
+
+#endif /* MSS_DDR_SGMII_SIMULATION_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/mpfs_hal_version.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/mpfs_hal_version.h
new file mode 100644
index 00000000..81ab4259
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/mpfs_hal_version.h
@@ -0,0 +1,50 @@
+#ifndef MPFS_HAL_VERSION_H
+#define MPFS_HAL_VERSION_H
+
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ *
+ */
+
+/*******************************************************************************
+ * @file mpfs_hal_version.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolareFire SoC Hardware Abstraction layer - MPFS HAL version.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MPFS_HAL_VERSION_MAJOR 1
+#define MPFS_HAL_VERSION_MINOR 8
+#define MPFS_HAL_VERSION_PATCH 125
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/mss_hal.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/mss_hal.h
new file mode 100644
index 00000000..86a3f9c5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/mss_hal.h
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file mss_hal.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS HAL include file. This is the file intended for application to
+ * include so that all the other MPFS files are then accessible to it.
+ *
+ */
+
+#ifndef MSS_HAL_H
+#define MSS_HAL_H
+
+#ifndef CONFIG_OPENSBI
+# include // for size_t
+# include // for bool, true, false
+# include
+#ifndef ssize_t
+typedef long ssize_t;
+#endif
+#endif
+
+#include "common/mss_assert.h"
+#include "common/nwc/mss_ddr_defs.h"
+#include "common/nwc/mss_ddr_sgmii_regs.h"
+#include "common/nwc/mss_io_config.h"
+#include "common/nwc/mss_pll.h"
+#include "common/nwc/mss_scb_nwc_regs.h"
+#include "common/nwc/mss_scb_nwc_regs.h"
+/*
+ * mss_sw_config.h may be edited as required and should be located outside the
+ * mpfs_hal folder
+ */
+#include "mpfs_hal_config/mss_sw_config.h"
+/*
+ * The hw_platform.h is included here only. It must be included after
+ * mss_sw_config.h. This allows defines in hw_platform.h be overload from
+ * mss_sw_config.h if necessary.
+ * */
+#include "common/atomic.h"
+#include "common/bits.h"
+#include "common/encoding.h"
+#include "fpga_design_config/fpga_design_config.h"
+#include "common/nwc/mss_ddr.h"
+#include "common/mss_clint.h"
+#include "common/mss_h2f.h"
+#include "common/mss_hart_ints.h"
+#include "common/mss_mpu.h"
+#include "common/mss_pmp.h"
+#include "common/mss_plic.h"
+#include "common/mss_seg.h"
+#include "common/mss_sysreg.h"
+#include "common/mss_util.h"
+#include "common/mss_mtrap.h"
+#include "common/mss_l2_cache.h"
+#include "common/mss_axiswitch.h"
+#include "common/mss_peripherals.h"
+#include "common/nwc/mss_cfm.h"
+#include "common/nwc/mss_ddr.h"
+#include "common/nwc/mss_sgmii.h"
+#include "startup_gcc/system_startup.h"
+#include "common/nwc/mss_ddr_debug.h"
+#ifdef SIMULATION_TEST_FEEDBACK
+#include "nwc/simulation.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_HAL_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/readme.md b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/readme.md
new file mode 100644
index 00000000..f2ad5816
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/readme.md
@@ -0,0 +1,121 @@
+===============================================================================
+# mpfs_hal
+===============================================================================
+
+The PolarFire-SoC MSS HAL provides the initial boot code, interrupt handling,
+and hardware access methods for the MPFS MSS. The terms PolarFire-SoC HAL and
+MPFS HAL are used interchangeably but in the main the term PolarFire-SoC MSS HAL
+is preferred.
+The PolarFire-SoC MSS hal is a combination of C and assembly source code.
+
+The mpfs_hal folder is included in an PolarFire Embedded project under the
+platform directory.
+
+It contains :
+
+* Start-up code executing from reset
+* Interrupt handling support
+* Exception handling support
+* Memory protection configuration, PMP and MPU
+* DDR configuration
+* SGMII configuration
+* MSSIO setup
+
+## Inputs to the mss_hal
+There are two configuration sources.
+
+1. Libero design
+
+ Libero input through header files located in the config/hardware under the
+ platform directory. These files are generated using the PF SoC embedded
+ software configuration generator. It takes an xml file generated in the Libero
+ design flow and produces header files based on the xml content in a suitable
+ form for consumption by the hal.
+
+2. Software configuration
+ Software configuration settings are located in the mpfs_hal_config folder.
+
+
+### Example Project directory structure, showing where mpfs_hal folder sits.
+
+~~~~
+
+ +---------+
+ | project |
+ +----+----+ +---------+ +-----------+
+ +-----+| src |----->|application|
+ +---------+ | +-----------+
+ |
+ | +-----------+
+ +-->|boards |
+ + +----+------+
+ | | +---------------+
+ | +---------+|icicle-kit-es |
+ | +---+-----------+
+ | |
+ | | +---------------+
+ | +->|platform_config|
+ | | +---------------+
+ | |
+ | | +---------------+
+ | |---------|drivers_config |
+ | | +---------------+
+ | |
+ | | +---------------+
+ | |---------|linker |
+ | | +---------------+
+ | |
+ | | +---------------+
+ | |---------|mpfs_hal_config|
+ | | +---------------+
+ | |
+ | |
+ | | +---------------+
+ | +>|soc_config |
+ | | +---+-----------+
+ | | |
+ | | | +---------------+------------------------+
+ | | +->|multiple folders with fpga config for sw|
+ | | +----------------------------------------+
+ | |
+ | |
+ | |
+ | | +---------------+
+ | +>|soc_fpga_design|
+ | +--+------------+
+ | |
+ | | +---------------+
+ | +-->|libero_tcl |
+ | | +---------------+
+ | |
+ | +-----------+ | +---------------+
+ +--+|middleware + +-->|xml |
+ | +-----------+ +---------------+
+ |
+ +
+ | +-----------+
+ +--+|platform |
+ +----+------+
+ | +---------------+
+ +---------+|drivers |
+ | +---------------+
+ |
+ | +---------------+
+ +---------+|hal |
+ | +---------------+
+ |
+ | +---------------+
+ +---------+|mpfs_hal |
+ | +---------------+
+ |
+ | +-------------------------+
+ +---------+|platform_config_reference|
+ | +-------------------------+
+ |
+ | +---------------------+
+ +---------+|soc_config_generator |
+ +---------------------+
+~~~~
+
+Please see the user guide for further details on
+use.
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/mss_entry.S b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/mss_entry.S
new file mode 100644
index 00000000..62caf72a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/mss_entry.S
@@ -0,0 +1,658 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file entry.S
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief entry functions.
+ *
+ */
+
+#include "../common/bits.h"
+#include "../common/encoding.h"
+#include "../common/mss_mtrap.h"
+#include "system_startup_defs.h"
+#include "mpfs_hal_config/mss_sw_config.h"
+
+ .option norvc
+ .section .text.init,"ax", %progbits
+ .globl reset_vector
+ .globl _start
+
+reset_vector:
+_start:
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+ /*
+ * clear the Return Address Stack
+ */
+ call .clear_ras
+ /* Setup trap handler */
+ la a4, trap_vector
+ csrw mtvec, a4 # initalise machine trap vector address
+ /* Make sure that mtvec is updated before continuing */
+ 1:
+ csrr a5, mtvec
+ bne a4, a5, 1b
+ /* Disable and clear all interrupts */
+ li a2, MSTATUS_MIE
+ csrc mstatus, a2 # clear interrupt enable bit
+ csrw mie, zero
+ csrw mip, zero
+ # Init delegation registers, mideleg, medeleg, if a U54
+ # These are not initialised by the hardware and come up in a random state
+ csrr a0, mhartid
+ beqz a0, .skip_e51
+ csrw mideleg, 0
+ csrw medeleg, 0
+.skip_e51:
+ # mscratch must be init to zero- we are not using scratch memory
+ csrw mscratch, zero
+ csrw mcause, zero
+ csrw mepc, zero
+ /*
+ * clear PMP enables
+ */
+ csrw pmpcfg0, zero
+ csrw pmpcfg2, zero
+ /*
+ * clear regs
+ */
+ li x1, 0
+ li x2, 0
+ li x3, 0
+ li x4, 0
+ li x5, 0
+ li x6, 0
+ li x7, 0
+ li x8, 0
+ li x9, 0
+ li x10,0
+ li x11,0
+ li x12,0
+ li x13,0
+ li x14,0
+ li x15,0
+ li x16,0
+ li x17,0
+ li x18,0
+ li x19,0
+ li x20,0
+ li x21,0
+ li x22,0
+ li x23,0
+ li x24,0
+ li x25,0
+ li x26,0
+ li x27,0
+ li x28,0
+ li x29,0
+ li x30,0
+ li x31,0
+
+ # enable FPU and accelerator if present, setting ignored on E51
+ li t0, MSTATUS_FS | MSTATUS_XS
+ csrs mstatus, t0
+
+ # Init floating point control register to zero
+ # skip if e51
+ csrr a0, mhartid
+ beqz a0, .no_float
+#ifdef __riscv_flen
+ fscsr x0
+#endif
+.no_float:
+
+ # make sure XLEN agrees with compilation choice, if not will loop here
+.LxlenCheck:
+ csrr t0, misa
+#if __riscv_xlen == 64
+ bltz t0, .LxlenPass
+#else
+ bgez t0, .LxlenPass
+#endif
+ j .LxlenCheck
+.LxlenPass:
+
+ # initialize global pointer, global data
+ # The __global_pointer is allocated in the linker script. It points to a
+ # location 2k after sdata start as the offsets used in the gp are +/- 2k
+ # See https://www.sifive.com/blog/2017/08/28/all-aboard-part-3-linker-relaxation-in-riscv-toolchain/
+ # see: http://www.rowleydownload.co.uk/arm/documentation/gnu/as/RISC_002dV_002dDirectives.html
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+
+ # get core id
+ csrr a0, mhartid
+ li a1, 0
+ beq a0, a1, .hart0
+ li a1, 1
+ beq a0, a1, .hart1
+ li a1, 2
+ beq a0, a1, .hart2
+ li a1, 3
+ beq a0, a1, .hart3
+ li a1, 4
+ beq a0, a1, .hart4
+
+.hart0:
+ la a4, __stack_bottom_h0$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h0$
+ j .continue
+.hart1:
+ la a4, __stack_bottom_h1$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h1$
+ j .continue
+.hart2:
+ la a4, __stack_bottom_h2$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h2$
+ j .continue
+.hart3:
+ la a4, __stack_bottom_h3$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h3$
+ j .continue
+.hart4:
+ la a4, __stack_bottom_h4$ # keep bottom of stack in a5 so we can init later
+ la sp, __stack_top_h4$
+
+.continue:
+ # clear HLS and stack
+ mv a5, sp
+.init_stack:
+ #csrw mepc, zero
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, .init_stack
+ # Allocate some space at top of stack for the HLS
+ addi sp, sp, -HLS_DEBUG_AREA_SIZE
+ # HLS grows up from new top of stack
+ mv tp, sp
+ # get core id
+ csrr a0, mhartid
+ li a1, MPFS_HAL_FIRST_HART
+ bne a0, a1, .LOtherHartstoWFI
+ # clear the common heap
+ la a4, __heap_start
+ la a5, __heap_end
+.init_heap:
+ #csrw mepc, zero
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, .init_heap
+ #
+ # clear DTIM - this is required to stop memory errors on initial access by
+ # cache
+ # Also, stops x propagation in simulation, when cache/stack reads unused
+ # area
+ #
+ li a2, MPFS_HAL_CLEAR_MEMORY
+ beq x0, a2, .skip_mem_clear
+ call .clear_dtim
+ call .clear_l2lim
+.skip_mem_clear:
+ /*
+ * Clear bus error unit accrued register on start-up
+ * This is cleared by the first hart only
+ */
+ la a4,0x01700020UL
+ sb x0, 0(a4)
+ la a4,0x01701020UL
+ sb x0, 0(a4)
+ la a4,0x01702020UL
+ sb x0, 0(a4)
+ la a4,0x01703020UL
+ sb x0, 0(a4)
+ la a4,0x01704020UL
+ sb x0, 0(a4)
+ # now core MPFS_HAL_FIRST_HART jumps to main_first_hart
+.main_hart:
+ # pass HLS address
+ mv a0, tp
+ j main_first_hart
+.LoopForeverMain:
+ #in case of return, loop forever. nop's added so can be seen in debugger
+ nop
+ nop
+ j .LoopForeverMain
+
+.LOtherHartstoWFI:
+ li a2, MSTATUS_MIE
+ csrc mstatus, a2 # clear interrupt enable bit
+ csrw mie, zero
+ csrw mip, zero
+ li a2, MIP_MSIP
+ csrw mie, a2 # Set MSIE bit to receive IPI. This needs to be
+ # enabled- otherwise stays in wfi.
+ # Other interrupts appera to bring out of wfi,even if
+ # not enabled.
+ #
+ # Wait here until main hart is up and running
+ #
+ li a3, HLS_MAIN_HART_STARTED
+ la a1, (__stack_top_h0$ - HLS_DEBUG_AREA_SIZE)
+.wait_main_hart:
+ LWU a2, 0(a1)
+ bne a3, a2, .wait_main_hart
+ # Flag we are here to the main hart
+ li a1, HLS_OTHER_HART_IN_WFI
+ sw a1, 0(tp)
+ /* flush the instruction cache */
+ fence.i
+.LwaitOtherHart:
+ # We assume wfi instruction will be run before main hart attampts to take
+ # out of wfi
+ wfi
+ # Only start if MIP_MSIP is set - the wfi will ensure this, but adding
+ # breakpoints in the debugger (halt)
+ # will wakeup wfi, so the following code will make sure we remain here until
+ # we get a software interrupt
+ csrr a2, mip
+ andi a2, a2, MIP_MSIP
+ beqz a2, .LwaitOtherHart
+ /* Disable and clear all interrupts- should be only a sw interrupt */
+ li a2, MSTATUS_MIE
+ csrc mstatus, a2 # clear interrupt enable bit
+ csrw mie, zero
+ csrw mip, zero
+ # set marker as to where we are
+ li a1, HLS_OTHER_HART_PASSED_WFI
+ sw a1, 0(tp)
+ # pass HLS address
+ mv a0, tp
+ j main_other_hart
+.LoopForeverOther:
+ #in case of return, loop forever. nop's added so can be seen in debugger
+ nop
+ nop
+ j .LoopForeverOther
+
+#else /* IMAGE_LOADED_BY_BOOTLOADER == 1 */
+
+/***********************************************************************************
+ *The program has been loaded by a bootloader
+ * a0 - contains the hart ID
+ * a1 - contains pointer to bootloader -Hart Local Storage, for this hart.
+ */
+_start_non_bootloader_image:
+ /* ebreak called at the start of the program if required when debuging. */
+ /* DEBUG_EBREAK_AT_START is set to one in the debug build, 0 in the */
+ /* release build */
+ /* uncomment the 3 lines below if you want to use this method to for */
+ /* debugging */
+ /* li a2, DEBUG_EBREAK_AT_START
+ beq x0, a2, 1f
+ ebreak */
+1:
+ /* store the value here received from boot-loader */
+ /* a0 will always contain the hart ID */
+ /* If a1 is null, boot-loader is not passing pointer to the HLS */
+ /* If this is the case, point HLS to out own and fill with hart ID */
+ /* Setup trap handler */
+ /* we are currently only supporting mmode */
+ /* m-mode/s-mode set-up option will be added here */
+ la a4, trap_vector
+ csrw mtvec, a4 # initalise machine trap vector address
+ /* Make sure that mtvec is updated before continuing */
+2:
+ csrr a5, mtvec
+ bne a4, a5, 2b
+ /* Disable and clear all interrupts */
+ /* assumption is this has been done by the Boot-loader */
+ # Init delegation registers, mideleg, medeleg, if a U54
+ # These are not initialised by the hardware and come up in a random state
+ # mhartid is in a0
+ beqz a0, 3f
+ csrw mideleg, 0
+ csrw medeleg, 0
+3:
+ # mscratch must be init to zero- we are not using scratch memory
+ csrw mscratch, zero
+ csrw mcause, zero
+ csrw mepc, zero
+
+ # Init floating point control register to zero
+ # skip if e51
+ # mhartid is in a0
+ beqz a0, 1f
+#ifdef __riscv_flen
+ fscsr x0
+#endif
+1: # no float
+ # make sure XLEN agrees with compilation choice, if not will loop here
+ csrr t0, misa
+#if __riscv_xlen == 64
+ bltz t0, 2f
+#else
+ bgez t0, 2f
+#endif
+ j 1b
+2:
+ # initialize global pointer, global data
+ # The __global_pointer is allocated in the linker script. It points to a
+ # location 2k after sdata start as the offsets used in the gp are +/- 2k
+ # See https://www.sifive.com/blog/2017/08/28/all-aboard-part-3-linker-relaxation-in-riscv-toolchain/
+ # see: http://www.rowleydownload.co.uk/arm/documentation/gnu/as/RISC_002dV_002dDirectives.html
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+
+ la a4, __app_stack_bottom # keep bottom of stack in a5 so we can init later
+ la a5, __app_stack_top
+ la sp, __app_stack_top
+1:
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, 1b
+ # clear the common heap
+ la a4, __heap_start
+ la a5, __heap_end
+2:
+ STORE x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, 2b
+ # check if HLS passed by BL, if not allocate one here
+ bnez a1, 1f
+ # Allocate some space at top of stack for the HLS, as HLS mem not passed
+ addi sp, sp, -HLS_DEBUG_AREA_SIZE
+ # HLS grows up from new top of stack
+ mv tp, sp
+ mv a0, tp
+ j u54_single_hart
+1:
+ # pass HLS address from the boot-loader
+ mv a0, a1
+ j u54_single_hart
+2:
+ # in case of return, loop forever. nop's added so can be seen in debugger
+ nop
+ nop
+ j 2b
+#endif /* IMAGE_LOADED_BY_BOOTLOADER */
+
+/******************************************************************************/
+/******************************interrupt handeling below here******************/
+/******************************************************************************/
+
+trap_vector:
+ # The mscratch register is an XLEN-bit read/write register dedicated for use by machine mode.
+ # Typically, it is used to hold a pointer to a machine-mode hart-local context space and swapped
+ # with a user register upon entry to an M-mode trap handler.
+ # In this implementation, we are noty using HLS
+ # csrrw sp, mscratch, sp #copy sp to mscratch, and mscrath to sp
+
+ addi sp, sp, -INTEGER_CONTEXT_SIZE # moves sp down stack to make I
+ # INTEGER_CONTEXT_SIZE area
+ # Preserve the registers.
+ STORE sp, 2*REGBYTES(sp) # sp
+ STORE a0, 10*REGBYTES(sp) # save a0,a1 in the created CONTEXT
+ STORE a1, 11*REGBYTES(sp)
+ STORE ra, 1*REGBYTES(sp)
+ STORE gp, 3*REGBYTES(sp)
+ STORE tp, 4*REGBYTES(sp)
+ STORE t0, 5*REGBYTES(sp)
+ STORE t1, 6*REGBYTES(sp)
+ STORE t2, 7*REGBYTES(sp)
+ STORE s0, 8*REGBYTES(sp)
+ STORE s1, 9*REGBYTES(sp)
+ STORE a2,12*REGBYTES(sp)
+ STORE a3,13*REGBYTES(sp)
+ STORE a4,14*REGBYTES(sp)
+ STORE a5,15*REGBYTES(sp)
+ STORE a6,16*REGBYTES(sp)
+ STORE a7,17*REGBYTES(sp)
+ STORE s2,18*REGBYTES(sp)
+ STORE s3,19*REGBYTES(sp)
+ STORE s4,20*REGBYTES(sp)
+ STORE s5,21*REGBYTES(sp)
+ STORE s6,22*REGBYTES(sp)
+ STORE s7,23*REGBYTES(sp)
+ STORE s8,24*REGBYTES(sp)
+ STORE s9,25*REGBYTES(sp)
+ STORE s10,26*REGBYTES(sp)
+ STORE s11,27*REGBYTES(sp)
+ STORE t3,28*REGBYTES(sp)
+ STORE t4,29*REGBYTES(sp)
+ STORE t5,30*REGBYTES(sp)
+ STORE t6,31*REGBYTES(sp)
+ # Invoke the handler.
+ mv a0, sp # a0 <- regs
+ # Please note: mtval is the newer name for register mbadaddr
+ # If you get a compile failure here, use the newer name
+ # At this point (2019), both are supported in latest compiler
+ # older compiler versions only support mbadaddr, so going with this.
+ # See: https://github.com/riscv/riscv-gcc/issues/133
+ csrr a1, mbadaddr # useful for anaysis when things go wrong
+ csrr a2, mepc
+ jal trap_from_machine_mode
+
+restore_regs:
+ # Restore all of the registers.
+ LOAD ra, 1*REGBYTES(sp)
+ LOAD gp, 3*REGBYTES(sp)
+ LOAD tp, 4*REGBYTES(sp)
+ LOAD t0, 5*REGBYTES(sp)
+ LOAD t1, 6*REGBYTES(sp)
+ LOAD t2, 7*REGBYTES(sp)
+ LOAD s0, 8*REGBYTES(sp)
+ LOAD s1, 9*REGBYTES(sp)
+ LOAD a0,10*REGBYTES(sp)
+ LOAD a1,11*REGBYTES(sp)
+ LOAD a2,12*REGBYTES(sp)
+ LOAD a3,13*REGBYTES(sp)
+ LOAD a4,14*REGBYTES(sp)
+ LOAD a5,15*REGBYTES(sp)
+ LOAD a6,16*REGBYTES(sp)
+ LOAD a7,17*REGBYTES(sp)
+ LOAD s2,18*REGBYTES(sp)
+ LOAD s3,19*REGBYTES(sp)
+ LOAD s4,20*REGBYTES(sp)
+ LOAD s5,21*REGBYTES(sp)
+ LOAD s6,22*REGBYTES(sp)
+ LOAD s7,23*REGBYTES(sp)
+ LOAD s8,24*REGBYTES(sp)
+ LOAD s9,25*REGBYTES(sp)
+ LOAD s10,26*REGBYTES(sp)
+ LOAD s11,27*REGBYTES(sp)
+ LOAD t3,28*REGBYTES(sp)
+ LOAD t4,29*REGBYTES(sp)
+ LOAD t5,30*REGBYTES(sp)
+ LOAD t6,31*REGBYTES(sp)
+ LOAD sp, 2*REGBYTES(sp)
+ addi sp, sp, +INTEGER_CONTEXT_SIZE # moves sp up stack to reclaim
+ # INTEGER_CONTEXT_SIZE area
+ mret
+
+ /*****************************************************************************/
+ /******************************interrupt handeling above here*****************/
+ /*****************************************************************************/
+
+.enable_sw_int:
+ li a2, MIP_MSIP
+ csrw mie, a2 # Set MSIE bit to receive IPI
+ li a2, MSTATUS_MIE
+ csrs mstatus, a2 # enable interrupts
+ /* flush the instruction cache */
+ fence.i
+ ret
+
+ /***********************************************************************************
+ *
+ * The following init_memory() symbol overrides the weak symbol in the HAL and does
+ * a safe copy of RW data and clears zero-init memory
+ *
+ */
+ // zero_section helper function:
+ // a0 = exec_start_addr
+ // a1 = exec_end_addr
+ //
+ .globl zero_section
+ .type zero_section, @function
+zero_section:
+ bge a0, a1, .zero_section_done
+ sd zero, (a0)
+ addi a0, a0, 8
+ j zero_section
+.zero_section_done:
+ ret
+
+ // zero_section helper function:
+ // a0 = exec_start_addr
+ // a1 = exec_end_addr
+ // a2 = start count
+ //
+ .globl count_section
+ .type count_section, @function
+count_section:
+ beq a0, a1, .count_section_done
+ sd a2, (a0)
+ addi a0, a0, 8
+ addi a2, a2, 8
+ j count_section
+.count_section_done:
+ ret
+
+ // copy_section helper function:
+ // a0 = load_addr
+ // a1 = exec_start_addr
+ // a2 = exec_end_addr
+ .globl copy_section
+ .type copy_section, @function
+copy_section:
+ beq a1, a0, .copy_section_done // if load_addr == exec_start_addr, goto copy_section_done
+.check_if_copy_section_done:
+ beq a1, a2, .copy_section_done // if offset != length, goto keep_copying
+.keep_copying:
+ ld a3, 0(a0) // val = *load_addr
+ sd a3, 0(a1) // *exec_start_addr = val;
+ addi a0, a0, 8 // load_addr = load_addr + 8
+ addi a1, a1, 8 // exec_start_addr = exec_start_addr + 8
+ j .check_if_copy_section_done
+.copy_section_done:
+ ret
+
+
+/***********************************************************************************
+ *
+ * The following copy_switch_code() symbol overrides the weak symbol in the HAL and does
+ * a safe copy of HW config data
+ */
+ .globl copy_switch_code
+ .type copy_switch_code, @function
+copy_switch_code:
+ la a5, __sc_start // a5 = __sc_start
+ la a4, __sc_load // a4 = __sc_load
+ beq a5,a4,.copy_switch_code_done // if a5 == a4, goto copy_switch_code_done
+ la a3, __sc_end // a3 = __sc_end
+ beq a5,a3,.copy_switch_code_done // if a5 == a3, goto copy_switch_code_done
+.copy_switch_code_loop:
+ lw a2,0(a4) // a2 = *a4
+ sw a2,0(a5) // *a5 = a2
+ addi a5,a5,4 // a5+=4
+ addi a4,a4,4 // a4+=4
+
+ bltu a5,a3,.copy_switch_code_loop // if a5 < a3, goto copy_switch_code_loop
+.copy_switch_code_done:
+ ret
+
+/*******************************************************************************
+ *
+ */
+#define START__OF_LIM 0x08000000
+#define END__OF_LIM 0x08200000
+#define START__OF_DTM 0x01000000
+#define END__OF_DTM 0x01002000
+
+
+.clear_l2lim:
+ // Clear the LIM
+ //
+ // On reset, the first 15 ways are L2 and the last way is cache
+ // We can initialize all, as cache write through to DDR is blocked
+ // until DDR in initialized, so will have no effect other than clear ECC
+ //
+ // NOTE: we need to check if we are debugging from LIM,if so do not
+ // initialize.
+ //
+ la a2, _start
+ la a4, 0x08000000 # start of LIM address
+ and a2, a2, a4
+ bnez a2, .done_clear
+ la a5, 0x08200000 # end of LIM address
+ j 1f
+.clear_dtim:
+ //
+ // Clear the E51 DTIM to prevent any ECC memory errors on initial access
+ //
+ la a4, 0x01000000 # DTIM start
+ la a5, 0x01002000 # DTIM end
+1:
+ // common loop used by both .clear_l2lim and .clear_dtim
+ sd x0, 0(a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, 1b
+.done_clear:
+ ret
+
+/*
+ * record_ecc_error_counts on reset
+ * These are non-zero in the coreplex.
+ * Can be checked later on to see if values have changed
+ * a0 = mECCDataFailCount save address
+ a1 = mECCDataCorrectionCount save address
+ a2 = mECCDirFixCount save address
+ */
+.record_ecc_error_counts:
+ # Store initial ECC errors
+ #define mECCDataFailCount 0x02010168U
+ la a5, mECCDataFailCount
+ mv a4, a0// eg. Use stat of DTIM in not used for anything else 0x01000100
+ lw t2,0(a5)
+ sw t2,0(a4)
+ #define mECCDataCorrectionCount 0x02010148U
+ la a5, mECCDataCorrectionCount
+ mv a4, a1// eg. Use stat of DTIM in not used for anything else 0x01000110
+ lw t2,0(a5)
+ sw t2,0(a4)
+ #define mECCDirFixCount 0x02010108u
+ la a5, mECCDirFixCount
+ mv a4, a2// eg. Use stat of DTIM in not used for anything else 0x01000120
+ lw t2,0(a5)
+ sw t2,0(a4)
+ ret
+
+/*
+ * clear_ras , clear_ras_2_deep
+ * Two deep function calls.
+ * Used to clear the interal processor Return Address Stack
+ * This is belt and braces, may not be required
+ */
+.clear_ras:
+ mv a5, x1
+ nop
+ call .clear_ras_2_deep
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ mv x1, a5
+ ret
+
+.clear_ras_2_deep:
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ ret
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/mss_utils.S b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/mss_utils.S
new file mode 100644
index 00000000..482d4b61
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/mss_utils.S
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright 2021 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_utils.S
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief utilities used by mpfs-hal startup code
+ *
+ */
+ .section .text.init,"ax", %progbits
+ .align 3
+
+/***********************************************************************************
+ *
+ * pdma_transfer
+ * Only used by the mpfs hal. App code uses the provided driver.
+ *
+ * a0 = dest
+ * a1 = src
+ * a2 = length
+ * a3 = PDMA Base Address - 0x3000000 + (0x01000 * PDMA_CHANNEL)
+ */
+ .globl pdma_transfer
+ .type pdma_transfer, @function
+pdma_transfer:
+ mv t1,a0
+ mv t0, a3 // Base address
+ li t1, 1
+ sw t1, 0(t0) // claim
+ li t1, 0
+ sw t1, 4(t0) // read[31:28]/write[27:24] size 0=>1byte, 1 =>2 bytes etx
+ mv t1, a2 // SIZE
+ sd t1, 8(t0) // bytes
+ mv t1, a0 // dest address
+ sd t1, 16(t0) // dest
+ mv t1, a1 // source address
+ sd t1, 24(t0) // src
+ li t1, 0xff000000
+ sw t1, 4(t0) // full speed copy
+ li t1, 3
+ sw t1, 0(t0) // start transfer
+ fence
+ ret
+
+/***********************************************************************************
+ *
+ * pdma_transfer_complete
+ * Loops until transfer complete
+ * Only used by the mpfs hal. App code uses the provided driver.
+ *
+ * a0 = PDMA Base Address - 0x3000000 + (0x01000 * PDMA_CHANNEL)
+ */
+ //
+ .globl pdma_transfer_complete
+ .type pdma_transfer_complete, @function
+pdma_transfer_complete:
+ mv t0, a0 // Base address
+1: // wait for completion
+ lw t1, 0(t0)
+ andi t1, t1, 2
+ bnez t1, 1b
+ // release DMA
+ sw zero, 0(t0)
+ ret
+
+
+ /***********************************************************************************
+ *
+ * memfill() - fills memory, alternate to lib function when not available
+ */
+ // memfill helper function:
+ // a0 = dest
+ // a1 = value to fill
+ // a2 = length
+ .globl memfill
+ .type memfill, @function
+memfill:
+ mv t1,a0
+ mv t2,a1
+ beqz a2,2f
+1:
+ sb t2,0(t1)
+ addi a2,a2,-1
+ addi t1,t1,1
+ bnez a2,1b
+2:
+ ret
+
+/***********************************************************************************
+ *
+ * The following config_copy() symbol overrides the weak symbol in the HAL and does
+ * a safe copy of HW config data
+ */
+ // config_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_copy
+ .type config_copy, @function
+config_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ lb t2,0(a1)
+ sb t2,0(t1)
+ addi a2,a2,-1
+ addi t1,t1,1
+ addi a1,a1,1
+ bnez a2,1b
+2:
+ ret
+
+ /***********************************************************************************
+ *
+ * config_16_copy () Copies a word at a time, used when copying to contigous registers
+ */
+ // config_16_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_16_copy
+ .type config_16_copy, @function
+config_16_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ lh t2,0(a1)
+ sh t2,0(t1)
+ addi a2,a2,-2
+ addi t1,t1,2
+ addi a1,a1,2
+ bnez a2,1b
+2:
+ ret
+
+/***********************************************************************************
+ *
+ * config_32_copy () Copies a word at a time, used when copying to contigous registers
+ */
+ // config_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_32_copy
+ .type config_32_copy, @function
+config_32_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ lw t2,0(a1)
+ sw t2,0(t1)
+ addi a2,a2,-4
+ addi t1,t1,4
+ addi a1,a1,4
+ bnez a2,1b
+2:
+ ret
+
+ /***********************************************************************************
+ *
+ * config_64_copy - copying using 64 bit loads, addresses must be on 64 bit boundary
+ */
+ // config_64_copy helper function:
+ // a0 = dest
+ // a1 = src
+ // a2 = length
+ .globl config_64_copy
+ .type config_64_copy, @function
+config_64_copy:
+ mv t1,a0
+ beqz a2,2f
+1:
+ ld t2,0(a1)
+ sd t2,0(t1)
+ addi a2,a2,-8
+ addi t1,t1,8
+ addi a1,a1,8
+ bnez a2,1b
+2:
+ ret
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/newlib_stubs.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/newlib_stubs.c
new file mode 100644
index 00000000..0ed8513d
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/newlib_stubs.c
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ * @file newlib_stubs.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Stubs for Newlib system calls.
+ *
+ */
+#include
+#include
+#include
+#include
+#include
+#include "../mss_hal.h"
+
+/*==============================================================================
+ * Redirection of standard output to a SmartFusion2 MSS UART.
+ *------------------------------------------------------------------------------
+ * A default implementation for the redirection of the output of printf() to a
+ * UART is provided at the bottom of this file. This redirection is enabled by
+ * adding the symbol/define MICROCHIP_STDIO_THRU_MMUART0 or
+ * MICROCHIP_STDIO_THRU_MMUART0 to your project settings and specifying the baud
+ * rate using the MICROCHIP_STDIO_BAUD_RATE define.
+ */
+#ifdef MICROCHIP_STDIO_THRU_MMUART0
+#ifndef MICROCHIP_STDIO_THRU_UART
+#define MICROCHIP_STDIO_THRU_UART
+#endif
+#endif /* MICROCHIP_STDIO_THRU_MMUART0 */
+
+#ifdef MICROCHIP_STDIO_THRU_MMUART1
+#ifndef MICROCHIP_STDIO_THRU_UART
+#define MICROCHIP_STDIO_THRU_UART
+#endif
+#endif /* MICROCHIP_STDIO_THRU_MMUART1 */
+
+/*
+ * Select which MMUART will be used for stdio and what baud rate will be used.
+ * Default to 57600 baud if no baud rate is specified using the
+ * MICROCHIP_STDIO_BAUD_RATE #define.
+ */
+#ifdef MICROCHIP_STDIO_THRU_UART
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+#ifndef MICROCHIP_STDIO_BAUD_RATE
+#define MICROCHIP_STDIO_BAUD_RATE MSS_UART_115200_BAUD
+#endif
+
+#ifdef MICROCHIP_STDIO_THRU_MMUART0
+static mss_uart_instance_t * const gp_my_uart = &g_mss_uart0;
+#else
+static mss_uart_instance_t * const gp_my_uart = &g_mss_uart1;
+#endif
+
+/*------------------------------------------------------------------------------
+ * Global flag used to indicate if the UART driver needs to be initialized.
+ */
+static int g_stdio_uart_init_done = 0;
+
+#endif /* MICROCHIP_STDIO_THRU_UART */
+
+/*==============================================================================
+ * Environment variables.
+ * A pointer to a list of environment variables and their values. For a minimal
+ * environment, this empty list is adequate:
+ */
+char *__env[1] = { 0 };
+char **environ = __env;
+
+
+/*==============================================================================
+ * Close a file.
+ */
+int _close(int file);
+int _close(int file)
+{
+ (void)file;
+ return -1;
+}
+
+/*==============================================================================
+ * Transfer control to a new process.
+ */
+int _execve(char *name, char **argv, char **env);
+int _execve(char *name, char **argv, char **env)
+{
+ (void)name;
+ (void)argv;
+ (void)env;
+ errno = ENOMEM;
+ return -1;
+}
+
+/*==============================================================================
+ * Exit a program without cleaning up files.
+ */
+void _exit( int code )
+{
+ (void)code;
+ /* Should we force a system reset? */
+ while( 1 )
+ {
+ ;
+ }
+}
+
+/*==============================================================================
+ * Create a new process.
+ */
+int _fork(void);
+int _fork(void)
+{
+ errno = EAGAIN;
+ return -1;
+}
+
+/*==============================================================================
+ * Status of an open file.
+ */
+int _fstat(int file, struct stat *st);
+int _fstat(int file, struct stat *st)
+{
+ (void)file;
+ st->st_mode = S_IFCHR;
+ return (0);
+}
+
+/*==============================================================================
+ * Process-ID
+ */
+int _getpid(void);
+int _getpid(void)
+{
+ return (1);
+}
+
+/*==============================================================================
+ * Query whether output stream is a terminal.
+ */
+int _isatty(int file);
+int _isatty(int file)
+{
+ (void)file;
+ return (1);
+}
+
+/*==============================================================================
+ * Send a signal.
+ */
+int _kill(int pid, int sig);
+int _kill(int pid, int sig)
+{
+ (void)pid;
+ (void)sig;
+ errno = EINVAL;
+ return (-1);
+}
+
+/*==============================================================================
+ * Establish a new name for an existing file.
+ */
+int _link(char *old, char *new);
+int _link(char *old, char *new)
+{
+ (void)old;
+ (void)new;
+ errno = EMLINK;
+ return (-1);
+}
+
+/*==============================================================================
+ * Set position in a file.
+ */
+int _lseek(int file, int ptr, int dir);
+int _lseek(int file, int ptr, int dir)
+{
+ (void)file;
+ (void)ptr;
+ (void)dir;
+ return (0);
+}
+
+/*==============================================================================
+ * Open a file.
+ */
+int _open(const char *name, int flags, int mode);
+int _open(const char *name, int flags, int mode)
+{
+ (void)name;
+ (void)flags;
+ (void)mode;
+ return (-1);
+}
+
+/*==============================================================================
+ * Read from a file.
+ */
+int _read(int file, char *ptr, int len);
+int _read(int file, char *ptr, int len)
+{
+ (void)file;
+ (void)ptr;
+ (void)len;
+ return (0);
+}
+
+/*==============================================================================
+ * Write to a file. libc subroutines will use this system routine for output to
+ * all files, including stdout so if you need to generate any output, for
+ * example to a serial port for debugging, you should make your minimal write
+ * capable of doing this.
+ */
+int _write_r( void * reent, int file, char * ptr, int len );
+int _write_r( void * reent, int file, char * ptr, int len )
+{
+ (void)reent;
+ (void)file;
+ (void)ptr;
+ (void)len;
+#ifdef MICROCHIP_STDIO_THRU_UART
+ /*--------------------------------------------------------------------------
+ * Initialize the UART driver if it is the first time this function is
+ * called.
+ */
+ if(!g_stdio_uart_init_done)
+ {
+ MSS_UART_init(gp_my_uart,
+ MICROCHIP_STDIO_BAUD_RATE,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY);
+
+ g_stdio_uart_init_done = 1;
+ }
+
+ /*--------------------------------------------------------------------------
+ * Output text to the UART.
+ */
+ MSS_UART_polled_tx(gp_my_uart, (uint8_t *)ptr, len);
+
+ return len;
+#else /* MICROCHIP_STDIO_THRU_UART */
+ return (0);
+#endif /* MICROCHIP_STDIO_THRU_UART */
+}
+
+/*==============================================================================
+ * Increase program data space. As malloc and related functions depend on this,
+ * it is useful to have a working implementation. The following suffices for a
+ * standalone system; it exploits the symbol _end automatically defined by the
+ * GNU linker.
+ */
+caddr_t _sbrk(int incr);
+caddr_t _sbrk(int incr)
+{
+ extern char _end; /* Defined by the linker */
+ extern char __heap_start;
+ extern char __heap_end;
+ static char *heap_end;
+ char *prev_heap_end;
+
+ (void)__heap_start;
+ (void)__heap_end;
+#ifdef DEBUG_HEAP_SIZE
+ char * stack_ptr = NULL;
+#endif
+
+ /*
+ * Did we allocated memory for the heap in the linker script?
+ * You need to set HEAP_SIZE to a non-zero value in your linker script if
+ * the following assertion fires.
+ */
+ ASSERT(&__heap_end > &__heap_start);
+
+ if (heap_end == NULL)
+ {
+ heap_end = &_end;
+ }
+
+ prev_heap_end = heap_end;
+
+#ifdef DEBUG_HEAP_SIZE /* add this define if you want to debug crash due to overflow of heap */
+ /* fixme- this test needs to be reworked to take account of multiple harts and TLS */
+ stack_ptr = read_csr(sp);
+ /* stack_ptr has just been placed on the stack, so its address in currently pointing to the stack end */
+ if(heap_end < stack_ptr)
+ {
+ /*
+ * Heap is at an address below the stack, growing up toward the stack.
+ * The stack is above the heap, growing down towards the heap.
+ * Make sure the stack and heap do not run into each other.
+ */
+ if (heap_end + incr > stack_ptr)
+ {
+ _write_r ((void *)0, 1, "Heap and stack collision\n", 25);
+ _exit (1);
+ }
+ }
+ else
+ {
+ /*
+ * If the heap and stack are not growing towards each other then use the
+ * _eheap linker script symbol to figure out if there is room left on
+ * the heap.
+ * Please note that this use case makes sense when the stack is located
+ * in internal eSRAM in the 0x20000000 address range and the heap is
+ * located in the external memory in the 0xA0000000 memory range.
+ * Please note that external memory should not be accessed using the
+ * 0x00000000 memory range to read/write variables/data because of the
+ * SmartFusion2 cache design.
+ */
+ extern char _heap_end; /* Defined by the linker */
+ char *top_of_heap;
+
+ top_of_heap = &_heap_end;
+ if(heap_end + incr > top_of_heap)
+ {
+ _write_r ((void *)0, 1, "Out of heap memory\n", 25);
+ _exit (1);
+ }
+ }
+#endif
+ heap_end += incr;
+
+ /*
+ * Did we run out of heap?
+ * You need to increase the heap size in the linker script if the following
+ * assertion fires.
+ * */
+ ASSERT(heap_end <= &__heap_end);
+
+ return ((caddr_t) prev_heap_end);
+}
+
+/*==============================================================================
+ * Status of a file (by name).
+ */
+int _stat(char *file, struct stat *st);
+int _stat(char *file, struct stat *st)
+{
+ (void)file;
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+/*==============================================================================
+ * Timing information for current process.
+ */
+int _times(struct tms *buf);
+int _times(struct tms *buf)
+{
+ (void)buf;
+ return (-1);
+}
+
+/*==============================================================================
+ * Remove a file's directory entry.
+ */
+int _unlink(char *name);
+int _unlink(char *name)
+{
+ (void)name;
+ errno = ENOENT;
+ return (-1);
+}
+
+/*==============================================================================
+ * Wait for a child process.
+ */
+int _wait(int *status);
+int _wait(int *status)
+{
+ (void)status;
+ errno = ECHILD;
+ return (-1);
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup.c b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup.c
new file mode 100644
index 00000000..7656c489
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup.c
@@ -0,0 +1,585 @@
+/******************************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+/***************************************************************************
+ * @file system_startup.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief first C code called on startup. Will call user code created outside
+ * the HAL.
+ */
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#ifdef MPFS_HAL_HW_CONFIG
+#include "../common/nwc/mss_nwc_init.h"
+#include "system_startup_defs.h"
+#endif
+
+
+/*==============================================================================
+ * This function is called by the lowest enabled hart (MPFS_HAL_FIRST_HART) in
+ * the configuration file (platform/config/software/mpfs_hal/mss_sw_config.h )
+ *
+ * The other harts up to MPFS_HAL_LAST_HART are placed in wfi at this point.
+ * This function brings them out of wfi in sequence.
+ * If you need to modify this function, create your own one in a user directory
+ * space
+ * e.g. /hart0/e51.c
+ */
+__attribute__((weak)) int main_first_hart(HLS_DATA* hls)
+{
+ uint64_t hartid = read_csr(mhartid);
+
+ if(hartid == MPFS_HAL_FIRST_HART)
+ {
+ uint8_t hart_id;
+ ptrdiff_t stack_top;
+
+ /*
+ * We only use code within the conditional compile
+ * #ifdef MPFS_HAL_HW_CONFIG
+ * if this program is used as part of the initial board bring-up
+ * Please comment/uncomment MPFS_HAL_HW_CONFIG define in
+ * platform/config/software/mpfs_hal/sw_config.h
+ * as required.
+ */
+#ifdef MPFS_HAL_HW_CONFIG
+ config_l2_cache();
+#endif /* MPFS_HAL_HW_CONFIG */
+
+ init_memory();
+#ifndef MPFS_HAL_HW_CONFIG
+ hls->my_hart_id = MPFS_HAL_FIRST_HART;
+#endif
+#ifdef MPFS_HAL_HW_CONFIG
+ load_virtual_rom();
+ (void)init_bus_error_unit();
+ (void)init_mem_protection_unit();
+ (void)init_pmp((uint8_t)MPFS_HAL_FIRST_HART);
+ (void)mss_set_apb_bus_cr((uint32_t)LIBERO_SETTING_APBBUS_CR);
+#endif /* MPFS_HAL_HW_CONFIG */
+ /*
+ * Initialise NWC
+ * Clocks
+ * SGMII
+ * DDR
+ * IOMUX
+ */
+#ifdef MPFS_HAL_HW_CONFIG
+ (void)mss_nwc_init();
+
+ /* main hart init's the PLIC */
+ PLIC_init_on_reset();
+ /*
+ * Start the other harts. They are put in wfi in entry.S
+ * When debugging, harts are released from reset separately,
+ * so we need to make sure hart is in wfi before we try and release.
+ */
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h0$);
+ hls = (HLS_DATA*)(stack_top - HLS_DEBUG_AREA_SIZE);
+ hls->in_wfi_indicator = HLS_MAIN_HART_STARTED;
+ hls->my_hart_id = MPFS_HAL_FIRST_HART;
+ WFI_SM sm_check_thread = INIT_THREAD_PR;
+ hart_id = MPFS_HAL_FIRST_HART + 1U;
+ while( hart_id <= MPFS_HAL_LAST_HART)
+ {
+ uint32_t wait_count = 0U;
+
+ switch(sm_check_thread)
+ {
+ default:
+ case INIT_THREAD_PR:
+
+ switch (hart_id)
+ {
+ case 1:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h1$);
+ break;
+ case 2:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h2$);
+ break;
+ case 3:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h3$);
+ break;
+ case 4:
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h4$);
+ break;
+ }
+ hls = (HLS_DATA*)(stack_top - HLS_DEBUG_AREA_SIZE);
+ sm_check_thread = CHECK_WFI;
+ wait_count = 0U;
+ break;
+
+ case CHECK_WFI:
+ if( hls->in_wfi_indicator == HLS_OTHER_HART_IN_WFI )
+ {
+ /* Separate state- to add a little delay */
+ sm_check_thread = SEND_WFI;
+ }
+ break;
+
+ case SEND_WFI:
+ hls->my_hart_id = hart_id; /* record hartid locally */
+ raise_soft_interrupt(hart_id);
+ sm_check_thread = CHECK_WAKE;
+ wait_count = 0UL;
+ break;
+
+ case CHECK_WAKE:
+ if( hls->in_wfi_indicator == HLS_OTHER_HART_PASSED_WFI )
+ {
+ sm_check_thread = INIT_THREAD_PR;
+ hart_id++;
+ wait_count = 0UL;
+ }
+ else
+ {
+ wait_count++;
+ if(wait_count > 0x10U)
+ {
+ if( hls->in_wfi_indicator == HLS_OTHER_HART_IN_WFI )
+ {
+ hls->my_hart_id = hart_id; /* record hartid locally */
+ raise_soft_interrupt(hart_id);
+ wait_count = 0UL;
+ }
+ }
+ }
+ break;
+ }
+ }
+ stack_top = (ptrdiff_t)((uint8_t*)&__stack_top_h0$);
+ hls = (HLS_DATA*)(stack_top - HLS_DEBUG_AREA_SIZE);
+ hls->in_wfi_indicator = HLS_MAIN_HART_FIN_INIT;
+
+ /*
+ * Turn on fic interfaces by default. Drivers will turn on/off other MSS
+ * peripherals as required.
+ */
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC0, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC1, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC2, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_FIC3, (uint8_t)MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+
+#endif /* MPFS_HAL_HW_CONFIG */
+ (void)main_other_hart(hls);
+ }
+
+ /* should never get here */
+ while(true)
+ {
+ static volatile uint64_t counter = 0U;
+ /* Added some code as debugger hangs if in loop doing nothing */
+ counter = counter + 1U;
+ }
+
+ return (0);
+}
+
+/*==============================================================================
+ * u54_single_hart startup.
+ * This is called when a bootloader has loaded a single hart program.
+ * A pointer to the hart Local Storage (HLS) is passed here which has been
+ * passed by the boot program in the a1 register.
+ * The HLS contains the hartID.
+ * It also contains a pointer to shared memory
+ * Information on the HLS used in the bare metal examples.
+ * The HLS is a small amount of memory dedicated to each hart.
+ * The HLS also contains a pointer to shared memory.
+ * The shared memory is accessible by all harts if used. It is
+ * allocated by the boot-loader if the MPFS_HAL_SHARED_MEM_ENABLED
+ * is defined in the mss_sw_config.h file project configuration file.
+ * Please see the project mpfs-hal-run-from-ddr-u54-1 located in the Bare Metal
+ * library under examples/mpfs-hal for an example of it use.
+ *
+ * https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
+ *
+ * If you need to modify this function, create your own one in a user directory
+ * space
+ * e.g. /hart1/x.c
+ */
+__attribute__((weak)) int u54_single_hart(HLS_DATA* hls)
+{
+ init_memory();
+ hls->my_hart_id = MPFS_HAL_FIRST_HART;
+#ifdef MPFS_HAL_SHARED_MEM_ENABLED
+ /* if shared memory enabled, pointer from Boot-loader in the HLS should be
+ * non-zero */
+ ASSERT(hls->shared_mem != NULL);
+#endif
+ switch(hls->my_hart_id)
+ {
+ case 0U:
+ e51();
+ break;
+
+ case 1U:
+ u54_1();
+ break;
+
+ case 2U:
+ u54_2();
+ break;
+
+ case 3U:
+ u54_3();
+ break;
+
+ case 4U:
+ u54_4();
+ break;
+
+ default:
+ /* no more harts */
+ break;
+ }
+
+ /* should never get here */
+ while(true)
+ {
+ static volatile uint64_t counter = 0U;
+ /* Added some code as debugger hangs if in loop doing nothing */
+ counter = counter + 1U;
+ }
+
+ return (0);
+}
+
+/*==============================================================================
+ * U54s startup.
+ * This is called from entry.S
+ * If you need to modify this function, create your own one in a user directory
+ * space.
+ *
+ * Please note: harts MPFS_HAL_FIRST_FIRST + 1 to MPFS_HAL_FIRST_LAST will wait
+ * in startup code in entry.S as they run the wfi (wait for interrupt)
+ * instruction.
+ * They are woken up as required by the the MPFS_HAL_FIRST_HART, in the function
+ * main_first_hart().
+ * ( It triggers a software interrupt on the particular hart to be woken up )
+ */
+__attribute__((weak)) int main_other_hart(HLS_DATA* hls)
+{
+#ifdef MPFS_HAL_HW_CONFIG
+ extern char __app_stack_top_h0;
+ extern char __app_stack_top_h1;
+ extern char __app_stack_top_h2;
+ extern char __app_stack_top_h3;
+ extern char __app_stack_top_h4;
+
+ const uint64_t app_stack_top_h0 = (const uint64_t)&__app_stack_top_h0 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h1 = (const uint64_t)&__app_stack_top_h1 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h2 = (const uint64_t)&__app_stack_top_h2 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h3 = (const uint64_t)&__app_stack_top_h3 - (HLS_DEBUG_AREA_SIZE);
+ const uint64_t app_stack_top_h4 = (const uint64_t)&__app_stack_top_h4 - (HLS_DEBUG_AREA_SIZE);
+
+#ifdef MPFS_HAL_HW_CONFIG
+#ifdef MPFS_HAL_SHARED_MEM_ENABLED
+ /*
+ * If we are a boot-loader, and shared memory enabled (MPFS_HAL_SHARED_MEM_ENABLED)
+ * sets the pointer in each harts HLS to the shared memory.
+ * This allows access to this shared memory across all harts.
+ */
+ const uint64_t app_hart_common_start = (const uint64_t)&__app_hart_common_start;
+ hls->shared_mem = (uint64_t *)app_hart_common_start;
+ hls->shared_mem_marker = SHARED_MEM_INITALISED_MARKER;
+ hls->shared_mem_status = SHARED_MEM_DEFAULT_STATUS;
+#endif
+#else
+#ifdef MPFS_HAL_SHARED_MEM_ENABLED
+ /* make sure each harts Harts Local Storage has pointer to common memory if enabled */
+ /* store the value here received from boot-loader */
+ /* a1 will contain pointer to the start of shared memory */
+ //hls->shared_mem = (uint64_t *)__uninit_bottom$;
+#else
+ /*
+ * We are not using shared memory
+ */
+ hls->shared_mem = (uint64_t *)NULL;
+#endif
+#endif
+
+ volatile uint64_t dummy;
+
+ switch(hls->my_hart_id)
+ {
+
+ case 0U:
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h0));
+ e51();
+ break;
+
+ case 1U:
+ (void)init_pmp((uint8_t)1);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h1));
+ u54_1();
+ break;
+
+ case 2U:
+ (void)init_pmp((uint8_t)2);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h2));
+ u54_2();
+ break;
+
+ case 3U:
+ (void)init_pmp((uint8_t)3);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h3));
+ u54_3();
+ break;
+
+ case 4U:
+ (void)init_pmp((uint8_t)4);
+ __asm volatile ("add sp, x0, %1" : "=r"(dummy) : "r"(app_stack_top_h4));
+ u54_4();
+ break;
+
+ default:
+ /* no more harts */
+ break;
+ }
+
+ /* should never get here */
+ while(true)
+ {
+ static volatile uint64_t counter = 0U;
+ /* Added some code as debugger hangs if in loop doing nothing */
+ counter = counter + 1U;
+ }
+#endif
+ return (0);
+
+}
+
+/*==============================================================================
+ * Load the virtual ROM located at address 0x20003120 within the SCB system
+ * registers with an executable allowing to park a hart in an infinite loop.
+ */
+#ifdef MPFS_HAL_HW_CONFIG
+#define VIRTUAL_BOOTROM_BASE_ADDR 0x20003120UL
+#define NB_BOOT_ROM_WORDS 8U
+const uint32_t rom[NB_BOOT_ROM_WORDS] =
+{
+ 0x00000513U, /* li a0, 0 */
+ 0x34451073U, /* csrw mip, a0 */
+ 0x10500073U, /* wfi */
+ 0xFF5FF06FU, /* j 0x20003120 */
+ 0xFF1FF06FU, /* j 0x20003120 */
+ 0xFEDFF06FU, /* j 0x20003120 */
+ 0xFE9FF06FU, /* j 0x20003120 */
+ 0xFE5FF06FU /* j 0x20003120 */
+};
+
+void load_virtual_rom(void)
+{
+ volatile uint32_t * p_virtual_bootrom = (uint32_t *)VIRTUAL_BOOTROM_BASE_ADDR;
+ config_copy( (void *)p_virtual_bootrom, (void *)rom,sizeof(rom[NB_BOOT_ROM_WORDS]));
+}
+#endif /* MPFS_HAL_HW_CONFIG */
+
+/*==============================================================================
+ * Put the hart executing this code into an infinite loop executing from the
+ * SCB system register memory space.
+ * This allows preventing a hart from accessing memory regardless of memory
+ * hierarchy configuration or compiler/linker settings.
+ * This function relies on load_virtual_rom() having been called previously to
+ * populate the virtual ROM with a suitable executable.
+ */
+static void park_hart(void)
+{
+ clear_csr(mstatus, MSTATUS_MIE);
+ __asm volatile("fence.i");
+ __asm volatile("li ra,0x20003120");
+ __asm volatile("ret");
+}
+
+/*==============================================================================
+ * E51 code executing after system startup.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void e51(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+/*==============================================================================
+ * First U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_1(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+
+/*==============================================================================
+ * Second U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_2(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+/*==============================================================================
+ * Third U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_3(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+/*==============================================================================
+ * Fourth U54.
+ * In absence of an application function of this name with strong linkage, this
+ * function will get linked.
+ * This default implementation is for illustration purpose only. If you need to
+ * modify this function, create your own one in an application directory space.
+ */
+__attribute__((weak)) void u54_4(void)
+{
+ /* Put hart in safe infinite WFI loop. */
+ park_hart();
+}
+
+ /*-----------------------------------------------------------------------------
+ * _start() function called invoked
+ * This function is called on power up and warm reset.
+ */
+ __attribute__((weak)) void init_memory( void)
+ {
+ copy_section(&__text_load, &__text_start, &__text_end);
+ copy_section(&__sdata_load, &__sdata_start, &__sdata_end);
+ copy_section(&__data_load, &__data_start, &__data_end);
+
+ zero_section(&__sbss_start, &__sbss_end);
+ zero_section(&__bss_start, &__bss_end);
+
+ __disable_all_irqs(); /* disables local and global interrupt enable */
+ }
+
+ /*-----------------------------------------------------------------------------
+ * _start() function called invoked
+ * This function is called on power up and warm reset.
+ */
+ __attribute__((weak)) void init_ddr(void)
+ {
+ if ((LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK) != DDR_OFF_MODE) {
+#ifdef DDR_SUPPORT
+ uint64_t end_address;
+
+#if 0 /* enable to init cache to zero using 64 bit writes */
+ end_address = LIBERO_SETTING_DDR_64_NON_CACHE + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0 + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1;
+ zero_section((uint64_t *)LIBERO_SETTING_DDR_64_NON_CACHE, (uint64_t *)end_address);
+#endif
+
+ end_address = LIBERO_SETTING_DDR_64_CACHE + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_0 + LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI1_1;
+ zero_section((uint64_t *)LIBERO_SETTING_DDR_64_CACHE, (uint64_t *)end_address);
+#endif
+ }
+ }
+
+ /**
+ * This function is configured by editing parameters in
+ * mss_sw_config.h as required.
+ * @return
+ */
+
+__attribute__((weak)) uint8_t init_bus_error_unit(void)
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ uint8_t hart_id;
+ /* Init BEU in all harts - enable local interrupt */
+ for(hart_id = MPFS_HAL_FIRST_HART; hart_id <= MPFS_HAL_LAST_HART; hart_id++)
+ {
+ BEU->regs[hart_id].ENABLE = (uint64_t)BEU_ENABLE;
+ BEU->regs[hart_id].PLIC_INT = (uint64_t)BEU_PLIC_INT;
+ BEU->regs[hart_id].LOCAL_INT = (uint64_t)BEU_LOCAL_INT;
+ BEU->regs[hart_id].CAUSE = 0ULL;
+ BEU->regs[hart_id].ACCRUED = 0ULL;
+ BEU->regs[hart_id].VALUE = 0ULL;
+ }
+#endif
+ return (0U);
+}
+
+/**
+ * init_mem_protection_unit(void)
+ * add this function to you code and configure as required
+ * @return
+ */
+__attribute__((weak)) uint8_t init_mem_protection_unit(void)
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ mpu_configure();
+#endif
+ return (0U);
+}
+
+/**
+ * init_pmp(void)
+ * add this function to you code and configure as required
+ * @return
+ */
+__attribute__((weak)) uint8_t init_pmp(uint8_t hart_id)
+{
+ pmp_configure(hart_id);
+ return (0U);
+}
+
+/**
+ * set_apb_bus_cr(void)
+ * todo: add check to see if value valid re. mss configurator
+ * @return
+ */
+__attribute__((weak)) uint8_t mss_set_apb_bus_cr(uint32_t reg_value)
+{
+ SYSREG->APBBUS_CR = reg_value;
+ return (0U);
+}
+
+/**
+ * get_apb_bus_cr(void)
+ * @return
+ */
+__attribute__((weak)) uint8_t mss_get_apb_bus_cr(void)
+{
+ return (SYSREG->APBBUS_CR);
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup.h
new file mode 100644
index 00000000..3c962166
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup.h
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+*/
+
+/******************************************************************************
+ * @file system_startup.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Macros and APIs for the system_startup.c
+ */
+
+#ifndef SYSTEM_STARTUP_H
+#define SYSTEM_STARTUP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum WFI_SM_
+{
+ INIT_THREAD_PR = 0x00, /*!< 0 init pointer */
+ CHECK_WFI = 0x01, /*!< is hart in wfi? */
+ SEND_WFI = 0x02, /*!< separate state to
+ add a little delay*/
+ CHECK_WAKE = 0x03, /*!< has hart left wfi*/
+} WFI_SM;
+
+/*------------------------------------------------------------------------------
+ * Markers used to indicate startup status of hart
+ */
+#ifndef HLS_DATA_IN_WFI
+#define HLS_DATA_IN_WFI 0x12345678U
+#endif
+#ifndef HLS_DATA_PASSED_WFI
+#define HLS_DATA_PASSED_WFI 0x87654321U
+#endif
+
+#ifndef SHARED_MEM_INITALISED_MARKER
+#define SHARED_MEM_INITALISED_MARKER 0xA1A2A3A4UL
+#endif
+#ifndef SHARED_MEM_DEFAULT_STATUS
+#define SHARED_MEM_DEFAULT_STATUS 0x00000000UL
+#endif
+
+typedef struct HLS_DATA_
+{
+ volatile uint32_t in_wfi_indicator;
+ volatile uint32_t my_hart_id;
+ volatile uint32_t shared_mem_marker;
+ volatile uint32_t shared_mem_status;
+ volatile uint64_t * shared_mem;
+} HLS_DATA;
+
+/*------------------------------------------------------------------------------
+ * Symbols from the linker script used to locate the text, data and bss sections.
+ */
+extern unsigned long __stack_top_h0$;
+extern unsigned long __stack_bottom_h0$;
+extern unsigned long __stack_top_h1$;
+extern unsigned long __stack_bottom_h1$;
+extern unsigned long __stack_top_h2$;
+extern unsigned long __stack_bottom_h2$;
+extern unsigned long __stack_top_h3$;
+extern unsigned long __stack_bottom_h3$;
+extern unsigned long __stack_top_h4$;
+extern unsigned long __stack_bottom_h4$;
+extern unsigned long __app_hart_common_start;
+extern unsigned long __app_hart_common_end;
+
+extern unsigned long __data_load;
+extern unsigned long __data_start;
+extern unsigned long __data_end;
+
+extern unsigned long __sbss_start;
+extern unsigned long __sbss_end;
+
+extern unsigned long __bss_start;
+extern unsigned long __bss_end;
+
+extern unsigned long __sdata_load;
+extern unsigned long __sdata_start;
+extern unsigned long __sdata_end;
+
+extern unsigned long __text_load;
+extern unsigned long __text_start;
+extern unsigned long __text_end;
+
+extern unsigned long __l2lim_end;
+
+extern unsigned long __e51itim_start;
+extern unsigned long __e51itim_end;
+
+extern unsigned long __u54_1_itim_start;
+extern unsigned long __u54_1_itim_end;
+
+extern unsigned long __u54_2_itim_start;
+extern unsigned long __u54_2_itim_end;
+
+extern unsigned long __u54_3_itim_start;
+extern unsigned long __u54_3_itim_end;
+
+extern unsigned long __u54_4_itim_start;
+extern unsigned long __u54_4_itim_end;
+
+#ifndef MPFS_HAL_HW_CONFIG
+extern unsigned long __uninit_bottom$;
+extern unsigned long __uninit_top$;
+#endif
+
+/*
+ * Function Declarations
+ */
+int main_first_hart(HLS_DATA* hls);
+int main_other_hart(HLS_DATA* hls);
+void e51(void);
+void u54_1(void);
+void u54_2(void);
+void u54_3(void);
+void u54_4(void);
+void init_memory( void);
+void init_ddr( void);
+uint8_t init_mem_protection_unit(void);
+uint8_t init_pmp(uint8_t hart_id);
+uint8_t init_bus_error_unit( void);
+uint8_t mss_set_apb_bus_cr(uint32_t reg_value);
+uint8_t mss_get_apb_bus_cr(void);
+char * memfill(void *dest, const void * src, size_t len);
+char * config_copy(void *dest, const void * src, size_t len);
+char * config_16_copy(void *dest, const void * src, size_t len);
+char * config_32_copy(void *dest, const void * src, size_t len);
+char * config_64_copy(void *dest, const void * src, size_t len);
+
+void copy_section
+(
+ uint64_t * p_load,
+ uint64_t * p_vma,
+ uint64_t * p_vma_end
+);
+void zero_section
+(
+ uint64_t *__sbss_start,
+ uint64_t * __sbss_end
+);
+void load_virtual_rom(void);
+
+void count_section
+(
+ uint64_t * start_address,
+ uint64_t * end_address,
+ uint64_t * start_value
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_STARTUP_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup_defs.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup_defs.h
new file mode 100644
index 00000000..586c5b97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/mpfs_hal/startup_gcc/system_startup_defs.h
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+*/
+
+/******************************************************************************
+ * @file system_startup_defs.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Defines for the system_startup_defs.c
+ */
+
+#ifndef SYSTEM_STARTUP_DEFS_H
+#define SYSTEM_STARTUP_DESF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ * Markers used to indicate startup status of hart
+ */
+#define HLS_MAIN_HART_STARTED 0x12344321U
+#define HLS_MAIN_HART_FIN_INIT 0x55555555U
+#define HLS_OTHER_HART_IN_WFI 0x12345678U
+#define HLS_OTHER_HART_PASSED_WFI 0x87654321U
+
+/*------------------------------------------------------------------------------
+ * Define the size of the HLS used
+ * In our HAL, we are using Hart Local storage for debug data storage only
+ * as well as flags for wfi instruction management.
+ * The TLS will take memory from top of the stack if allocated
+ *
+ */
+#if !defined (HLS_DEBUG_AREA_SIZE)
+#define HLS_DEBUG_AREA_SIZE 64
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_STARTUP_DESF_H */
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld
new file mode 100644
index 00000000..45c143ed
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-ddr-loaded-by-boot-loader.ld
+ * Use this linker script when the program is fully located in DDR. The
+ * assumption is DDR has already been initialized by another program.
+ *
+ * This linker script can be used with a debugger or when compiled and loaded
+ * by a boot-loader.
+ * The loading program passes two parameters in a0 and a1
+ * a0 - The hartid is passed here
+ * a1 - A pointer to Hart Local Storage (HLS) is passed here
+ * The HLS is a small amount of memory dedicated to each hart.
+ * The HLS also contains a pointer to shared memory.
+ * The shared memory is accessible by all harts if used. It is
+ * allocated by the boot-loader if the MPFS_HAL_SHARED_MEM_ENABLED
+ * is defined in the mss_sw_config.h file project configuration file.
+ * Please see the project mpfs-hal-run-from-ddr-u54-1 located in the Bare Metal
+ * library under examples/mpfs-hal for an example of it use.
+ *
+ * https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+HEAP_SIZE = 0k; /* needs to be calculated for your application if using */
+
+/*
+ * Stack size for our single hart U54 application.
+ */
+STACK_SIZE_U54_APPLICATION = 8k;
+
+/*
+ * A small amount of unitialised memory used to store information
+ * obtained from the boot-loader on start-up
+ */
+UNITITALISED_MEM = 16B;
+
+/* reset address 0xC0000000 */
+SECTION_START_ADDRESS = 0x80000000;
+
+
+SECTIONS
+{
+
+ /* text: test code section */
+ . = SECTION_START_ADDRESS;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > ddr_cached_32bit
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > ddr_cached_32bit
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > ddr_cached_32bit
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > ddr_cached_32bit
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__app_stack_bottom = .);
+ . += STACK_SIZE_U54_APPLICATION;
+ PROVIDE(__app_stack_top = .);
+ } > ddr_cached_32bit
+
+ /*
+ * used by a program loaded by a bootloader to store information passed
+ * from boot-loader
+ * a0 holds the hart ID
+ * a1 hold pointer to device data, which includes pointer to shared memory
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .no_init : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ . += UNITITALISED_MEM;
+ PROVIDE(__uninit_top_h$ = .);
+ } > ddr_cached_32bit
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..b98f7342
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-envm-lma-scratchpad-vma.ld
+ * Code starts from eNVM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * STACK_SIZE_xxx_STARTUP
+ * Stack size for each hart's startup code.
+ * Before copying itself to the scratchpad memory area and executing the code from there, the
+ * startup code is executing from LIM. The scratchpad area is not configured yet. This per-hart
+ * startup stack area is located in LIM and used during this phase of the startup code.
+ * STACK_SIZE_xxx_APPLICATION
+ * After the startup code executing from LIM configures the scratchpad memory, it configures
+ * the each hart's SP with this stack area for the respective hart's application function,
+ * (namely e51(), u54_1(), u54_2(), u54_3(), u54_4() ) to use it.
+ * This per-hart application stack area is located in scratchpad and used by application when
+ * it is executing from scratchpad.
+ *
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >envm
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> envm /* On the MPFS for startup code use, >switch_code AT>envm */
+}
+
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-envm.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-envm.ld
new file mode 100644
index 00000000..29817bd0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-envm.ld
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_envm.ld
+ * Use with Bare metal startup code.
+ * Startup code runs from envm on MSS reset
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ /* *entry.o(.text); */
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > envm
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> envm
+
+ /*
+ * The .ram_code section will contain the code that is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code_dtim AT>envm
+
+ /*
+ * The .ddr_code section will contain the code that is run from DDR.
+ * This is to verify DDR working as expeted
+ */
+ .ddr_code :
+ {
+ . = ALIGN (4);
+ __ddr_load = LOADADDR (.ram_code);
+ __ddr_start = .;
+ *(.ddr_codetext) /* .ram_codetext sections (code) */
+ *(.ddr_codetext*) /* .ram_codetext* sections (code) */
+ *(.ddr_coderodata) /* read-only data (constants) */
+ *(.ddr_coderodata*)
+ . = ALIGN (4);
+ __ddr_end = .;
+ } >ddr_cached_32bit AT>envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set
+ point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing.
+ Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim AT > envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim AT > envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary (0x1000) - corresponds to page size, when using
+ memory mem */
+ /* protection */
+ /* .stack : ALIGN(0x1000) */
+ .stack : ALIGN(0x10)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ /* place __start_of_free_lim$ after last allocation of l2_lim */
+ . = ALIGN(0x10);
+ PROVIDE(__start_of_free_lim$ = .);
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..391c47bf
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ * Code starts from LIM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * STACK_SIZE_xxx_STARTUP
+ * Stack size for each hart's startup code.
+ * Before copying itself to the scratchpad memory area and executing the code from there, the
+ * startup code is executing from LIM. The scratchpad area is not configured yet. This per-hart
+ * startup stack area is located in LIM and used during this phase of the startup code.
+ * STACK_SIZE_xxx_APPLICATION
+ * After the startup code executing from LIM configures the scratchpad memory, it configures
+ * the each hart's SP with this stack area for the respective hart's application function,
+ * (namely e51(), u54_1(), u54_2(), u54_3(), u54_4() ) to use it.
+ * This per-hart application stack area is located in scratchpad and used by application when
+ * it is executing from scratchpad.
+ *
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __l2lim_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >l2lim
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> l2lim
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>envm */
+
+}
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-lim.ld b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-lim.ld
new file mode 100644
index 00000000..908cf23e
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/linker/mpfs-lim.ld
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_lim.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+ /* text: text code section */
+ . = __l2lim_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ . = ALIGN(0x10);
+ } > l2lim
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ . = ALIGN (0x10);
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> l2lim
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including eNVM clock.
+ * This can not be done when running from eNVM
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>eNVM */
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h
new file mode 100644
index 00000000..7b6e905d
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * Platform definitions
+ * Version based on requirements of MPFS MSS
+ *
+ */
+ /*========================================================================*//**
+ @mainpage Sample file detailing how mss_sw_config.h should be constructed for
+ the MPFS MSS
+
+ @section intro_sec Introduction
+ The mss_sw_config.h has the default software configuration settings for the
+ MPFS HAL and will be located at
+ /src/platform/platform_config_reference folder of the bare
+ metal SoftConsole project. The platform_config_reference is provided as a
+ default reference configuration.
+ When you want to configure the MPFS HAL with required configuration for
+ your project, the mss_sw_config.h must be edited and be placed in the
+ following project directory:
+ /src/boards//platform_config/mpfs_hal_config/
+
+ @section
+
+*//*==========================================================================*/
+
+
+#ifndef MSS_SW_CONFIG_H_
+#define MSS_SW_CONFIG_H_
+
+/*
+ * MPFS_HAL_FIRST_HART and MPFS_HAL_LAST_HART defines are used to specify which
+ * harts to actually start. The value and the actual hart it represents are
+ * listed below:
+ * value hart
+ * 0 E51
+ * 1 U54_1
+ * 2 U54_2
+ * 3 U54_3
+ * 4 U54_4
+ * Set MPFS_HAL_FIRST_HART to a value greater than 0 if you do not want your
+ * application to start and execute code on the harts represented by smaller
+ * value numbers.
+ * Set MPFS_HAL_LAST_HART to a value smaller than 4 if you do not wish to use
+ * all U54_x harts.
+ * Harts that are not started will remain in an infinite WFI loop unless used
+ * through some other method.
+ * The value of MPFS_HAL_FIRST_HART must always be less than MPFS_HAL_LAST_HART.
+ * The value of MPFS_HAL_LAST_HART must never be greater than 4.
+ * A typical use-case where you set MPFS_HAL_FIRST_HART = 1 and
+ * MPFS_HAL_LAST_HART = 1 is when
+ * your application is running on U54_1 and a bootloader running on E51 loads
+ * your application to the target memory and kicks-off U54_1 to run it.
+ */
+#ifndef MPFS_HAL_FIRST_HART
+#define MPFS_HAL_FIRST_HART 0
+#endif
+
+#ifndef MPFS_HAL_LAST_HART
+#define MPFS_HAL_LAST_HART 4
+#endif
+
+/*
+ * IMAGE_LOADED_BY_BOOTLOADER
+ * We set IMAGE_LOADED_BY_BOOTLOADER = 0 if the application image runs from
+ * non-volatile memory after reset. (No previous stage bootloader is used.)
+ * Set IMAGE_LOADED_BY_BOOTLOADER = 1 if the application image is loaded by a
+ * previous stage bootloader.
+ *
+ * MPFS_HAL_HW_CONFIG is defined if we are a boot-loader. This is a
+ * conditional compile switch is used to determine if MPFS HAL will perform the
+ * hardware configurations or not.
+ * Defined => This program acts as a First stage bootloader and performs
+ * hardware configurations.
+ * Not defined => This program assumes that the hardware configurations are
+ * already performed (Typically by a previous boot stage)
+ *
+ * List of items initialised when MPFS_HAL_HW_CONFIG is enabled
+ * - load virtual rom (see load_virtual_rom(void) in system_startup.c)
+ * - l2 cache config
+ * - Bus error unit config
+ * - MPU config
+ * - pmp config
+ * - I/O, clock and clock mux's, DDR and SGMII
+ * - will start other harts, see text describing MPFS_HAL_FIRST_HART,
+ * MPFS_HAL_LAST_HART above
+ *
+ */
+#define IMAGE_LOADED_BY_BOOTLOADER 0
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+#define MPFS_HAL_HW_CONFIG
+#endif
+
+
+/*
+ * If you are using common memory for sharing across harts,
+ * uncomment #define MPFS_HAL_SHARED_MEM_ENABLED
+ * make sure common memory is allocated in the linker script
+ * See app_hart_common mem section in the example platform
+ * linker scripts.
+ */
+
+#define MPFS_HAL_SHARED_MEM_ENABLED
+
+
+/* define the required tick rate in Milliseconds */
+/* if this program is running on one hart only, only that particular hart value
+ * will be used */
+#define HART0_TICK_RATE_MS 5UL
+#define HART1_TICK_RATE_MS 5UL
+#define HART2_TICK_RATE_MS 5UL
+#define HART3_TICK_RATE_MS 5UL
+#define HART4_TICK_RATE_MS 5UL
+
+/*
+ * Define the size of the Hart Local Storage (HLS).
+ * In the MPFS HAL, we are using HLS for debug data storage during the initial
+ * boot phase.
+ * This includes the flags which indicate the hart state regarding boot state.
+ * The HLS will take memory from top of each stack allocated at boot time.
+ *
+ */
+#define HLS_DEBUG_AREA_SIZE 64
+
+/*
+ * Bus Error Unit (BEU) configurations
+ * BEU_ENABLE => Configures the events that the BEU can report. bit value
+ * 1= enabled, 0 = disabled.
+ * BEU_PLIC_INT => Configures which accrued events should generate an
+ * interrupt to the PLIC.
+ * BEU_LOCAL_INT => Configures which accrued events should generate a
+ * local interrupt to the hart on which the event accrued.
+ */
+#define BEU_ENABLE 0x0ULL
+#define BEU_PLIC_INT 0x0ULL
+#define BEU_LOCAL_INT 0x0ULL
+
+/*
+ * Clear memory on startup
+ * 0 => do not clear DTIM and L2
+ * 1 => Clears memory
+ * Note: If you are the zero stage bootloader, set this to one.
+ */
+#ifndef MPFS_HAL_CLEAR_MEMORY
+#define MPFS_HAL_CLEAR_MEMORY 1
+#endif
+
+/*
+ * Comment out the lines to disable the corresponding hardware support not required
+ * in your application.
+ * This is not necessary from an operational point of view as operation dictated
+ * by MSS configurator settings, and items are enabled/disabled by this method.
+ * The reason you may want to use below is to save code space.
+ */
+#define SGMII_SUPPORT
+#define DDR_SUPPORT
+#define MSSIO_SUPPORT
+
+/*
+ * DDR software options
+ */
+
+/*
+ * Debug DDR startup through a UART
+ * Comment out in normal operation. May be useful for debug purposes in bring-up
+ * of a new board design.
+ * See the weakly linked function setup_ddr_debug_port(mss_uart_instance_t * uart)
+ * If you need to edit this function, make another copy of the function in your
+ * application without the weak linking attribute. This copy will then get linked.
+ * */
+//#define DEBUG_DDR_INIT
+//#define DEBUG_DDR_RD_RW_FAIL
+//#define DEBUG_DDR_RD_RW_PASS
+//#define DEBUG_DDR_CFG_DDR_SGMII_PHY
+//#define DEBUG_DDR_DDRCFG
+
+
+/*
+ * The hardware configuration settings imported from Libero project get generated
+ * into /src/boards// folder.
+ * If you need to overwrite them for testing purposes, you can do so here.
+ * e.g. If you want change the default SEG registers configuration defined by
+ * LIBERO_SETTING_SEG0_0, define it here and it will take precedence.
+ * #define LIBERO_SETTING_SEG0_0 0x80007F80UL
+ *
+ */
+
+#endif /* USER_CONFIG_MSS_USER_CONFIG_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/soc_config_generator/mpfs_configuration_generator.py b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/soc_config_generator/mpfs_configuration_generator.py
new file mode 100644
index 00000000..3394bdba
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-external-loopback/src/platform/soc_config_generator/mpfs_configuration_generator.py
@@ -0,0 +1,713 @@
+#-------------------------------------------------------------------------------
+# This script takes an xml file which describes hardware options and produces
+# header files in the target directory which are used by the embedded
+# software.
+#-------------------------------------------------------------------------------
+
+import datetime
+import os
+import os.path
+import xml.etree.ElementTree as ET
+import sys
+from pathlib import Path
+
+
+# --------------------------------------------------------------------------------------------
+# mpfs_configuration_generator.py version
+#
+# 0.6.3 target folder name change from "fpga_config" -> fpga_design config, filename
+# hw_platform.h changed to fpga_design_config.h ,
+# bug fix related to multiple xml file selection and added libero design information
+# constants in fpga_design_config.h/ removed date,version and design information from all the files
+# except fpga_design_config.h
+#
+# 0.6.2 added support for multiple xml file found in input folder
+# /empty xml file check/ xml filename arg in current folder/
+# if multiple files are there then the file with the latest time stamp will
+# be selected.
+# 0.6.1 changed target folder name from soc_config to fpga_config
+#
+# 0.5.2 Aries Embedded Feedback: remove trailing spaces.
+# 0.5.1 Added check that the source XML document is more recent than content of already existing
+# SoC configuration files.
+#
+# 0.4.2 Allowed to only specify the folder where the input XML
+# file is located. Use file ending with _mss_cfg.xml if one exists, any other .xml file in
+# the input folder otherwise.
+#
+# 0.4.1 Modified the arguments to allow specifying
+# the folder where the soc_config folder should be generated.
+#
+# 0.3.4 fixed comment formatting bug in hw_memory.h generation
+# 0.3.3 updated copyright format
+# 0.3.2 removed leading zeros from decimal values ( clock rates)
+# -------------------------------------------------------------------------------------------------------
+def get_script_ver():
+ '''
+ This changes anytime anytime the mpfs_configuration_generator.py script
+ changes. This does not necessarily mean the xml format has been updated in
+ get_xml_ver()
+ :return: script version
+ '''
+ return "0.6.3"
+
+
+
+
+# -----------------------------------------------------------------------------
+# xml file to parse
+# Also an xml files listing tags used for reference
+# -----------------------------------------------------------------------------
+reference_xml_file = \
+ ('hardware_des_xml,src_example,mpfs_hw_ref_defaults.xml,default',
+ 'hardware_des_xml,src_example,mpfs_hw_ref_ddr3_100Mhz_ext_clk.xml,ddr3_100Mhz_ref')
+
+xml_tag_file = 'hardware_des_xml,src_example,mpfs_hw_tag_reference.xml'
+
+
+# -----------------------------------------------------------------------------
+# xml tags, the structure here should follow the readme.md description
+# contained in the root folder for tags
+# Please note: The tag in the first column ( mss_xxx) is the same as the
+# directory name (/fpga_design_config/mss_xxx)
+# the fourth item lets program know how to format info in header file
+# the six item lets program know how to format value, decimal or hex
+# -----------------------------------------------------------------------------
+xml_tags = ('mss_memory_map,map,mem_elements,fm_define,none,hex',
+ 'mss_memory_map,apb_split,registers,fm_struct,none,hex',
+ 'mss_memory_map,cache,registers,fm_struct,none,hex',
+ 'mss_memory_map,pmp_h0,registers,fm_struct,HART0_,hex64',
+ 'mss_memory_map,pmp_h1,registers,fm_struct,HART1_,hex64',
+ 'mss_memory_map,pmp_h2,registers,fm_struct,HART2_,hex64',
+ 'mss_memory_map,pmp_h3,registers,fm_struct,HART3_,hex64',
+ 'mss_memory_map,pmp_h4,registers,fm_struct,HART4_,hex64',
+ 'mss_memory_map,mpu_fic0,registers,fm_struct,FIC0_,hex64',
+ 'mss_memory_map,mpu_fic1,registers,fm_struct,FIC1_,hex64',
+ 'mss_memory_map,mpu_fic2,registers,fm_struct,FIC2_,hex64',
+ 'mss_memory_map,mpu_crypto,registers,fm_struct,CRYPTO_,hex64',
+ 'mss_memory_map,mpu_gem0,registers,fm_struct,GEM0_,hex64',
+ 'mss_memory_map,mpu_gem1,registers,fm_struct,GEM1_,hex64',
+ 'mss_memory_map,mpu_usb,registers,fm_struct,USB_,hex64',
+ 'mss_memory_map,mpu_mmc,registers,fm_struct,MMC_,hex64',
+ 'mss_memory_map,mpu_scb,registers,fm_struct,SCB_,hex64',
+ 'mss_memory_map,mpu_trace,registers,fm_struct,TRACE_,hex64',
+ 'mss_io,io_mux,registers,fm_reg,none,hex',
+ 'mss_io,hsio,registers,fm_reg,none,hex',
+ 'mss_sgmii,tip,registers,fm_reg,none,hex',
+ 'mss_ddr,options,registers,fm_reg,none,hex',
+ 'mss_ddr,io_bank,registers,fm_reg,none,hex',
+ 'mss_ddr,mode,registers,fm_reg,none,hex',
+ 'mss_ddr,off_mode,registers,fm_reg,none,hex',
+ 'mss_ddr,segs,registers,fm_reg,none,hex',
+ 'mss_ddr,ddrc,registers,fm_reg,none,hex',
+ 'mss_clocks,clocks,registers,fm_define,none,decimal',
+ 'mss_clocks,mss_sys,registers,fm_define,MSS_,hex',
+ 'mss_clocks,mss_pll,registers,fm_define,MSS_,hex',
+ 'mss_clocks,sgmii_pll,registers,fm_reg,SGMII_,hex',
+ 'mss_clocks,ddr_pll,registers,fm_reg,DDR_,hex',
+ 'mss_clocks,mss_cfm,registers,fm_reg,MSS_,hex',
+ 'mss_clocks,sgmii_cfm,registers,fm_reg,SGMII_,hex',
+ 'mss_general,mss_peripherals,registers,fm_reg,none,hex',)
+
+
+# -----------------------------------------------------------------------------
+# Header files to generate
+# -----------------------------------------------------------------------------
+header_files = ('fpga_design_config,memory_map,hw_memory.h',
+ 'fpga_design_config,memory_map,hw_apb_split.h',
+ 'fpga_design_config,memory_map,hw_cache.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart0.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart1.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart2.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart3.h',
+ 'fpga_design_config,memory_map,hw_pmp_hart4.h',
+ 'fpga_design_config,memory_map,hw_mpu_fic0.h',
+ 'fpga_design_config,memory_map,hw_mpu_fic1.h',
+ 'fpga_design_config,memory_map,hw_mpu_fic2.h',
+ 'fpga_design_config,memory_map,hw_mpu_crypto.h',
+ 'fpga_design_config,memory_map,hw_mpu_gem0.h',
+ 'fpga_design_config,memory_map,hw_mpu_gem1.h',
+ 'fpga_design_config,memory_map,hw_mpu_usb.h',
+ 'fpga_design_config,memory_map,hw_mpu_mmc.h',
+ 'fpga_design_config,memory_map,hw_mpu_scb.h',
+ 'fpga_design_config,memory_map,hw_mpu_trace.h',
+ 'fpga_design_config,io,hw_mssio_mux.h',
+ 'fpga_design_config,io,hw_hsio_mux.h',
+ 'fpga_design_config,sgmii,hw_sgmii_tip.h',
+ 'fpga_design_config,ddr,hw_ddr_options.h',
+ 'fpga_design_config,ddr,hw_ddr_io_bank.h',
+ 'fpga_design_config,ddr,hw_ddr_mode.h',
+ 'fpga_design_config,ddr,hw_ddr_off_mode.h',
+ 'fpga_design_config,ddr,hw_ddr_segs.h',
+ 'fpga_design_config,ddr,hw_ddrc.h',
+ 'fpga_design_config,clocks,hw_mss_clks.h',
+ 'fpga_design_config,clocks,hw_clk_sysreg.h',
+ 'fpga_design_config,clocks,hw_clk_mss_pll.h',
+ 'fpga_design_config,clocks,hw_clk_sgmii_pll.h',
+ 'fpga_design_config,clocks,hw_clk_ddr_pll.h',
+ 'fpga_design_config,clocks,hw_clk_mss_cfm.h',
+ 'fpga_design_config,clocks,hw_clk_sgmii_cfm.h',
+ 'fpga_design_config,general,hw_gen_peripherals.h')
+
+MAX_LINE_WIDTH = 80
+
+
+# -----------------------------------------------------------------------------
+# Read the xml file into ET
+# -----------------------------------------------------------------------------
+def read_xml_file(s):
+ file_dir = os.path.join(*s)
+ tree = ET.parse(file_dir.strip())
+ root = tree.getroot() # type: object
+ return root
+
+
+# -----------------------------------------------------------------------------
+# Routine to make a folder
+# -----------------------------------------------------------------------------
+def safe_make_folder(i):
+ '''Makes a folder (and its parents) if not present'''
+ try:
+ os.makedirs(i)
+ except:
+ pass
+
+
+# -----------------------------------------------------------------------------
+# Create the directory structure
+# -----------------------------------------------------------------------------
+def create_hw_dir_struct(root_folder, TOP):
+ '''Creates directory structure off root, subdirectories passed in a tupple'''
+ for folder in TOP:
+ safe_make_folder(root_folder + '/' + folder)
+
+
+# -----------------------------------------------------------------------------
+# Generate the copyright notice at the top of the header file
+# -----------------------------------------------------------------------------
+def WriteCopyright(root, theFile, filename, creator):
+ '''
+ generate copyright notice based on the following:
+ #/*******************************************************************************
+ # * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ # *
+ # * SPDX-License-Identifier: MIT
+ # *
+ # * MPFS HAL Embedded Software
+ # *
+ # */
+ :param root:
+ :param theFile:
+ :param filename:
+ :param creator:
+ :return:
+ '''
+ theFile.write('/**********************************************************'
+ '*********************\n')
+ theFile.write(" * Copyright 2019-" + str(datetime.datetime.now().year) + " Microchip FPGA Embedded Systems Solutions.\n")
+ theFile.write(' *\n')
+ theFile.write(' * SPDX-License-Identifier: MIT\n')
+ theFile.write(' *\n')
+ theFile.write(" * @file " + filename + "\n")
+ theFile.write(" * @author " + creator + "\n")
+ theFile.write(' *\n')
+ if theFile.name == "fpga_design_config\fpga_design_config.h":
+ for child in root:
+ if child.tag == "design_information":
+ for child1 in child:
+ if child1.tag == "design_name":
+ theFile.write(' * Libero design name: ' + child1.text.strip() + "\n")
+ if child1.tag == "libero_version":
+ theFile.write(' * Generated using Libero version: ' + child1.text.strip() + "\n")
+ if child1.tag == "mpfs_part_no":
+ theFile.write(' * MPFS part number used in design: ' + child1.text.strip() + "\n")
+ if child1.tag == "creation_date_time":
+ theFile.write(' * Date generated by Libero: ' + child1.text.strip() + "\n")
+ if child1.tag == "xml_format_version":
+ theFile.write(' * Format version of XML description: ' + child1.text.strip() + "\n")
+ theFile.write(' * PolarFire SoC Configuration Generator version: ' + get_script_ver() + "\n")
+
+ strings = ('', ' Note 1: This file should not be edited. If you need to modify a parameter',\
+ ' without going through regenerating using the MSS Configurator Libero flow ' ,' or editing the associated xml file',\
+ ' the following method is recommended: \n',\
+ ' 1. edit the following file ',' boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h\n',\
+ ' 2. define the value you want to override there.',' (Note: There is a commented example in the platform directory)\n',\
+ ' Note 2: The definition in mss_sw_config.h takes precedence, as',\
+ ' mss_sw_config.h is included prior to the generated header files located in', ' boards/your_board/fpga_design_config'\
+ )
+ for string in strings:
+ theFile.write(' *' + string + "\n")
+ theFile.write(' *\n */\n')
+
+
+# -----------------------------------------------------------------------------
+# the header start define
+# -----------------------------------------------------------------------------
+def start_define(theFile, filename):
+ filename = filename[:-2] # remove .h from file name
+ theFile.write('\n#ifndef ' + filename.upper() + '_H_')
+ theFile.write('\n#define ' + filename.upper() + '_H_\n\n')
+
+
+# -----------------------------------------------------------------------------
+# start c plus define
+# -----------------------------------------------------------------------------
+def start_cplus(theFile, filename):
+ theFile.write('\n#ifdef __cplusplus\n')
+ theFile.write('extern ' + ' \"C\"' + ' {\n')
+ theFile.write('#endif\n\n')
+
+
+# -----------------------------------------------------------------------------
+# end define associated with header start define
+# -----------------------------------------------------------------------------
+def end_define(theFile, filename):
+ filename = filename[:-2] # remove .h from file name
+ theFile.write('\n#endif /*' + ' #ifdef ' + filename.upper() + '_H_ */\n\n')
+
+
+# -----------------------------------------------------------------------------
+# end c++ define
+# -----------------------------------------------------------------------------
+def end_cplus(theFile, filename):
+ theFile.write('\n#ifdef __cplusplus\n}\n#endif\n\n')
+
+
+# -----------------------------------------------------------------------------
+# write line, break into chunks
+# -----------------------------------------------------------------------------
+def write_line(headerFile , reg_description):
+ ''' write line, break into chunks '''
+ word_list = reg_description.split() # list of words
+ sentence = word_list[0] + ' '
+ word_list.pop(0)
+ for word in word_list:
+ if (len(sentence + word + ' ') > MAX_LINE_WIDTH):
+ headerFile.write(sentence.rstrip() + '\n')
+ sentence = word + ' '
+ else:
+ sentence = sentence + word + ' '
+ if len(sentence) > 0:
+ headerFile.write(sentence.rstrip() + '\n')
+
+
+# -----------------------------------------------------------------------------
+# Iterate through registers and produce header file output
+# -----------------------------------------------------------------------------
+def generate_register(headerFile, registers, tags):
+ '''
+ Parse registers tag for register tags and print to header file
+ :param headerFile: header file to print to
+ :param registers: registers in a tag
+ :param tags: Some tags used to determine print format
+ :return:
+ '''
+ for register in registers:
+ # if tag 4 is set, pre-append register name with tag[4] value
+ if tags[4] != 'none':
+ pre_append = tags[4]
+ name = 'LIBERO_SETTING_' + pre_append + register.get('name')
+ else:
+ name = 'LIBERO_SETTING_' + register.get('name')
+ name_of_reg = name
+ description = register.get('description')
+ name_gap = 15
+ if len(name) > 15:
+ name_gap = len(name)
+ s = '#define' + ' ' + name.ljust(name_gap, ' ')
+ name = register.get('name') + "_OFF_MODE"
+ name_gap = 15
+ if len(name) > 15:
+ name_gap = len(name)
+ stest1 = '#define' + ' ' + name.ljust(name_gap, ' ')
+ field_list = []
+ reg_value = 0
+ reg_value_default = 0
+ for field in register:
+ if field.tag == "field":
+ gap = 30
+ if len(field.get('name')) > gap:
+ gap = len(field.get('name')) + 4
+ sfield = ' /* ' + field.get('name').ljust(gap, ' ')
+ stemp = ' [' + field.get('offset') + ':' + field.get('width') + ']'
+ stemp = stemp.ljust(12, ' ')
+ sfield += stemp
+ sfield += field.get('Type')
+ if (field.get('Type') == 'RW'):
+ sfield += ' value= ' + field.text.strip()
+ temp_val = ((int(field.text.strip(), 16)) << int(field.get('offset')))
+ reg_value += temp_val
+ sfield += ' */\n'
+ # add the field to list of fields
+ field_list.extend([sfield])
+ if tags[5] == 'decimal':
+ value = format(reg_value, '01X')
+ default_value = format(reg_value_default, '08X')
+ elif tags[5] == 'hex64':
+ value = '0x' + format(reg_value, '016X') + 'ULL'
+ default_value = '0x' + format(reg_value_default, '08X')
+ else :
+ value = '0x' + format(reg_value, '08X') + 'UL'
+ default_value = '0x' + format(reg_value_default, '08X')
+ name_gap = 4
+ if len(s) >= name_gap:
+ name_gap = len(s) + 4
+ s = s.ljust(name_gap, ' ') + value + '\n'
+ reg_description = '/*' + description + ' */\n'
+ headerFile.write('#if !defined ' + '(' + name_of_reg + ')\n')
+ # Write out the register description, max chars per line 80
+ write_line(headerFile , reg_description)
+ headerFile.write(s)
+ for x in range(len(field_list)):
+ headerFile.write(field_list[x])
+ headerFile.write('#endif\n')
+
+
+# -----------------------------------------------------------------------------
+# Iterate through tag mem_elements looking for mem elements produce header file
+# output
+# -----------------------------------------------------------------------------
+def generate_mem_elements(headerFile, mem_elements, tags):
+ '''
+ Parse registers tag for mem tags and print to header file
+ :param headerFile:
+ :param registers:
+ :return:
+ '''
+ for mem in mem_elements:
+ name = 'LIBERO_SETTING_' + mem.get('name')
+ name_of_reg = name
+ name_size = name + '_SIZE'
+ description = mem.get('description')
+ name_gap = 15
+ if len(name) > 15:
+ name_gap = len(name)
+ s = '#define' + ' ' + name.ljust(name_gap, ' ')
+ s1 = '#define' + ' ' + name_size.ljust(name_gap, ' ')
+ # get the values
+ mem_value = mem.text.strip()
+ mem_size = mem.get('size')
+ # make sure space between name and value 4 spaces
+ name_gap = 4
+ if len(s) >= name_gap:
+ name_gap = len(s) + 4
+ # make sure space between name and value 4 spaces
+ name_size_gap = 4
+ if len(s1) >= name_size_gap:
+ name_size_gap = len(s1) + 4
+ # create the strings for writing
+ s = s.ljust(name_gap, ' ') + mem_value + '\n'
+ reg_description = '/*' + description + ' */\n'
+ s1 = s1.ljust(name_size_gap, ' ') + mem_size \
+ + ' /* Length of memory block*/ \n'
+ headerFile.write('#if !defined ' + '(' + name_of_reg + ')\n')
+ headerFile.write(reg_description)
+ headerFile.write(s)
+ headerFile.write(s1)
+ headerFile.write('#endif\n')
+
+
+# -----------------------------------------------------------------------------
+# generate a header file
+# -----------------------------------------------------------------------------
+def generate_header( file, real_root, root, file_name, tags):
+ creator = "Microchip-FPGA Embedded Systems Solutions"
+ with open(file, 'w+') as headerFile:
+ # write the copyright header
+ WriteCopyright(real_root, headerFile, file_name, creator)
+ start_define(headerFile, file_name)
+ start_cplus(headerFile, file_name)
+ for child in root:
+ if child.tag == "registers":
+ generate_register(headerFile, child, tags)
+ if child.tag == "mem_elements":
+ generate_mem_elements(headerFile, child, tags)
+ for child2 in child:
+ if child2.tag == "registers":
+ generate_register(headerFile, child2, tags)
+ end_cplus(headerFile, file_name)
+ end_define(headerFile, file_name)
+
+
+# -----------------------------------------------------------------------------
+# fpga_design_config.h header file generation.
+# -----------------------------------------------------------------------------
+
+def write_libero_config_info(root,theFile):
+ script_version = get_script_ver().split('.')
+ tags_dic = {"design_name":"LIBERO_SETTING_DESIGN_NAME","libero_version":"LIBERO_SETTING_MSS_CONFIGURATOR_VERSION","mpfs_part_no" :"LIBERO_SETTING_MPFS_PART "\
+ ,"creation_date_time":"LIBERO_SETTING_GENERATION_DATE","xml_format_version":"LIBERO_SETTING_XML_VERSION"}
+
+ #max constant name size + some extra buffer space
+ max_gap = max([len(v) for k,v in tags_dic.items()]) + 8
+
+ fixed_gap = 12
+ xml_version = []
+ for child in root:
+ if child.tag == "design_information":
+ for child1 in child:
+ if child1.tag in tags_dic:
+ gap = max_gap - (len(tags_dic[child1.tag]))
+ theFile.write('#define '+ tags_dic[child1.tag].ljust(4,' ') + " "*(gap + fixed_gap) + "\"" + child1.text.strip() + "\"" + "\n")
+ if child1.tag == "xml_format_version":
+ xml_version = child1.text.strip().split('.')
+
+ const = {"LIBERO_SETTING_XML_VERSION_MAJOR": xml_version[0],"LIBERO_SETTING_XML_VERSION_MINOR":xml_version[1],"LIBERO_SETTING_XML_VERSION_PATCH":xml_version[2], "LIBERO_SETTING_HEADER_GENERATOR_VERSION":'.'.join(script_version),"LIBERO_SETTING_HEADER_GENERATOR_VERSION_MAJOR":script_version[0],"LIBERO_SETTING_HEADER_GENERATOR_VERSION_MINOR":script_version[1],"LIBERO_SETTING_HEADER_GENERATOR_VERSION_PATCH":script_version[2]}
+
+ # write hard coded constants in the fpga_design_config.h file.
+ for k,v in const.items():
+ gap = max_gap - len(k)
+ if k == "LIBERO_SETTING_HEADER_GENERATOR_VERSION":
+ theFile.write('#define '+ k.ljust(4,' ') + " "*(gap + fixed_gap) + "\"" + v + "\"" + "\n")
+ else:
+ theFile.write('#define '+ k + " "*(gap + fixed_gap) + v + "\n")
+ #new line
+ theFile.write("\n")
+
+
+def generate_reference_header_file(ref_header_file, root, header_files):
+ creator = "Embedded Software"
+ # itemName ="io_mux configuration"
+ s = ref_header_file.split(',')
+ file = os.path.join(*s)
+ file_name = s[-1]
+ with open(file, 'w+') as headerFile:
+ # write the copyright header
+
+ WriteCopyright(root, headerFile, file_name, creator)
+ # add exclusive define
+ start_define(headerFile, file_name)
+ # include all the headers
+
+ #define Libero design information constants
+ write_libero_config_info(root,headerFile)
+ index = 0
+ for child in header_files:
+ c = header_files[index].split(',')
+ c.remove('fpga_design_config')
+ # include_file = os.path.join(*c)
+ # as we need formatting correct for linux and windows
+ include_file = c[0] + '/' + c[1]
+ headerFile.write('#include \"' + include_file + '\"\n')
+ index += 1
+ # add the c++ define
+ start_cplus(headerFile, file_name)
+ # no content in this case
+ comment = '/* No content in this file, used for referencing header */\n'
+ headerFile.write(comment)
+ # end the c++ define
+ end_cplus(headerFile, file_name)
+ end_define(headerFile, file_name)
+
+
+# -----------------------------------------------------------------------------
+# Generate all the header files, passed in output_header_files
+# -----------------------------------------------------------------------------
+def generate_header_files(output_header_files, input_xml_file, input_xml_tags):
+ # read in an xml file
+ s = input_xml_file.split(',')
+
+ root = read_xml_file(s)
+ index = 0
+ while index < len(input_xml_tags):
+ ref_tags = input_xml_tags[index].split(',')
+ s = output_header_files[index].split(',')
+ file_name = s[-1]
+ dir_name = s[-2]
+ file_dir = os.path.join(*s)
+ found_match = 0
+ for child in root:
+ if child.tag == 'mss_' + dir_name:
+ for child1 in child:
+ if child1.tag == ref_tags[1]:
+ found_match = 1
+ break
+ #
+ # Next, create file based on xml content
+ #
+ if found_match == 1:
+ generate_header(file_dir, root, child1, file_name, ref_tags)
+ index += 1
+
+ '''
+ generate a header which references all the generated headers
+ '''
+ file_name = 'fpga_design_config,fpga_design_config.h'
+ generate_reference_header_file(file_name, root, output_header_files)
+
+
+# -----------------------------------------------------------------------------
+# Return absolute path created from working directory location and relative
+# path passed as argument. Handles path to an XML file and path to a folder.
+# -----------------------------------------------------------------------------
+def get_full_path(in_path):
+ print(in_path)
+ cwd = os.getcwd()
+ print(cwd)
+ filename = ''
+ temp = in_path
+ if in_path.endswith('.xml'):
+ path_comp = in_path.split('/')
+ last = len(path_comp) - 1
+ filename = path_comp[last]
+
+ in_path = in_path.replace(filename, '')
+ print(in_path)
+ if in_path == '':
+ filename = temp
+ in_path = os.getcwd()
+ print(in_path)
+ else:
+ xml_list = []
+ dir_entries = os.listdir(in_path)
+ for dir_entry in dir_entries:
+
+ if dir_entry.endswith('.xml'):
+ xml_list.append(dir_entry)
+ else:
+ if dir_entry.endswith('_mss_cfg.xml'):
+ xml_list.append(dir_entry)
+ break
+ #This section will sort the xml file by the latest timestamp
+ if len(xml_list) > 1:
+
+ xml_list = sort_by_timestamp(xml_list,in_path)
+ filename = xml_list[-1]
+ #prompt the selected filename
+ print("selected xml file is : {}".format(filename))
+ else:
+ if len(xml_list) != 0:
+ filename = xml_list[0]
+
+ print(in_path)
+
+ try:
+ print("trying to change directory")
+ os.chdir(in_path)
+ full_path = os.getcwd()
+ except IOError:
+ print("caught IO error ")
+ sys.exit()
+
+ os.chdir(cwd)
+ full_path = full_path + '/' + filename
+ if is_empty_file(full_path):
+ print("\nxml File is empty")
+ sys.exit()
+ else:
+ return full_path
+
+
+# -------------------------------------------------------
+# check is fpath is a file and empty
+# -------------------------------------------------------
+def is_empty_file(fpath):
+ return os.path.isfile(fpath) and os.path.getsize(fpath) == 0
+
+# -------------------------------------------------------
+# sort file names on the basis of time stamp
+# -------------------------------------------------------
+def sort_by_timestamp(file_name,file_path):
+ cwd = os.getcwd()
+ try :
+ os.chdir(file_path)
+ path = os.getcwd()
+ except IOError :
+ print("not a valid folder name--------------")
+ sys.exit()
+
+
+ Files = [path + '/' + file_name[i] for i in range(len(file_name))]
+ Files.sort(key=os.path.getmtime)
+ s_file_name = []
+ for i in range(len(Files)):
+ s_file_name.append(Files[i].split('/')[-1])
+
+ print("sorted list of files\n",s_file_name)
+ os.chdir(cwd)
+ return s_file_name
+
+# -----------------------------------------------------------------------------
+# helper for showing help information
+# -----------------------------------------------------------------------------
+def show_help():
+ print ('no of args you entered = ' + str(len(sys.argv) - 1))
+ print ('mpfs_configuration_generator.py :')
+ print (' This program reads xml hardware definition, outputs: header files')
+ print \
+ (' Usage: python3 mpfs_configuration_generator.py [xml file path] [output folder path] ')
+ print('path can be absolute as well as relative \n')
+ input(' Please run again with correct arguments')
+
+
+# -----------------------------------------------------------------------------
+# main function
+# todo: add options from the command line
+# -----------------------------------------------------------------------------
+def main_config_generator():
+ '''
+ This script takes an xml file which describes hardware options and produces
+ header files in the target directory which are used by the embedded
+ software.
+ Currently there are Two command line arguments
+ arg0: path to the folder containing xml file.
+ arg1: path of the folder where the fpga_design_config will be generated.
+ Note - If multiple xml files are present then the one with the latest time stamp
+ will be selected.
+
+ '''
+
+ #
+ # check/parse arguments
+ #
+ nb_arguments = len(sys.argv) - 1
+ if nb_arguments < 2:
+ show_help()
+ sys.exit()
+ fullCmdArguments = sys.argv
+ # - further arguments
+ argumentList = fullCmdArguments[1:]
+ input_xml_file = argumentList[0]
+ input_xml_file = get_full_path(input_xml_file)
+
+ if nb_arguments >= 2:
+ output_folder_name = argumentList[1]
+ output_folder_name = get_full_path(output_folder_name)
+ os.chdir(output_folder_name)
+
+ debug_reg_csv = False
+ if nb_arguments >= 4:
+ if argumentList[3] == 'debug_regs':
+ debug_reg_csv = True
+ if nb_arguments >= 3:
+ if argumentList[2] == 'generate_refernce_xml':
+ gen_xml = True
+ else:
+ gen_xml = False
+ #
+ # Check version of python interpreter, helps debugging
+ # Currently runs on python version 2 and 3
+ #
+ print ('python interpreter details:',sys.version_info)
+ if sys.version_info > (3, 0):
+ # # Python 3 code in this block
+ print ('python interpreter running is version 3')
+ else:
+ # # Python 2 code in this block
+ print ('python interpreter running is version 2')
+
+ # Create directory structure for the header files
+ #
+ root_folder = 'fpga_design_config'
+ TOP = ['clocks', 'ddr', 'io', 'memory_map', 'sgmii', 'general']
+ create_hw_dir_struct(root_folder, TOP)
+ #
+ # Next, read in XML content and create header files
+ #
+ generate_header_files(header_files, input_xml_file, xml_tags)
+ print('Hardware configuration header files created in directory:', os.path.join(output_folder_name, 'fpga_design_config'))
+
+if __name__ == "__main__":
+ main_config_generator()
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/.cproject b/driver-examples/mss-can/mpfs-can-full/.cproject
new file mode 100644
index 00000000..f083126e
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/.cproject
@@ -0,0 +1,1068 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/.gitignore b/driver-examples/mss-can/mpfs-can-full/.gitignore
new file mode 100644
index 00000000..65d718f0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/.gitignore
@@ -0,0 +1,8 @@
+/Debug*/
+/Release*/
+/core
+/LIM-Debug/
+/LIM-Release/
+/eNVM-Scratchpad-Release/
+/DDR-Release/
+/.settings/
diff --git a/driver-examples/mss-can/mpfs-can-full/.project b/driver-examples/mss-can/mpfs-can-full/.project
new file mode 100644
index 00000000..1b2eeee1
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/.project
@@ -0,0 +1,26 @@
+
+
+ mpfs-can-full
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/README.md b/driver-examples/mss-can/mpfs-can-full/README.md
new file mode 100644
index 00000000..17b3a584
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/README.md
@@ -0,0 +1,77 @@
+# PolarFire SoC MSS Full CAN example
+
+This example project demonstrates using the MSS CAN peripheral to perform CAN
+message transmission and reception. The MSS CAN driver has APIs for BasicCAN and
+FullCAN Configurations. This project is configured for FullCAN communication.
+
+The operation of the MSS CAN is controlled via a serial console.
+
+## How to use this example
+
+On connecting Icicle kit J11 to the host PC, you should see 4 COM port interfaces.
+To use this project, configure the COM port **interface1** as below:
+ - 115200 baud
+ - 8 data bits
+ - 1 stop bit
+ - no parity
+ - no flow control
+
+This is a self contained example project. A greeting message is displayed
+over the UART terminal. On startup, the example project requests the user to
+enter the data to be send via the CAN Bus. You can enter up to 32 pairs of hex
+digits (no separating spaces) and the data will be sent out in chunks of 8
+bytes at a time in up to 4 CAN packets. You can send less than 32 bytes of
+data by pressing return to terminate the data early.
+
+The test program then enters a loop looking for user input to select the next
+action to perform. Whilst in this loop, the data portion of any CAN Bus packets
+received into the rx buffers is displayed on the console. The following menu
+options are available:
+
+ 0 - Perform a hardware reset of the MSS CAN peripheral via SYSREG. This
+ shuts down all CAN communications.
+ 5 - Reinitailze the MSS CAN peripheral then get data from user and send via
+ CAN Bus.
+ 7 - Get data from user and send via CAN Bus.
+
+The following macros modify the behaviour of the program:
+
+ CAN_TX_EXTENDED_ID - Defining this macro causes CAN messages with
+ with extended 29 bit IDs to be sent instead of
+ the standard 11 bit IDs.
+ CAN_TARGET_COCO_PC_ACTIVE - Defining this macro adjusts the baud rate to
+ enable reliable operation with the Kromschroder
+ CoCo PC Active CAN Bus interface.
+
+Jumper settings:
+Connect CAN-0 and PCAN as mentioned below:
+
+ | CAN-0 J27 | PCAN | Description |
+ |---------------|--------- |--------------|
+ | 1 | 7 | CAN_H |
+ | 2 | 2 | CAN_L |
+ | 3 | 6 | GND |
+
+## Test CAN Message Transmission
+ 1. Enter the data on UART terminal, which will be received through MSSUART1.
+ 2. Based on received data bytes, segregate as CAN messages of maximum 8
+ bytes length.
+ 3. Send the received data in terms of CAN messages.
+ 4. Observe the CAN messages on CAN Analyzer with message identifier as 0x78.
+ 5. Compare the data received on CAN Analyzer with the data sent from the
+ UART terminal data should be same.
+
+## Test CAN Message Reception
+ 1. Send the 8 bytes of CAN message from CAN Analyzer with message identifier
+ as 0x80.
+ 2. Read the data using CAN APIs and store it in to RAM buffer.
+ 3. Transmit the data using MSSUART1 on to UART terminal.
+ 4. Observe the data received on UART terminal.
+ 5. Compare the data sent from CAN Analyzer with the data received on
+ UART terminal data should be same.
+
+This project provides build configurations and debug launchers as exaplained
+[here](https://github.com/polarfire-soc/polarfire-soc-bare-metal-examples/blob/main/README.md)
+
+The design description file with this clock setting is available at ./src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
+This project can be tested with standard Libero reference design. However, please make sure that the input clock to MSS CAN block is set to 8MHz in xml.
diff --git a/driver-examples/mss-can/mpfs-can-full/mpfs-can-full hw all-harts attach.launch b/driver-examples/mss-can/mpfs-can-full/mpfs-can-full hw all-harts attach.launch
new file mode 100644
index 00000000..33512d70
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/mpfs-can-full hw all-harts attach.launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/mpfs-can-full hw all-harts debug.launch b/driver-examples/mss-can/mpfs-can-full/mpfs-can-full hw all-harts debug.launch
new file mode 100644
index 00000000..53ee9e48
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/mpfs-can-full hw all-harts debug.launch
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/application/hart0/e51.c b/driver-examples/mss-can/mpfs-can-full/src/application/hart0/e51.c
new file mode 100644
index 00000000..a14b792a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/application/hart0/e51.c
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on E51.
+ *
+ * Please refer to README.md file for more details
+ */
+
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h0 = 0U;
+
+/* Main function for the hart0(E51 processor).
+ * Application code running on hart1 is placed here
+ *
+ * The hart1 is in WFI while booting, hart0 brings it out of WFI when it raises
+ * the first Software interrupt.
+ */
+void e51(void)
+{
+ uint8_t flag = 0u;
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ (void)mss_config_clk_rst(MSS_PERIPH_MMUART0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
+
+ MSS_UART_init( &g_mss_uart0_lo,
+ MSS_UART_115200_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx_string(&g_mss_uart0_lo ,
+ (const uint8_t*)"\r\nPlease observe UART-1 for application messages\r\n");
+
+ /* Raise software interrupt to wake hart 1 */
+ raise_soft_interrupt(1U);
+
+ __enable_irq();
+
+ while (1U)
+ {
+ icount++;
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ }
+ }
+ /* never return */
+}
+
+/* hart0 Software interrupt handler */
+void Software_h0_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h0++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/application/hart1/u54_1.c b/driver-examples/mss-can/mpfs-can-full/src/application/hart1/u54_1.c
new file mode 100644
index 00000000..eeb4d2f2
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/application/hart1/u54_1.c
@@ -0,0 +1,543 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_1
+ *
+ * PolarFire SoC MSS CAN example demonstrating the Data Transmission and
+ * Reception using MSSCAN (FullCAN).
+ * For Transmission: Get data from UART terminal using MSSUART1 --> Form as CAN
+ * packets --> Send to CAN Analyzer.
+ * For Reception: Send the CAN Message from CAN Analyzer --> Read the Message-->
+ * Send to UART terminal using MSSUART1.
+ * Board settings and test procedure clearly mentioned in README.md file.
+ */
+
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "drivers/mss/mss_can/mss_can.h"
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+/*------------------------------------------------------------------------------
+ * Macros.
+ */
+#define ENTER 0x0DU
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ */
+static void display_greeting(void);
+static uint8_t get_data_frm_uart(void);
+static void display_hex_values(const uint8_t *, uint32_t);
+static void ascii_to_hex(uint8_t *, uint32_t );
+static void display_option(void);
+static void check_rx_buffer(void);
+
+/*------------------------------------------------------------------------------
+ * Static Variables.
+ */
+static uint8_t g_uart_to_can[32];
+static uint8_t g_temp[64];
+static uint8_t g_can_to_uart[8];
+
+/*------------------------------------------------------------------------------
+ * Global Variables.
+ */
+mss_can_filterobject pfilter;
+mss_can_msgobject pmsg;
+mss_can_msgobject rx_buf;
+mss_can_rxmsgobject rx_msg;
+
+/*------------------------------------------------------------------------------
+ * MSS UART instance for UART1
+ */
+uint64_t uart_lock;
+
+mss_can_instance_t* g_mss_can_0 = &g_mss_can_0_lo;
+mss_uart_instance_t *g_uart = &g_mss_uart1_lo;
+
+/* Main function for the HART1(U54_1 processor).
+ * Application code running on HART1 is placed here
+ *
+ * The HART1 goes into WFI. HART0 brings it out of WFI when it raises the first
+ * Software interrupt to this HART
+ */
+void u54_1(void)
+{
+ volatile uint8_t count = 0u;
+ int32_t error_flag;
+ uint8_t rx_bytes = 0u;
+ uint8_t no_of_msgs = 0u;
+ size_t rx_size;
+ uint8_t rx_char;
+ uint8_t loop_count;
+ uint32_t msg_len;
+ uint32_t chunk_size;
+ uint8_t init_return_value = 0u;
+ uint32_t tx_status = 0u;
+ uint8_t ret_status;
+
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+#endif
+
+ /* The hart is out of WFI, clear the SW interrupt. Here onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ (void)mss_config_clk_rst(MSS_PERIPH_MMUART1, (uint8_t) 1, PERIPHERAL_ON);
+ (void)mss_config_clk_rst(MSS_PERIPH_CAN0, (uint8_t) 1, PERIPHERAL_ON);
+
+ PLIC_DisableIRQ(CAN0_PLIC);
+
+ PLIC_init();
+ __enable_irq();
+
+ MSS_UART_init(g_uart,
+ MSS_UART_115200_BAUD,
+ (MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY |
+ MSS_UART_ONE_STOP_BIT));
+
+ /*--------------------------------------------------------------------------
+ * Performs CAN Initialization and Message Buffer Configuration
+ */
+#ifdef CAN_TARGET_COCO_PC_ACTIVE
+ /*
+ * Tweaked 20kbs configuration for a 16MHz PCLK1 which works with the
+ * CoCo PC Active device to allow transmit and receive functionality be
+ * observed.
+ *
+ * The sample design used for this test had a 100MHz GL0 clock derived from
+ * the internal 25/50MHz source to generate a 128MHz processor clock which
+ * was divided by 8 to give a 16MHz PCLK1.
+ *
+ * This configuration uses 16 time quanta per bit. The standard 20kbs
+ * divisor should give 50uS per bit but in this design I was seeing a 50.5uS
+ * bit time which did not allow the MSS CAN receive data from the CoCo PC
+ * Active which had a bit time in the region of 49.5uS to 50uS. Reducing the
+ * divisor from 49 to 48 (to give divide by 49 instead of divide by 50) gave
+ * an MSS CAN bit time of 49.5uS and allowed reliable communications in both
+ * directions.
+ */
+ MSS_CAN_init(&g_mss_can_0,
+ CAN_SET_BITRATE(48)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES,
+ (PCAN_CONFIG_REG)0,
+ 6,
+ 6);
+#else
+ /* ----------------------- CAN - 0 Initialization ----------------- */
+ init_return_value = MSS_CAN_init(g_mss_can_0, CAN_SPEED_8M_1M,
+ (pmss_can_config_reg)0, 6u, 6u);
+ MSS_CAN_set_mode(g_mss_can_0, CANOP_MODE_NORMAL);
+ MSS_CAN_start(g_mss_can_0);
+#endif
+
+ /* Display greeting message */
+ display_greeting();
+
+ /* Clear receive buffer */
+ for (count = 0u; count < 8u; count++)
+ {
+ rx_buf.DATA[count] = 0u;
+ }
+
+ /* Configure for transmit */
+ pmsg.ID = 0x78u;
+ pmsg.DATALOW = 0xAAAAAAAAu;
+ pmsg.DATAHIGH = 0x55555555u;
+#ifdef CAN_TX_EXTENDED_ID
+ pmsg.L =((1<<20) | 0x00080000u); /* Extended ID, 8 bytes of data */
+#else
+ pmsg.L = 0x00080000u; /* Standard ID, 8 bytes of data */
+#endif
+
+ /* Configure for receive */
+ /* Initialize the rx mailbox */
+ rx_msg.ID = 0x80u;
+ rx_msg.DATAHIGH = 0u;
+ rx_msg.DATALOW = 0u;
+ /*
+ * use very broad masks here as we want to see any potential traffic for the
+ * demo to reduce the chances of failure. You can tweak these to do proper
+ * filtering if you know what traffic is available on your specific CAN Bus
+ * network.
+ */
+ rx_msg.AMR.L = 0xFFFFFFFFu;
+ rx_msg.ACR.L = 0x00000000u;
+ rx_msg.AMR_D = 0xFFFFFFFFu;
+ rx_msg.ACR_D = 0x00000000u;
+ rx_msg.RXB.DLC = 8u;
+ rx_msg.RXB.IDE = 0u;
+
+ ret_status = MSS_CAN_config_buffer_n(g_mss_can_0, 0, &rx_msg);
+ if (CAN_OK != ret_status)
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rMessage Buffer configuration Error");
+ }
+
+ MSS_CAN_send_message_n(g_mss_can_0, 0u, &pmsg);
+
+ while (1)
+ {
+ /*----------------------------------------------------------------------
+ * Read the Data from UART and Transmit using CAN
+ */
+ rx_bytes = get_data_frm_uart();
+
+ /* Convert ASCII values to Hex */
+ ascii_to_hex(g_temp, rx_bytes);
+
+ for (loop_count = 0u; loop_count < rx_bytes / 2u; loop_count++)
+ {
+ g_uart_to_can[loop_count] = g_temp[loop_count * 2u];
+ g_uart_to_can[loop_count] = g_uart_to_can[loop_count] << 4u;
+ g_uart_to_can[loop_count] |= g_temp[(loop_count * 2u) + 1u];
+ }
+ MSS_UART_polled_tx_string(g_uart,
+ (const uint8_t *)"\n\rData transmitted as CAN Message ");
+ display_hex_values(g_uart_to_can, loop_count);
+
+ /*------------------------------------------------------------------
+ * Identify the number of messages to transmit based on rx_bytes
+ */
+ no_of_msgs = rx_bytes / 16u;
+ if ((rx_bytes % 16u) != 0u)
+ {
+ no_of_msgs = no_of_msgs + 1u;
+ }
+
+ if (0u == loop_count) /* Allow sending an empty packet */
+ {
+ no_of_msgs = 1u;
+ }
+
+ count = 0u;
+
+ msg_len = loop_count;
+ error_flag = 0u;
+ while ((no_of_msgs != 0u) && (0u == error_flag))
+ {
+ /* Pack up to 8 bytes into this packet in 2 x 32bit chunks */
+ if (msg_len >= 8u)
+ {
+ chunk_size = 8u;
+ }
+ else
+ {
+ chunk_size = msg_len;
+ }
+
+ for (loop_count = 0u; loop_count < chunk_size; loop_count++)
+ {
+ if (loop_count < 4u)
+ {
+ pmsg.DATA[3u - loop_count] = \
+ g_uart_to_can[loop_count +(count * 8u)];
+ }
+ else
+ {
+ pmsg.DATA[11u - loop_count] = \
+ g_uart_to_can[loop_count +(count * 8u)];
+ }
+ }
+
+ pmsg.DLC = chunk_size;
+ ret_status = MSS_CAN_send_message_n(g_mss_can_0, 0u, &pmsg);
+ if (CAN_VALID_MSG != ret_status)
+ {
+ error_flag = 1u; /* Didn't succeed in sending packet... */
+ }
+ else
+ {
+ /* Wait around for this packet to send before going any
+ * further */
+ tx_status = MSS_CAN_get_tx_buffer_status(g_mss_can_0);
+ while (1u == (tx_status & 1))
+ {
+ tx_status = MSS_CAN_get_tx_buffer_status(g_mss_can_0);
+ }
+
+ no_of_msgs--;
+ msg_len -= chunk_size;
+ count++;
+ }
+ }
+
+ if (0u == count) /* Nothing sent */
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rUnable to send data via CAN Bus");
+ }
+ else
+ {
+ if (0u == error_flag) /* Everything sent */
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rObserve the data received on CAN Analyzer");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rIt should be same as the data transmitted from UART terminal");
+ }
+ else /* Some error occurred */
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rObserve the data Received on CAN Analyzer");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rSome transmission error(s) were detected.");
+ }
+ }
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r------------------------------------------------------------------------------");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\rPress any key to continue...");
+
+ do {
+ rx_size = MSS_UART_get_rx(g_uart, &rx_char, sizeof(rx_char));
+ } while (rx_size == 0u);
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+
+ /*----------------------------------------------------------------------
+ * Display options
+ */
+ display_option();
+ }
+
+}
+
+
+static void check_rx_buffer(void)
+{
+ uint8_t loop_count;
+
+ /*----------------------------------------------------------------------
+ * Read the Data from CAN channel and transmit through UART
+ */
+ if (CAN_VALID_MSG == MSS_CAN_get_message_n(g_mss_can_0, 0u, &rx_buf))
+ {
+ for (loop_count = 0u; loop_count < rx_buf.DLC; loop_count++)
+ {
+ if (loop_count < 4u)
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[3u - loop_count];
+ }
+ else
+ {
+ g_can_to_uart[loop_count] = rx_buf.DATA[11u - loop_count];
+ }
+ }
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************************************************************************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rData Received as CAN Message is ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+
+ /* Send to UART */
+ display_hex_values(g_can_to_uart, rx_buf.DLC);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rObserve the message sent from the CAN Analyzer ");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rIt should be same as message Received on UART terminal");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************************************************************************\n\r");
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Receive data from UART terminal.
+ */
+static uint8_t get_data_frm_uart(void)
+{
+ uint8_t complete = 0;
+ uint8_t rx_buff[1];
+ uint8_t count = 0;
+ uint8_t rx_size = 0;
+
+ for (count = 0u; count < 32u; count++)
+ {
+ g_uart_to_can[count] = 0u;
+ }
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rEnter the data to transmit through the CAN Channel:\n\r");
+
+ count = 0u;
+ while (!complete)
+ {
+ rx_size = MSS_UART_get_rx(g_uart, rx_buff, sizeof(rx_buff));
+ if(rx_size > 0u)
+ {
+ MSS_UART_polled_tx(g_uart, rx_buff, sizeof(rx_buff));
+
+ if (ENTER == rx_buff[0])
+ {
+ complete = 1u;
+ }
+ else
+ {
+ if (count % 2u == 0u)
+ {
+ g_temp[count] = rx_buff[0];
+ }
+ else
+ {
+ g_temp[count] = rx_buff[0];
+ }
+ count++;
+ }
+
+ if (64u == count)
+ {
+ complete = 1u;
+ }
+ }
+ }
+ return(count);
+}
+
+/*------------------------------------------------------------------------------
+ * Display greeting message when application is started.
+ */
+static void display_greeting(void)
+{
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************************************************************************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"*********** PolarFire SoC MSS CAN Driver Example (FullCAN Mode) **************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"******************************************************************************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Example project Demonstrates the using of MSS CAN Transmission and Reception \n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"------------------------------------------------------------------------------\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Read data from the UART1 and Transmit as CAN message using MSS CAN\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"------------------------------------------------------------------------------\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Receive the CAN Message from MSS CAN channel and send this to UART1\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"******************************************************************************\n\r");
+}
+
+/*------------------------------------------------------------------------------
+ * Display content of buffer passed as parameter as hex values.
+ */
+static void display_hex_values
+(
+ const uint8_t * in_buffer,
+ uint32_t byte_length
+)
+{
+ uint8_t display_buffer[128];
+ uint32_t inc;
+
+ if (0u == byte_length)
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+ }
+ else
+ {
+ if (byte_length > 16u)
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+ }
+
+ for (inc = 0u; inc < byte_length; ++inc)
+ {
+ if ((inc > 1u) && (0u == (inc % 16u)))
+ {
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r");
+ }
+ snprintf((char *)display_buffer, sizeof(display_buffer), "%02x ", in_buffer[inc]);
+ MSS_UART_polled_tx_string(g_uart, display_buffer);
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Converts ASCII values to HEX values
+ */
+static void ascii_to_hex
+(
+ uint8_t * in_buffer,
+ uint32_t byte_length
+)
+{
+ uint32_t inc;
+
+ for (inc = 0u; inc < byte_length; inc++)
+ {
+ if ((in_buffer[inc] <= 0x39u) && (in_buffer[inc] >= 0x30u))
+ {
+ in_buffer[inc] = in_buffer[inc] - 0x30u;
+ }
+ else if ((in_buffer[inc] <= 0x5Au) && (in_buffer[inc] >= 0x41u))
+ {
+ in_buffer[inc] = 0x0Au + in_buffer[inc] - 0x41u;
+ }
+ else if ((in_buffer[inc] <= 0x7Au) && (in_buffer[inc] >= 0x61u))
+ {
+ in_buffer[inc] = 0x0au + (in_buffer[inc] - 0x61u);
+ }
+ else
+ {
+ ;/* Do Nothing. */
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Display the Option to continue or exit.
+ */
+static void display_option(void)
+{
+ uint8_t rx_size=0;
+ uint8_t rx_buff[1];
+
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"\n\r******************* Select the Option to proceed further *********************\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Press Key '7' to send data.\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Press Key '5' to reinitalize MSS CAN device.\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"Press Key '0' to reset the MSS CAN device using SYSREG.\n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t*)"******************************************************************************\n\r");
+ do
+ {
+ /* Start command line interface if any key is pressed. */
+ rx_size = MSS_UART_get_rx(g_uart, rx_buff, sizeof(rx_buff));
+ if (rx_size > 0u)
+ {
+ switch(rx_buff[0])
+ {
+ case '7':
+ break;
+
+ case '5':
+#ifdef CAN_TARGET_COCO_PC_ACTIVE
+ /*
+ * Tweaked 20kbs configuration for a 16MHz PCLK1 which works with the
+ * CoCo PC Active device to allow transmit and receive functionality be
+ * observed. See comment in main() for details.
+ */
+ MSS_CAN_init(g_mss_can_0,
+ CAN_SET_BITRATE(48)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES,
+ (PCAN_CONFIG_REG)0,
+ 6,
+ 6);
+#else
+ MSS_CAN_init(g_mss_can_0, CAN_SPEED_16M_1M,
+ (pmss_can_config_reg)0, 6u, 6u);
+#endif
+ MSS_CAN_set_mode(g_mss_can_0, CANOP_MODE_NORMAL);
+ MSS_CAN_start(g_mss_can_0);
+ MSS_CAN_config_buffer_n(g_mss_can_0, 0, &rx_msg);
+ break;
+
+ case '0':
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rCAN Controller has been reset: \n\r");
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rNo more Data transfer through CAN: \n\r");
+ MSS_CAN_set_mode(g_mss_can_0, CANOP_SW_RESET);
+ MSS_UART_polled_tx_string(g_uart, (const uint8_t *)"\n\rPress Key '5' to re-initialize the CAN Controller \n\r");
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ * Read the Data from CAN channel and Transmit Through UART1
+ */
+ check_rx_buffer();
+
+ }while ((rx_buff[0]!= '7') & (rx_buff[0]!= '5'));
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/application/hart2/u54_2.c b/driver-examples/mss-can/mpfs-can-full/src/application/hart2/u54_2.c
new file mode 100644
index 00000000..2e8c0501
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/application/hart2/u54_2.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_2
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h2 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart2(U54_2 processor).
+ * Application code running on hart2 is placed here
+ *
+ * The hart2 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart
+ */
+void u54_2(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart2 Software interrupt handler */
+void Software_h2_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h2++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/application/hart3/u54_3.c b/driver-examples/mss-can/mpfs-can-full/src/application/hart3/u54_3.c
new file mode 100644
index 00000000..2ec3349a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/application/hart3/u54_3.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_3
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h3 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart3(U54_3 processor).
+ * Application code running on hart3 is placed here
+ *
+ * The hart3 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart.
+ */
+void u54_3(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ }while(0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart3 software interrupt handler */
+void Software_h3_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h3++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/application/hart4/u54_4.c b/driver-examples/mss-can/mpfs-can-full/src/application/hart4/u54_4.c
new file mode 100644
index 00000000..d70724e8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/application/hart4/u54_4.c
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Application code running on U54_4
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "inc/common.h"
+
+volatile uint32_t count_sw_ints_h4 = 0U;
+
+extern mss_uart_instance_t *g_uart;
+
+/* Main function for the hart4(U54_4 processor).
+ * Application code running on hart4 is placed here
+ *
+ * The hart4 goes into WFI. hart0 brings it out of WFI when it raises the first
+ * Software interrupt to this hart.
+ */
+void u54_4(void)
+{
+ char info_string[100];
+ volatile uint32_t icount = 0U;
+ uint64_t hartid = read_csr(mhartid);
+ uint32_t pattern_offset = 12U;
+ HLS_DATA* hls = (HLS_DATA*)(uintptr_t)get_tp_reg();
+ HART_SHARED_DATA * hart_share = (HART_SHARED_DATA *)hls->shared_mem;
+
+ /* Clear pending software interrupt in case there was any.
+ * Enable only the software interrupt so that the E51 core can bring this
+ * core out of WFI by raising a software interrupt. */
+ clear_soft_interrupt();
+ set_csr(mie, MIP_MSIP);
+
+ /* Put this hart in WFI. */
+ do
+ {
+ __asm("wfi");
+ } while (0 == (read_csr(mip) & MIP_MSIP));
+
+ /* The hart is out of WFI, clear the SW interrupt. Hear onwards Application
+ * can enable and use any interrupts as required */
+ clear_soft_interrupt();
+
+ __enable_irq();
+
+ sprintf(info_string, "\r\nHart %u, HLS mem address 0x%lx, Shared mem 0x%lx\r\n",\
+ hls->my_hart_id, (uint64_t)hls, (uint64_t)hls->shared_mem);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(g_uart, (const uint8_t*)info_string,(uint32_t)strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+
+ while (1U)
+ {
+ icount++;
+
+ if (0x100000U == icount)
+ {
+ icount = 0U;
+ sprintf(info_string,"Hart %d\r\n", hartid);
+ spinlock(&hart_share->mutex_uart0);
+ MSS_UART_polled_tx(&g_mss_uart0_lo, info_string, strlen(info_string));
+ spinunlock(&hart_share->mutex_uart0);
+ }
+ }
+ /* never return */
+}
+
+/* hart4 software interrupt handler */
+void Software_h4_IRQHandler(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+ count_sw_ints_h4++;
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/application/inc/common.h b/driver-examples/mss-can/mpfs-can-full/src/application/inc/common.h
new file mode 100644
index 00000000..80c76203
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/application/inc/common.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef COMMON_H_
+#define COMMON_H_
+
+#include
+#include "drivers/mss/mss_mmuart/mss_uart.h"
+
+typedef enum COMMAND_TYPE_
+{
+ CLEAR_COMMANDS = 0x00, /*!< 0 default behavior */
+ START_HART1_U_MODE = 0x01, /*!< 1 u mode */
+ START_HART2_S_MODE = 0x02, /*!< 2 s mode */
+} COMMAND_TYPE;
+
+
+typedef enum MODE_CHOICE_
+{
+ M_MODE = 0x00, /*!< 0 m mode */
+ S_MODE = 0x01, /*!< s mode */
+} MODE_CHOICE;
+
+
+typedef struct HART_SHARED_DATA_
+{
+ uint64_t init_marker;
+ volatile long mutex_uart0;
+ mss_uart_instance_t *g_mss_uart0_lo;
+} HART_SHARED_DATA;
+
+/**
+ * extern variables
+ */
+
+/**
+ * functions
+ */
+void jump_to_application(HLS_DATA* hls, MODE_CHOICE mode_choice, uint64_t next_addr);
+void
+uart_tx_with_mutex
+(
+ mss_uart_instance_t * this_uart,
+ uint64_t mutex_addr,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+void
+uart_tx_string_with_mutex
+(
+ mss_uart_instance_t * this_uart,
+ uint64_t mutex_addr,
+ const uint8_t * pbuff
+);
+
+#endif /* COMMON_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
new file mode 100644
index 00000000..7e0a4bc5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/fpga_design/design_description/ICICLE_MSS_CAN_8MHz.xml
@@ -0,0 +1,4024 @@
+
+
+ 2021.1
+ ICICLE_MSS
+ MPFS250T_ES
+ FCVG484
+ 06-22-2021_18:26:34
+ 0.5.3
+
+
+
+
+
+
+ 0x1
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0xB
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x4
+
+
+
+
+
+
+ 0x00
+ 0x0
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+
+
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+ 0x00
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0x9F
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xFFFFFFFFFFFFFFFF
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+ 0xFFFFFFFFF
+ 0x0
+ 0x1F
+
+
+
+
+
+
+ 0
+
+
+ 220
+
+
+ 0
+
+
+ 511
+
+
+
+
+
+
+
+
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0xF
+ 0xF
+
+
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+
+
+ 0x4
+ 0x4
+ 0x4
+ 0x4
+ 0xC
+ 0xC
+ 0x8
+ 0x8
+
+
+ 0x2
+ 0x2
+ 0x2
+ 0x2
+ 0x7
+ 0x7
+ 0x7
+ 0xF
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0xD
+ 0x00
+ 0xA
+ 0x0
+ 0x4
+ 0x0
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x0928
+ 0x0928
+
+
+ 0x7
+ 0x00
+ 0x9
+ 0x0
+ 0x8
+ 0x0
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0829
+ 0x0829
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x3F
+ 0x00
+ 0x3F
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x3F
+ 0x00
+ 0x3F
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x2
+ 0x9
+ 0x1
+ 0x1
+ 0x00
+ 0x1
+ 0x1
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x14
+ 0x0
+ 0x2
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x7
+ 0x7
+ 0x7
+ 0x0
+ 0x0
+ 0x0
+ 0x4
+ 0x7
+ 0x7
+ 0x3
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x7
+ 0x7
+ 0x7
+ 0x0
+ 0x0
+ 0x0
+ 0x4
+ 0x7
+ 0x7
+ 0x3
+ 0x0
+
+
+ 0x8
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x0
+
+
+
+
+
+
+
+
+
+
+ 0x0
+ 0x3
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0xf000
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x0
+ 0x0
+
+
+ 0xFF000000
+
+
+
+
+
+
+
+
+
+
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x2
+ 0x5
+ 0x0
+ 0x7F
+ 0x1F
+
+
+ 0x02
+
+
+
+
+
+
+ 0x2
+ 0x2
+ 0x1
+ 0x0
+ 0xC
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x6
+
+
+ 0x6
+
+
+ 0x2
+
+
+ 0x2
+
+
+ 0x5
+
+
+ 0x5
+
+
+ 0x7
+
+
+ 0x7
+
+
+ 0x7
+
+
+ 0x3
+
+
+ 0x4
+
+
+ 0x3
+
+
+ 0x4
+
+
+ 0x8000
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+
+
+
+
+
+
+ 0x4
+ 0x0
+ 0x0
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x2
+ 0x2
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x4
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x7F80
+ 0x0
+ 0x1
+
+
+ 0x7030
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x7FB0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x1
+
+
+ 0x7FA0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x1
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+
+
+ 0x00001D
+
+
+ 0x00000000
+
+
+ 0x00000004
+
+
+ 0x0000000A
+
+
+ 0x00C2CA
+
+
+ 0x0
+
+
+ 0x9140F38D
+
+
+ 0x75955134
+
+
+ 0x71B69961
+
+
+ 0x000
+
+
+ 0x440C2040
+
+
+ 0x02481C61
+
+
+ 0x00000000
+
+
+ 0x00000140
+
+
+ 0x000000A0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x6
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x00000001
+
+
+ 0x00000016
+
+
+ 0x00000016
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000005
+
+
+ 0x00000006
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000004
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000003
+
+
+ 0x00000006
+
+
+ 0x00000036
+
+
+ 0x00000036
+
+
+ 0x00000036
+
+
+ 0x0
+
+
+ 0x81881881
+
+
+ 0x00008818
+
+
+ 0xa92a92a9
+
+
+ 0x00002a92
+
+
+ 0xc28c28c2
+
+
+ 0x00008c28
+
+
+ 0xea2ea2ea
+
+
+ 0x00002ea2
+
+
+ 0x03903903
+
+
+ 0x00009039
+
+
+ 0x2b32b32b
+
+
+ 0x000032b3
+
+
+ 0x44944944
+
+
+ 0x00009449
+
+
+ 0x6c36c36c
+
+
+ 0x000036c3
+
+
+ 0x85985985
+
+
+ 0x00009859
+
+
+ 0xad3ad3ad
+
+
+ 0x00003ad3
+
+
+ 0xc69c69c6
+
+
+ 0x00009c69
+
+
+ 0xee3ee3ee
+
+
+ 0x00003ee3
+
+
+ 0x07a07a07
+
+
+ 0x0000a07a
+
+
+ 0x2f42f42f
+
+
+ 0x000042f4
+
+
+ 0x48a48a48
+
+
+ 0x0000a48a
+
+
+ 0x70470470
+
+
+ 0x00004704
+
+
+ 0x00000000
+
+
+ 0x00000048
+
+
+ 0x0000002C
+
+
+ 0x00000020
+
+
+ 0x00000004
+
+
+ 0x00000010
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x22
+
+
+ 0xF
+
+
+ 0x8
+
+
+ 0x11
+
+
+ 0x33
+
+
+ 0x20
+
+
+ 0x130
+
+
+ 0x8
+
+
+ 0x10
+
+
+ 0x8
+
+
+ 0x0
+
+
+ 0x6
+
+
+ 0x1F
+
+
+ 0x5
+
+
+ 0xF
+
+
+ 0xF
+
+
+ 0xF
+
+
+ 0x1F
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x7
+
+
+ 0xC
+
+
+ 0x0
+
+
+ 0x6
+
+
+ 0x0
+
+
+ 0x2
+
+
+ 0x0
+
+
+ 0xC34
+
+
+ 0x27100
+
+
+ 0xA
+
+
+ 0x10
+
+
+ 0x3
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0xC
+
+
+ 0x5
+
+
+ 0x00000200
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x27100
+
+
+ 0x0
+
+
+ 0x400
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x640
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x28
+
+
+ 0x8
+
+
+ 0xA
+
+
+ 0x00000000
+
+
+ 0x8
+
+
+ 0xE
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x1
+
+
+ 0x2
+
+
+ 0x4
+
+
+ 0x18
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x320
+
+
+ 0x12
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000008
+
+
+ 0x0000000b
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000001
+
+
+ 0x000000FF
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x0
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x15
+
+
+ 0x6
+
+
+ 0x3
+
+
+ 0x00000001
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x7FFFFFFF
+
+
+ 0x0
+
+
+ 0x7FFFFFFF
+
+
+ 0x0
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x8001
+
+
+ 0x1
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x3F
+
+
+ 0x3F
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+ 0x18
+
+
+ 0x00000000
+
+
+ 0x1
+
+
+ 0x00000000
+
+
+ 0x00000000
+
+
+
+
+
+
+
+
+ 125000000
+
+
+ 600000000
+
+
+ 600000000
+
+
+ 1000000
+
+
+ 300000000
+
+
+ 150000000
+
+
+
+
+
+
+ 0x0
+ 0x1
+ 0x2
+
+
+ 0x7D
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x1
+ 0x40
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x5
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x4B
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x60
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x2
+ 0x4
+ 0x6
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x14
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ DDR3
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x5
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x1
+ 0x0
+ 0x8
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x6
+ 0x0
+ 0x0
+ 0x0
+ 0xd
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x2
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x80
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x8
+ 0x10
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x1
+ 0x0
+ 0x0
+
+
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+ 0x1
+ 0x1
+ 0x0
+
+
+ 0x5
+
+
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x0
+ 0x0
+ 0x3
+ 0x0
+ 0x1
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
+
+
+
+ 0x3
+ 0x0
+ 0x7
+ 0x0
+ 0xF
+ 0x0
+
+
+ 0x0
+ 0x0
+ 0x0
+ 0x0
+
+
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt
new file mode 100644
index 00000000..d05a6a92
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/drivers_config/readme.txt
@@ -0,0 +1,5 @@
+contains user configuration of the drivers.
+drivers config should follow the following format:
+platform/config/drivers//_sw_cfg.h
+e.g
+platform/config/drivers/ddr/ddr_sw_cfg.h
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld
new file mode 100644
index 00000000..2ab464f3
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-ddr-loaded-by-boot-loader.ld
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-ddr-loaded-by-boot-loader.ld
+ * Use this linker script when the program is fully located in DDR. The
+ * assumption is DDR has already been initialized by another program.
+ * This linker script can be used with a debugger or when compiled and loaded
+ * by a boot-loader.
+ * Please see the project mpfs-hal-run-from-ddr-1 located in the Bare Metal
+ * library under examples/mpfs-hal for an example of it use.
+ * https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+HEAP_SIZE = 0k; /* needs to be calculated for your application if using */
+
+/*
+ * Stack size for our single hart U54 application.
+ */
+STACK_SIZE_U54_APPLICATION = 8k;
+
+/*
+ * A small amount of unitialised memory used to store information
+ * obtained from the boot-loader on start-up
+ */
+UNITITALISED_MEM = 16B;
+
+/* reset address 0xC0000000 */
+SECTION_START_ADDRESS = 0x80000000;
+
+
+SECTIONS
+{
+
+ /* text: test code section */
+ . = SECTION_START_ADDRESS;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > ddr_cached_32bit
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> ddr_cached_32bit
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > ddr_cached_32bit
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > ddr_cached_32bit
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > ddr_cached_32bit
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > ddr_cached_32bit
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__app_stack_bottom = .);
+ . += STACK_SIZE_U54_APPLICATION;
+ PROVIDE(__app_stack_top = .);
+ } > ddr_cached_32bit
+
+ /*
+ * used by a program loaded by a bootloader to store information passed
+ * from boot-loader
+ * a0 holds the hart ID
+ * a1 hold pointer to device data, which includes pointer to shared memory
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .no_init : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ . += UNITITALISED_MEM;
+ PROVIDE(__uninit_top_h$ = .);
+ /*
+ * following not used but need to be provided for compilation
+ */
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__stack_top_h0$ = .);
+ PROVIDE(__stack_top_h1$ = .);
+ PROVIDE(__stack_top_h2$ = .);
+ PROVIDE(__stack_top_h3$ = .);
+ PROVIDE(__stack_top_h4$ = .);
+ } > ddr_cached_32bit
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..45b2bba6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm-lma-scratchpad-vma.ld
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma-envm.ld
+ * Code starts from eNVM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * The startup stack size is used on start-up.
+ * The application stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >envm
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> envm /* On the MPFS for startup code use, >switch_code AT>envm */
+}
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld
new file mode 100644
index 00000000..cf28ec03
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-envm.ld
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_envm.ld
+ * Use with Bare metal startup code.
+ * Startup code runs from envm on MSS reset
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1K of DTIM is used to run code when switching the envm clock */
+ switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+STACK_SIZE_PER_HART = 8k;
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ /* *entry.o(.text); */
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } > envm
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> envm
+
+ /*
+ * The .ram_code section will contain the code that is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code_dtim AT>envm
+
+ /*
+ * The .ddr_code section will contain the code that is run from DDR.
+ * This is to verify DDR working as expeted
+ */
+ .ddr_code :
+ {
+ . = ALIGN (4);
+ __ddr_load = LOADADDR (.ram_code);
+ __ddr_start = .;
+ *(.ddr_codetext) /* .ram_codetext sections (code) */
+ *(.ddr_codetext*) /* .ram_codetext* sections (code) */
+ *(.ddr_coderodata) /* read-only data (constants) */
+ *(.ddr_coderodata*)
+ . = ALIGN (4);
+ __ddr_end = .;
+ } >ddr_cached_32bit AT>envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set
+ point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing.
+ Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim AT > envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim AT > envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary (0x1000) - corresponds to page size, when using
+ memory mem */
+ /* protection */
+ /* .stack : ALIGN(0x1000) */
+ .stack : ALIGN(0x10)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ /* place __start_of_free_lim$ after last allocation of l2_lim */
+ . = ALIGN(0x10);
+ PROVIDE(__start_of_free_lim$ = .);
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld
new file mode 100644
index 00000000..98a7dace
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim-lma-scratchpad-vma.ld
@@ -0,0 +1,388 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-lim-lma-scratchpad-vma.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ * Code starts from LIM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * The startup stack size is used on start-up.
+ * The application stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __l2lim_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >l2lim
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> l2lim
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>envm */
+
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld
new file mode 100644
index 00000000..fd4ed76a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/linker/mpfs-lim.ld
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs_lim.ld
+ * Used when debugging code. The debugger loads the code to LIM.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/* STACK_SIZE_PER_HART needs to be calculated for your */
+/* application. Must be aligned */
+/* Also Thread local storage (AKA hart local storage) allocated for each hart */
+/* as part of the stack
+/* So memory map will look like once apportion in startup code: */
+/* */
+/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */
+/* TLS hart 0 */
+/* stack hart1 */
+/* TLS hart 1 */
+/* etc */
+/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */
+/* STACK_SIZE_PER_HART = 8k; */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * Stack size for each hart's application.
+ * These are the stack sizes that will be allocated to each hart before starting
+ * each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4().
+ */
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+ /* text: text code section */
+ . = __l2lim_start;
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ __text_start = .;
+ *(.text.init)
+ . = ALIGN(0x10);
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ . = ALIGN(0x10);
+ } > l2lim
+
+ .l2_scratchpad : ALIGN(0x10)
+ {
+ . = ALIGN (0x10);
+ __l2_scratchpad_load = LOADADDR(.l2_scratchpad);
+ __l2_scratchpad_start = .;
+ __l2_scratchpad_vma_start = .;
+ *(.l2_scratchpad)
+ . = ALIGN(0x10);
+ __l2_scratchpad_end = .;
+ __l2_scratchpad_vma_end = .;
+ } >scratchpad AT> l2lim
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including eNVM clock.
+ * This can not be done when running from eNVM
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>eNVM */
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } > l2lim
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > l2lim
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > l2lim
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack : ALIGN(0x1000)
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ PROVIDE(__stack_top_h0$ = .);
+
+ PROVIDE(__stack_bottom_h1$ = .);
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ PROVIDE(__stack_top_h1$ = .);
+
+ PROVIDE(__stack_bottom_h2$ = .);
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ PROVIDE(__stack_top_h2$ = .);
+
+ PROVIDE(__stack_bottom_h3$ = .);
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ PROVIDE(__stack_top_h3$ = .);
+
+ PROVIDE(__stack_bottom_h4$ = .);
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ PROVIDE(__stack_top_h4$ = .);
+
+ } > l2lim
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ } > l2lim
+
+ /*
+ * These are unused it the bootloader program but need to be preset for
+ * compilation, as used in non-bootloader function.
+ */
+ .unused_non_bootloader : ALIGN(0x10)
+ {
+ PROVIDE(__uninit_bottom$ = .);
+ PROVIDE(__uninit_top_h$ = .);
+ PROVIDE(__app_stack_bottom = .);
+ PROVIDE(__app_stack_top = .);
+ PROVIDE(__uninit_top_h$ = .);
+ } > l2lim
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h
new file mode 100644
index 00000000..fdf65956
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * Platform definitions
+ * Version based on requirements of MPFS MSS
+ *
+ */
+ /*========================================================================*//**
+ @mainpage Sample file detailing how mss_sw_config.h should be constructed for
+ the MPFS MSS
+
+ @section intro_sec Introduction
+ The mss_sw_config.h has the default software configuration settings for the
+ MPFS HAL and will be located at
+ /src/platform/platform_config_reference folder of the bare
+ metal SoftConsole project. The platform_config_reference is provided as a
+ default reference configuration.
+ When you want to configure the MPFS HAL with required configuration for
+ your project, the mss_sw_config.h must be edited and be placed in the
+ following project directory:
+ /src/boards//platform_config/mpfs_hal_config/
+
+ @section
+
+*//*==========================================================================*/
+
+
+#ifndef MSS_SW_CONFIG_H_
+#define MSS_SW_CONFIG_H_
+
+/*
+ * MPFS_HAL_FIRST_HART and MPFS_HAL_LAST_HART defines are used to specify which
+ * harts to actually start. The value and the actual hart it represents are
+ * listed below:
+ * value hart
+ * 0 E51
+ * 1 U54_1
+ * 2 U54_2
+ * 3 U54_3
+ * 4 U54_4
+ * Set MPFS_HAL_FIRST_HART to a value greater than 0 if you do not want your
+ * application to start and execute code on the harts represented by smaller
+ * value numbers.
+ * Set MPFS_HAL_LAST_HART to a value smaller than 4 if you do not wish to use
+ * all U54_x harts.
+ * Harts that are not started will remain in an infinite WFI loop unless used
+ * through some other method.
+ * The value of MPFS_HAL_FIRST_HART must always be less than MPFS_HAL_LAST_HART.
+ * The value of MPFS_HAL_LAST_HART must never be greater than 4.
+ * A typical use-case where you set MPFS_HAL_FIRST_HART = 1 and
+ * MPFS_HAL_LAST_HART = 1 is when
+ * your application is running on U54_1 and a bootloader running on E51 loads
+ * your application to the target memory and kicks-off U54_1 to run it.
+ */
+#ifndef MPFS_HAL_FIRST_HART
+#define MPFS_HAL_FIRST_HART 1
+#endif
+
+#ifndef MPFS_HAL_LAST_HART
+#define MPFS_HAL_LAST_HART 1
+#endif
+
+/*
+ * IMAGE_LOADED_BY_BOOTLOADER
+ * We set IMAGE_LOADED_BY_BOOTLOADER = 0 if the application image runs from
+ * non-volatile memory after reset. (No previous stage bootloader is used.)
+ * Set IMAGE_LOADED_BY_BOOTLOADER = 1 if the application image is loaded by a
+ * previous stage bootloader.
+ *
+ * MPFS_HAL_HW_CONFIG is defined if we are a boot-loader. This is a
+ * conditional compile switch is used to determine if MPFS HAL will perform the
+ * hardware configurations or not.
+ * Defined => This program acts as a First stage bootloader and performs
+ * hardware configurations.
+ * Not defined => This program assumes that the hardware configurations are
+ * already performed (Typically by a previous boot stage)
+ *
+ * List of items initialised when MPFS_HAL_HW_CONFIG is enabled
+ * - load virtual rom (see load_virtual_rom(void) in system_startup.c)
+ * - l2 cache config
+ * - Bus error unit config
+ * - MPU config
+ * - pmp config
+ * - I/O, clock and clock mux's, DDR and SGMII
+ * - will start other harts, see text describing MPFS_HAL_FIRST_HART,
+ * MPFS_HAL_LAST_HART above
+ *
+ */
+#define IMAGE_LOADED_BY_BOOTLOADER 1
+#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
+#define MPFS_HAL_HW_CONFIG
+#endif
+
+
+/*
+ * If you are using common memory for sharing across harts,
+ * uncomment #define MPFS_HAL_SHARED_MEM_ENABLED
+ * make sure common memory is allocated in the linker script
+ * See app_hart_common mem section in the example platform
+ * linker scripts.
+ */
+
+#define MPFS_HAL_SHARED_MEM_ENABLED
+
+
+/* define the required tick rate in Milliseconds */
+/* if this program is running on one hart only, only that particular hart value
+ * will be used */
+#define HART0_TICK_RATE_MS 5UL
+#define HART1_TICK_RATE_MS 5UL
+#define HART2_TICK_RATE_MS 5UL
+#define HART3_TICK_RATE_MS 5UL
+#define HART4_TICK_RATE_MS 5UL
+
+/*
+ * Define the size of the Hart Local Storage (HLS).
+ * In the MPFS HAL, we are using HLS for debug data storage during the initial
+ * boot phase.
+ * This includes the flags which indicate the hart state regarding boot state.
+ * The HLS will take memory from top of each stack allocated at boot time.
+ *
+ */
+#define HLS_DEBUG_AREA_SIZE 64
+
+/*
+ * Bus Error Unit (BEU) configurations
+ * BEU_ENABLE => Configures the events that the BEU can report. bit value
+ * 1= enabled, 0 = disabled.
+ * BEU_PLIC_INT => Configures which accrued events should generate an
+ * interrupt to the PLIC.
+ * BEU_LOCAL_INT => Configures which accrued events should generate a
+ * local interrupt to the hart on which the event accrued.
+ */
+#define BEU_ENABLE 0x0ULL
+#define BEU_PLIC_INT 0x0ULL
+#define BEU_LOCAL_INT 0x0ULL
+
+/*
+ * Clear memory on startup
+ * 0 => do not clear DTIM and L2
+ * 1 => Clears memory
+ * Note: If you are the zero stage bootloader, set this to one.
+ */
+#ifndef MPFS_HAL_CLEAR_MEMORY
+#define MPFS_HAL_CLEAR_MEMORY 1
+#endif
+
+/*
+ * Comment out the lines to disable the corresponding hardware support not required
+ * in your application.
+ * This is not necessary from an operational point of view as operation dictated
+ * by MSS configurator settings, and items are enabled/disabled by this method.
+ * The reason you may want to use below is to save code space.
+ */
+#define SGMII_SUPPORT
+#define DDR_SUPPORT
+#define MSSIO_SUPPORT
+
+/*
+ * DDR software options
+ */
+
+/*
+ * Debug DDR startup through a UART
+ * Comment out in normal operation. May be useful for debug purposes in bring-up
+ * of a new board design.
+ * See the weakly linked function setup_ddr_debug_port(mss_uart_instance_t * uart)
+ * If you need to edit this function, make another copy of the function in your
+ * application without the weak linking attribute. This copy will then get linked.
+ * */
+//#define DEBUG_DDR_INIT
+//#define DEBUG_DDR_RD_RW_FAIL
+//#define DEBUG_DDR_RD_RW_PASS
+//#define DEBUG_DDR_CFG_DDR_SGMII_PHY
+//#define DEBUG_DDR_DDRCFG
+
+
+/*
+ * The hardware configuration settings imported from Libero project get generated
+ * into /src/boards// folder.
+ * If you need to overwrite them for testing purposes, you can do so here.
+ * e.g. If you want change the default SEG registers configuration defined by
+ * LIBERO_SETTING_SEG0_0, define it here and it will take precedence.
+ * #define LIBERO_SETTING_SEG0_0 0x80007F80UL
+ *
+ */
+
+#endif /* USER_CONFIG_MSS_USER_CONFIG_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt
new file mode 100644
index 00000000..086c9f12
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/readme.txt
@@ -0,0 +1,2 @@
+contains user configuration of the platform
+e.g. division of memory between harts etc.
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-full/src/middleware/config/readme.txt b/driver-examples/mss-can/mpfs-can-full/src/middleware/config/readme.txt
new file mode 100644
index 00000000..95f6cb21
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/middleware/config/readme.txt
@@ -0,0 +1 @@
+contains files relating to configuration of third party modules
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-full/src/middleware/readme.txt b/driver-examples/mss-can/mpfs-can-full/src/middleware/readme.txt
new file mode 100644
index 00000000..0ffaed97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/middleware/readme.txt
@@ -0,0 +1 @@
+contains files relating to third party modules
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_can/mss_can.c b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_can/mss_can.c
new file mode 100644
index 00000000..fb59df0a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_can/mss_can.c
@@ -0,0 +1,1049 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * PolarFire SoC Microprocessor Subsystem(MSS) CAN bare metal software driver
+ * implementation.
+ */
+
+
+/*******************************************************************************
+ * Include files
+ */
+#include "mpfs_hal/mss_hal.h"
+#include "mss_can.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * Macros
+ */
+#define CAN_ID_SHIFT 18u
+#define CAN_ERROR_STATUS_SHIFT 16u
+#define CAN_ERROR_STATUS_MASK 0x03u
+#define CAN_RX_GTE96_SHIFT 19u
+#define CAN_FLAG_MASK 0x01u
+#define CAN_ERROR_COUNT_SHIFT 8u
+#define CAN_ERROR_COUNT_MASK 0xFFu
+#define CAN_TXGTE96_SHIFT 18u
+#define CAN_INT_MASK 0xFFFFFFFCu
+#define ENABLE 1u
+#define DISABLE 0u
+#define SYSREG_CAN_SOFTRESET_MASK (uint32_t)(3 << 14u)
+
+/*******************************************************************************
+ * Instance definition
+ */
+mss_can_instance_t g_mss_can_0_lo;
+mss_can_instance_t g_mss_can_1_lo;
+mss_can_instance_t g_mss_can_0_hi;
+mss_can_instance_t g_mss_can_1_hi;
+
+static void global_init
+(
+ mss_can_instance_t* this_wd
+);
+
+/***************************************************************************//**
+ * MSS_CAN_init()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_init
+(
+ mss_can_instance_t* this_can,
+ uint32_t bitrate,
+ pmss_can_config_reg pcan_config,
+ uint8_t basic_can_rx_mb,
+ uint8_t basic_can_tx_mb
+)
+{
+ uint32_t temp;
+ uint8_t mailbox_number;
+ uint8_t ret_value;
+ mss_can_rxmsgobject canrxobj;
+
+ global_init(this_can);
+
+ /* Initialize the device structure */
+ this_can->basic_can_rx_mb = basic_can_rx_mb;
+ this_can->basic_can_tx_mb = basic_can_tx_mb;
+
+ /* Initialize the rx mailbox */
+ canrxobj.ID = 0u;
+ canrxobj.DATAHIGH = 0u;
+ canrxobj.DATALOW = 0u;
+ canrxobj.AMR.L = 0u;
+ canrxobj.ACR.L = 0u;
+ canrxobj.AMR_D = 0u;
+ canrxobj.ACR_D = 0u;
+ canrxobj.RXB.L = (0u | CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL);
+
+ for (mailbox_number = 0u; mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ ret_value = MSS_CAN_config_buffer_n(this_can, mailbox_number,
+ &canrxobj);
+ }
+
+ /* Configure CAN controller */
+ if (CAN_SPEED_MANUAL == bitrate)
+ {
+ /*
+ * If user wants to specify registers directly Check if parameters
+ * meet minimums.
+ */
+ if (pcan_config->CFG_TSEG1 < 2u)
+ {
+ return (CAN_TSEG1_TOO_SMALL );
+ }
+
+ if ((pcan_config->CFG_TSEG2 == 0u) ||
+ ((pcan_config->SAMPLING_MODE == 1u) && (pcan_config->CFG_TSEG2
+ == 1u)))
+ {
+ return (CAN_TSEG2_TOO_SMALL);
+ }
+ temp = pcan_config->CFG_SJW;
+ if ((temp > pcan_config->CFG_TSEG1) ||
+ (temp > pcan_config->CFG_TSEG2))
+ {
+ return (CAN_SJW_TOO_BIG);
+ }
+
+ this_can->hw_reg->Config.L = pcan_config->L;
+ }
+ else
+ {
+ /* User has chosen a default setting. */
+ this_can->hw_reg->Config.L = bitrate;
+ }
+
+ /* Disable Interrupts */
+ this_can->hw_reg->IntEbl.L = DISABLE;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_config_reg()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_config_reg
+(
+ mss_can_instance_t* this_can,
+ uint32_t cfg
+)
+{
+ /* Clear all pending interrupts */
+ this_can->hw_reg->IntStatus.L = DISABLE;
+
+ /* Disable CAN Device */
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+
+ /* Disable receive interrupts. */
+ this_can->hw_reg->IntEbl.RX_MSG = DISABLE;
+
+ /* Disable interrupts from CAN device. */
+ this_can->hw_reg->IntEbl.INT_EBL = DISABLE;
+
+ /* Sets configuration bits */
+ this_can->hw_reg->Config.L = cfg;
+ MSS_CAN_start(this_can);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_mode()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_mode
+(
+ mss_can_instance_t* this_can,
+ mss_can_mode_t mode
+)
+{
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+ if (CANOP_SW_RESET == mode)
+ {
+ SYSREG->SOFT_RESET_CR |= SYSREG_CAN_SOFTRESET_MASK;
+ SYSREG->SOFT_RESET_CR &= ~SYSREG_CAN_SOFTRESET_MASK;
+ }
+ else
+ {
+ this_can->hw_reg->Command.L = (uint32_t)mode;
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_start()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_start
+(
+ mss_can_instance_t* this_can
+)
+{
+ /* Clear all pending interrupts*/
+ this_can->hw_reg->IntStatus.L = DISABLE;
+
+ /* Enable CAN Device*/
+ this_can->hw_reg->Command.RUN_STOP = ENABLE;
+
+ /* Enable CAN Interrupt at NVIC level- if supported */
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ if (if (&g_mss_can_0_lo == this_can) || (&g_mss_can_0_hi == this_can))
+ {
+ PLIC_DisableIRQ(CAN0_PLIC);
+ }
+ else
+ {
+ PLIC_DisableIRQ(CAN1_PLIC);
+ }
+#endif
+
+ /* Enable receive interrupts. */
+ this_can->hw_reg->IntEbl.RX_MSG = ENABLE;
+
+ /* Enable interrupts from CAN device.*/
+ this_can->hw_reg->IntEbl.INT_EBL = ENABLE;
+
+}
+
+/***************************************************************************//**
+ * MSS_CAN_stop()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_stop
+(
+ mss_can_instance_t* this_can
+)
+{
+ this_can->hw_reg->Command.RUN_STOP = DISABLE;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_id()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_id
+(
+ pmss_can_msgobject pmsg
+)
+{
+ if (pmsg->IDE)
+ {
+ return (pmsg->ID);
+ }
+ else
+ {
+ return (pmsg->ID >> CAN_ID_SHIFT);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_id()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_set_id
+(
+ pmss_can_msgobject pmsg
+)
+{
+ if (pmsg->IDE)
+ {
+ return (pmsg->ID);
+ }
+ else
+ {
+ return (pmsg->ID << CAN_ID_SHIFT);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_msg_filter_mask()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_msg_filter_mask
+(
+ uint32_t id,
+ uint8_t ide,
+ uint8_t rtr
+)
+{
+ if (ide)
+ {
+ id <<= 3u;
+ }
+ else
+ {
+ id <<= 21;
+
+ /* Set unused ID bits to 1! */
+ id |= (0x3FFFF << 3u);
+ }
+ id |= ((uint32_t)(ide << 2u) | (uint32_t)(rtr << 1u));
+
+ return (id);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_set_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntEbl.L |= irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_clear_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_clear_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntEbl.L &= ~irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_global_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_global_int_ebl
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntEbl.INT_EBL);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_int_ebl()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_int_ebl
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntEbl.L & CAN_INT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_clear_int_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+void
+MSS_CAN_clear_int_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+)
+{
+ this_can->hw_reg->IntStatus.L = irq_flag;
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_int_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_int_status
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->IntStatus.L);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_rtr_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_set_rtr_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Is buffer configured for RTR auto-replay? */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRREPLY == 0u)
+ {
+ return (CAN_NO_RTR_MAILBOX);
+ }
+ else
+ {
+ /* Transfer the ID. */
+ this_can->hw_reg->RxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->RxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ return (CAN_OK);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rtr_message_abort_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_rtr_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ /* Mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Set abort request */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRABORT = 1u;
+
+ /* Check the abort is granted */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.RTRREPLYPEND == 0u)
+ {
+ /* If the RX buffer isn't busy. Abort was successful */
+ return (CAN_OK);
+ }
+ else
+ {
+ /* Message not aborted.*/
+ return (CAN_ERR);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_config_buffer()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_config_buffer
+(
+ mss_can_instance_t* this_can,
+ pmss_can_filterobject pfilter
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX - this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Set filters */
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = pfilter->ACR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = pfilter->AMR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = pfilter->AMCR_D.MASK;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = pfilter->AMCR_D.CODE;
+
+ /* Configure mailbox */
+ if (mailbox_number < (CAN_RX_MAILBOX - 1))
+ {
+ /* set link flag, if not last buffer */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L =
+ (CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL | \
+ CAN_RX_LINK_EBL);
+ }
+ else
+ {
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L =
+ (CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL);
+ }
+ success = CAN_OK;
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_config_buffer_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_config_buffer_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_rxmsgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Configure mailbox */
+ this_can->hw_reg->RxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->RxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = pmsg->ACR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = pmsg->AMR.L;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = pmsg->AMR_D;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = pmsg->ACR_D;
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.L = (pmsg->RXB.L | \
+ CAN_RX_WPNH_EBL | CAN_RX_WPNL_EBL | \
+ CAN_RX_BUFFER_EBL | CAN_RX_INT_EBL);
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_RX_MAILBOX - this_can->basic_can_rx_mb))
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Check that a new message is available and get it */
+ if ((ENABLE == this_can->hw_reg->Command.RUN_STOP) &&
+ (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV))
+ {
+ /* Copy ID */
+ pmsg->ID = this_can->hw_reg->RxMsg[mailbox_number].ID;
+
+ /* Copy 4 of the data bytes */
+ pmsg->DATALOW = this_can->hw_reg->RxMsg[mailbox_number].DATALOW;
+
+ /* Copy the other 4 data bytes. */
+ pmsg->DATAHIGH = this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH;
+
+ /* Get DLC, IDE and RTR and time stamp. */
+ pmsg->L = this_can->hw_reg->RxMsg[mailbox_number].RXB.L;
+
+ /* Ack that it's been removed from the FIFO */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV = ENABLE;
+
+ /* And let app know there is a message. */
+ return (CAN_VALID_MSG);
+ }
+ else
+ {
+ return (CAN_NO_MSG);
+ }
+}
+
+/*******************************************************************************
+ * MSS_CAN_get_message()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX-this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Check that if there is a valid message */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV)
+ {
+ /* Copy ID */
+ pmsg->ID = this_can->hw_reg->RxMsg[mailbox_number].ID;
+
+ /* Copy 4 of the data bytes */
+ pmsg->DATALOW = this_can->hw_reg->RxMsg[mailbox_number].DATALOW;
+
+ /* Copy the other 4 data bytes.*/
+ pmsg->DATAHIGH = this_can->hw_reg->RxMsg[mailbox_number].DATAHIGH;
+
+ /* Get DLC, IDE and RTR and time stamp.*/
+ pmsg->L = this_can->hw_reg->RxMsg[mailbox_number].RXB.L;
+
+ /* Ack that it's been removed from the FIFO */
+ this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV = ENABLE;
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_message_av()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_message_av
+(
+ mss_can_instance_t* this_can
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_rx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that has a message available */
+ for (mailbox_number = CAN_RX_MAILBOX-this_can->basic_can_rx_mb; \
+ mailbox_number < CAN_RX_MAILBOX; mailbox_number++)
+ {
+ /* Check that buffer is enabled and contains a message */
+ if (this_can->hw_reg->RxMsg[mailbox_number].RXB.MSGAV)
+ {
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+)
+{
+ /* Can't send if device is disabled */
+ if (DISABLE == this_can->hw_reg->Command.RUN_STOP)
+ {
+ /* Message not sent. */
+ return (CAN_NO_MSG);
+ }
+
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_TX_MAILBOX - this_can->basic_can_tx_mb))
+ {
+ /* mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXREQ == 0u)
+ {
+ /* If the Tx buffer isn't busy.... */
+ this_can->hw_reg->TxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->TxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->TxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L = (pmsg->L | \
+ CAN_TX_WPNH_EBL | \
+ CAN_TX_REQ);
+ return (CAN_VALID_MSG);
+ }
+ else
+ {
+ /* Message not sent. */
+ return (CAN_NO_MSG);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_abort_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+)
+{
+ /* Is buffer configured for Full CAN? */
+ if (mailbox_number >= (CAN_TX_MAILBOX - this_can->basic_can_tx_mb))
+ {
+ /* mailbox is configured for basic CAN */
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ /* Set abort request */
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L =
+ ((this_can->hw_reg->TxMsg[mailbox_number].TXB.L & ~CAN_TX_REQ) | \
+ CAN_TX_ABORT);
+
+ /* Check the abort is granted */
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXABORT == 0u)
+ {
+ /* If the Tx buffer isn't busy, Abort was successful */
+ return (CAN_OK);
+ }
+ else
+ {
+ /* Message not aborted. */
+ return (CAN_ERR);
+ }
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message_ready()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message_ready
+(
+ mss_can_instance_t* this_can
+)
+{
+ uint8_t success = CAN_ERR;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_tx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that is available */
+ for (mailbox_number = CAN_TX_MAILBOX-this_can->basic_can_tx_mb; \
+ mailbox_number < CAN_TX_MAILBOX; mailbox_number++)
+ {
+ if (this_can->hw_reg->TxMsg[mailbox_number].TXB.TXREQ == 0u)
+ {
+ /* Tx buffer isn't busy */
+ success = CAN_OK;
+ break;
+ }
+ }
+
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_send_message()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_send_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+)
+{
+ uint8_t success = CAN_NO_MSG;
+ uint8_t mailbox_number;
+
+ /* Is a buffer configured for Basic CAN? */
+ if (this_can->basic_can_tx_mb == 0u)
+ {
+ return (CAN_INVALID_MAILBOX);
+ }
+
+ /* Find next BASIC CAN buffer that is available */
+ for (mailbox_number = CAN_TX_MAILBOX-this_can->basic_can_tx_mb; \
+ mailbox_number < CAN_TX_MAILBOX; mailbox_number++)
+ {
+ /* Check which transmit mailbox is not busy and use it. */
+ if ((MSS_CAN_get_tx_buffer_status(this_can) & (1u << mailbox_number))
+ == 0)
+ {
+ /* If the Tx buffer isn't busy.... */
+ this_can->hw_reg->TxMsg[mailbox_number].ID = pmsg->ID;
+ this_can->hw_reg->TxMsg[mailbox_number].DATALOW = pmsg->DATALOW;
+ this_can->hw_reg->TxMsg[mailbox_number].DATAHIGH = pmsg->DATAHIGH;
+ this_can->hw_reg->TxMsg[mailbox_number].TXB.L = (pmsg->L | \
+ CAN_TX_WPNH_EBL | \
+ CAN_TX_REQ);
+ success = CAN_VALID_MSG;
+ break;
+ }
+ }
+
+ return (success);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_mask_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t *pamr,
+ uint32_t *pacr,
+ uint16_t *pdta_amr,
+ uint16_t *pdta_acr
+)
+{
+ if (mailbox_number >= CAN_RX_MAILBOX)
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ *pamr = this_can->hw_reg->RxMsg[mailbox_number].AMR.L;
+ *pacr = this_can->hw_reg->RxMsg[mailbox_number].ACR.L;
+ *pdta_acr = this_can->hw_reg->RxMsg[mailbox_number].ACR_D;
+ *pdta_amr = this_can->hw_reg->RxMsg[mailbox_number].AMR_D;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_set_mask_n()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_set_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t amr,
+ uint32_t acr,
+ uint16_t dta_amr,
+ uint16_t dta_acr
+)
+{
+ if (mailbox_number >= CAN_RX_MAILBOX)
+ {
+ return (CAN_BASIC_CAN_MAILBOX);
+ }
+
+ this_can->hw_reg->RxMsg[mailbox_number].AMR.L = amr;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR.L = acr;
+ this_can->hw_reg->RxMsg[mailbox_number].AMR_D = (uint32_t)dta_amr;
+ this_can->hw_reg->RxMsg[mailbox_number].ACR_D = (uint32_t)dta_acr;
+
+ return (CAN_OK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_buffer_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_buffer_status
+(
+ mss_can_instance_t* this_can
+)
+{
+#ifdef CANMOD3
+ return (this_can->hw_reg->BufferStatus.L & 0x0000FFFF);
+#else
+ return (this_can->hw_reg->BufferStatus.RXMSGAV);
+#endif
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_buffer_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_buffer_status
+(
+ mss_can_instance_t* this_can
+)
+{
+#ifdef CANMOD3
+ return ((this_can->hw_reg->BufferStatus.L >> 16u) & 0x00FF);
+#else
+ return (this_can->hw_reg->BufferStatus.TXREQ);
+#endif
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_error_status()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint8_t
+MSS_CAN_get_error_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t *status
+)
+{
+ /* Supply error register info if user wants. */
+ *status = this_can->hw_reg->ErrorStatus.L;
+
+ /* 00 Error Active, 01 Error Passive, 1x Bus Off */
+ return ((uint8_t)(((*status) >> CAN_ERROR_STATUS_SHIFT) &
+ CAN_ERROR_STATUS_MASK));
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_error_count()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_error_count
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_ERROR_COUNT_SHIFT) & \
+ CAN_ERROR_COUNT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_rx_gte96()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_rx_gte96
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_RX_GTE96_SHIFT) & \
+ CAN_FLAG_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_error_count()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_error_count
+(
+ mss_can_instance_t* this_can
+)
+{
+ return (this_can->hw_reg->ErrorStatus.L & CAN_ERROR_COUNT_MASK);
+}
+
+/***************************************************************************//**
+ * MSS_CAN_get_tx_gte96 ()
+ * See "mss_can.h" for details of how to use this function.
+ */
+uint32_t
+MSS_CAN_get_tx_gte96
+(
+ mss_can_instance_t* this_can
+)
+{
+ return ((this_can->hw_reg->ErrorStatus.L >> CAN_TXGTE96_SHIFT) & \
+ CAN_FLAG_MASK);
+}
+
+/*******************************************************************************
+ * Global initialization for all modes
+ */
+static void global_init
+(
+ mss_can_instance_t* this_wd
+)
+{
+ if (&g_mss_can_0_lo == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_0_LO_BASE;
+ this_wd->irqn = CAN0_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_1_lo == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_1_LO_BASE;
+ this_wd->irqn = CAN1_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_0_hi == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_0_HI_BASE;
+ this_wd->irqn = CAN0_PLIC;
+ this_wd->int_type = 0;
+ }
+ else if (&g_mss_can_1_hi == this_wd)
+ {
+ this_wd->hw_reg = MSS_CAN_1_HI_BASE;
+ this_wd->irqn = CAN1_PLIC;
+ this_wd->int_type = 0;
+ }
+ else
+ {
+ ;/* LDRA Warning */
+ }
+}
+
+#ifndef MSS_CAN_USER_ISR
+/***************************************************************************//**
+ * CAN interrupt service routine.
+ * CAN_IRQHandler is included within the RISC-V vector table as part of the
+ * MPFS HAL.
+ */
+uint8_t External_can0_plic_IRQHandler(void)
+{
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ /* User provided code is required here to handle interrupts from the MSS CAN
+ * peripheral. Remove the assert once this is in place.*/
+ ASSERT(!"An ISR is required here if interrupts are enabled");
+#else
+ ASSERT(!"Unexpected MSS CAN interrupt - MSS CAN NVIC Interrupts should be \
+ disabled");
+#endif
+ return 0;
+}
+
+uint8_t can1_IRQHandler(void)
+{
+#ifdef MSS_CAN_ENABLE_INTERRUPTS
+ /* User provided code is required here to handle interrupts from the MSS CAN
+ * peripheral. Remove the assert once this is in place.*/
+ ASSERT(!"An ISR is required here if interrupts are enabled");
+#else
+ ASSERT(!"Unexpected MSS CAN interrupt - MSS CAN NVIC Interrupts should be \
+ disabled");
+#endif
+ return 0;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_can/mss_can.h b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_can/mss_can.h
new file mode 100644
index 00000000..d4153c32
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_can/mss_can.h
@@ -0,0 +1,2430 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * PolarFire SoC Microprocessor Subsystem(MSS) CAN bare metal software driver
+ * public API.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire SoC MSS CAN Bare Metal Driver.
+
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor Subsystem (MSS) includes two CAN controller.
+ The CAN controller is configurable to provide support for up to 32 transmit
+ and 32 receive mailboxes.
+
+ This PolarFire SoC MSS CAN driver provides a set of functions for accessing
+ and controlling the MSS CAN as part of a bare metal system where no operating
+ system is available. The driver can be adapted for use as part of an
+ operating system, but the implementation of the adaptation layer between the
+ driver and the operating system's driver model is outside the scope of the
+ driver.
+
+ --------------------------------
+ Features
+ --------------------------------
+ The MSS CAN driver provides support for the following features:
+ - Basic CAN APIs if application needs support for Basic CAN operation.
+ (Configure as FIFO by linking several mailboxes together, one message
+ filter for entire FIFO)
+ - Full CAN APIs (each mail box has its own message filter)
+ - Support for 11 bit and 29 bit message identifiers
+ - Support for Data frame and Remote frames
+ - Error detection mechanism
+
+ ==============================================================================
+ Hardware Flow Dependencies
+ ==============================================================================
+ The configuration of all features of the PolarFire MSS CAN is covered by
+ this driver, with the exception of the PolarFire SoC IOMUX configuration.
+ The PolarFire SoC allows multiple non-concurrent uses of few external pins
+ through IOMUX configuration. This feature allows optimization of external pin
+ usage by assigning external pins for use by either the microprocessor
+ subsystem or the FPGA fabric. The MSS CAN serial signals are routed through
+ IOMUXs to the PolarFire SoC device external pins. The MSS CAN serial
+ signals can also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
+ For more information on IOMUX, refer to the I/O Configuration section of the
+ PolarFire SoC Microprocessor Subsystem (MSS) User's Guide.
+
+ The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
+ must ensure that the MSS CAN peripherals are enabled and configured in the
+ PolarFire SoC MSS configurator if you wish to use them. For more information
+ on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
+ Subsystem (MSS) User's Guide.
+
+ On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
+ masters and multiple slaves. Five RISC-V CPUs connect to the Master ports M10
+ to M14 of the AXI switch. By default, all the APB peripherals are accessible
+ on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB bridges
+ (referred as main APB bus). However, to support logical separation in the
+ Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals can
+ alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to APB
+ bridges (referred as the AMP APB bus).
+ Application must make sure that the desired CAN instance is appropriately
+ configured on one of the APB bus described above by configuring the PolarFire
+ SoC system registers (SYSREG) as per the application need and that the
+ appropriate data structures are provided to this driver as parameter to the
+ functions provided by this driver.
+
+ The base address and the register addresses are defined in this driver as
+ constants. The interrupt number assignment for the MSS CAN peripherals is
+ defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
+ is included in the project settings of the SoftConsole toolchain and that it
+ is generated into your project.
+
+ ==============================================================================
+ Theory of Operation
+ ==============================================================================
+ The MSS CAN driver uses one instance of the mss_can_instance_t structure per
+ port. This instance is used to identify the target port and a pointer to this
+ instance is passed as the first argument to all CAN driver functions.
+
+ The PolarFire SoC MSS CAN driver operations can be divided in following
+ sub-sections:
+ - CAN Controller Configuration
+ - Operation Status
+ - Interrupt Support
+ - Helper Functions
+ - Basic CAN Message Handling
+ - Full CAN Message Handling
+
+ --------------------------------
+ Configuration
+ --------------------------------
+ The MSS CAN driver must first be initialized and the mode of operation must
+ be selected before performing data transfers on CAN Bus. The MSS_CAN_init()
+ function is used to initialize the CAN controller and driver. Set CAN
+ controller operation mode as normal operation using MSS_CAN_set_mode()
+ function. The operating mode of operation is selected using
+ MSS_CAN_set_mode() function. The actual data transfer can be started using
+ start the CAN controller by using MSS_CAN_start() function, with this actual
+ data transmission or reception shall start. MSS_CAN_stop() function is used
+ to stops the CAN controller. Once initialized, during normal mode of
+ operation, the MSS CAN driver configuration can be changed using
+ MSS_CAN_set_config_reg() function is used to change the CAN controllers
+ configuration during normal operation.
+
+ --------------------------------
+ Operation Status
+ --------------------------------
+ MSS_CAN_get_error_status() function returns the current CAN error state
+ (error active, error passive, and bus off). The MSS_CAN_get_rx_error_count()
+ and MSS_CAN_get_tx_error_count() functions return the actual
+ receive and transmit error counter values while MSS_CAN_get_rx_gte96()
+ function and MSS_CAN_get_tx_gte96() function show if the error counters are
+ greater or equal to 96, which indicates a heavily disturbed bus.
+
+ --------------------------------
+ Interrupt Support
+ --------------------------------
+ The interrupt service routines are not part of the CAN driver. But access
+ functions for the interrupt registers are provided. The individual
+ interrupt enable bits can be set using MSS_CAN_set_int_ebl() function and
+ individual interrupt enable bits can be cleared using MSS_CAN_clear_int_ebl
+ while MSS_CAN_get_int_ebl() function returns their actual state.
+ MSS_CAN_get_global_int_ebl() function indicates if interrupt
+ generation is enabled at all. MSS_CAN_get_int_status() function shows the
+ current state of the different interrupt status bits. Each interrupt status
+ bit can be individually cleared using MSS_CAN_clear_int_status() function.
+
+ The interrupt service routines are not part of the MSS CAN driver and the
+ driver ships with the MSS_CAN_ENABLE_INTERRUPTS macro disabled which stops
+ the MSS CAN interrupt being enabled at the PLIC, however a stub ISR is
+ present in the mss_can.c file to show the format of the function and catch
+ any unexpected interrupts to aid in debugging.
+
+ --------------------------------
+ Helper Functions
+ --------------------------------
+ The MSS CAN peripheral expects all ID bits to be left aligned. This makes
+ setting the ID cumbersome. Using MSS_CAN_set_id(), a given right-aligned
+ ID field is modified according to the ID size which is indicated by the
+ IDE bit. MSS_CAN_get_id() provides the reverse operation: It returns the
+ ID right aligned. MSS_CAN_get_msg_filter_mask() packs the ID, IDE, and RTR
+ bits together as they are used in the mask registers. MSS_CAN_get_mask_n()
+ returns the message filter settings of the selected receive mailbox.
+ MSS_CAN_set_mask_n() configures the message filter settings for the
+ selected receive mailbox.
+
+ --------------------------------
+ Basic CAN Message Handling
+ --------------------------------
+ A Basic CAN type controller contains one or more message filter and one
+ common message buffer or FIFO. The CAN driver contains some functions to
+ emulate Basic CAN operation by linking several buffers together to form a
+ buffer array that shares one message filter. Since this buffer array is not
+ a real FIFO, message inversion might happen (eg, a newer message might be
+ pulled from the receive buffer prior to an older message).
+ Before using the Basic CAN API, the CAN controller has to be configured
+ first with a MSS_CAN_config_buffer() function call. This sets up the
+ message array and configures the message filter. MSS_CAN_send_message()
+ function and MSS_CAN_get_message() function are used to send and receive
+ a message from transmit or receive buffers. MSS_CAN_send_message_ready()
+ function indicates if a new message can be sent. MSS_CAN_get_message_av()
+ function shows if a new message is available.
+
+ --------------------------------
+ Full CAN Message Handling
+ --------------------------------
+ In Full CAN operation, each message mailbox has its own message filter.
+ This reduces the number of receive interrupts as the host CPU only gets an
+ interrupt when a message of interest has arrived. Further, software based
+ message filtering overhead is reduced and there is less message to
+ be checked. Before a buffer can be used for Full CAN operation, it needs to
+ be configured using MSS_CAN_config_buffer_n() function. An error is
+ generated if this buffer is already reserved for Basic CAN operation.
+ The MSS_CAN_get_rx_buffer_status() and MSS_CAN_get_tx_buffer_status()
+ functions indicate the current state of the receive and transmit buffers
+ respectively. With MSS_CAN_send_message_n() function a message can be sent
+ using buffer. A pending message transfer can be aborted with
+ MSS_CAN_send_message_abort_n() function and a message can be read with
+ MSS_CAN_get_message_n() function. If a buffer is set for automatic RTR reply,
+ MSS_CAN_set_rtr_message_n() function sets the CAN message that is returned
+ upon reception of the RTR message. MSS_CAN_get_rtr_message_abort_n()
+ function aborts a RTR message transmit request.
+
+ NOTE:
+ 1. User has to set the RTR message filter to match with
+ MSS_CAN_rtr_message_abort_n() function a pending RTR auto-reply can be
+ aborted.
+ 2. An error is generated if buffer is already reserved for Basic CAN
+ operation and is trying to use the same buffer for Full CAN functionality.
+ 3. Special case of Full CAN where several mailboxes are linked together to
+ create FIFOs that share an identical message filter configuration, can
+ be built upon the available Full CAN functions.
+
+ *//*=========================================================================*/
+
+#ifndef MSS_CAN_H_
+#define MSS_CAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following macro MSS_CAN_ENABLE_INTERRUPTS must be defined to allow the
+ * enabling of the MSS CAN peripheral interrupts at the PLIC level.
+ * This version of the MSS CAN driver does not provide any support for MSS CAN
+ * interrupts and so this MACRO should be disabled unless there is a user
+ * supplied ISR.
+ */
+
+#if 0
+#define MSS_CAN_ENABLE_INTERRUPTS
+#endif
+
+/**
+ * Define CAN target device
+ *
+ * CANMOD3: Device with 16 Rx and 8 Tx mailboxes
+ * CANMOD3X: Device with 32 Rx and 32 Tx mailboxes
+ */
+
+#define CANMOD3X
+
+#ifdef CANMOD3
+ #define CAN_RX_MAILBOX 16u
+ #define CAN_TX_MAILBOX 8u
+#else
+ #define CAN_RX_MAILBOX 32u
+ #define CAN_TX_MAILBOX 32u
+#endif
+
+
+/* Configuration and Speed definitions */
+#define CAN_PRESET (mss_can_config_reg.L)0
+#define CAN_SAMPLE_BOTH_EDGES 0x00000001u
+#define CAN_THREE_SAMPLES 0x00000002u
+#define CAN_SET_SJW(_sjw) (_sjw<<2u)
+#define CAN_AUTO_RESTART 0x00000010u
+#define CAN_SET_TSEG2(_tseg2) (_tseg2<<5u)
+#define CAN_SET_TSEG1(_tseg1) (_tseg1<<8u)
+#define CAN_SET_BITRATE(_bitrate) (_bitrate<<16u)
+#define CAN_ARB_ROUNDROBIN 0x00000000u
+#define CAN_ARB_FIXED_PRIO 0x00001000u
+#define CAN_BIG_ENDIAN 0x00000000u
+#define CAN_LITTLE_ENDIAN 0x00002000u
+
+/* Manual setting with specified fields */
+#define CAN_SPEED_MANUAL 0u
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used in the PolarFire SoC MSS CAN driver for
+ bitrate definitions:
+
+ | Constants | Description |
+ |--------------------|-----------------------------------------------------|
+ | CAN_SPEED_8M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_5K | Indicates CAN controller shall be configured with |
+ | | 5Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_10K | Indicates CAN controller shall be configured with |
+ | | 10Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_20K | Indicates CAN controller shall be configured with |
+ | | 20Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_50K | Indicates CAN controller shall be configured with |
+ | | 50Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_100K | Indicates CAN controller shall be configured with |
+ | | 100Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_125K | Indicates CAN controller shall be configured with |
+ | | 125Kbps baud rate if the input clock is 32MHz. |
+ | AN_SPEED_8M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_250K | Indicates CAN controller shall be configured with |
+ | | 250Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_500K | Indicates CAN controller shall be configured with |
+ | | 500Kbps baud rate if the input clock is 32MHz. |
+ | CAN_SPEED_8M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 8MHz. |
+ | CAN_SPEED_16M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 16MHz. |
+ | CAN_SPEED_32M_1M | Indicates CAN controller shall be configured with |
+ | | 1MBPS baud rate if the input clock is 32MHz. |
+
+ */
+/* 5000m 81% Sample bit three times */
+#define CAN_SPEED_8M_5K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_5K CAN_SET_BITRATE(199)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_5K CAN_SET_BITRATE(399)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 5000m 81% Sample bit three times */
+#define CAN_SPEED_8M_10K CAN_SET_BITRATE(49)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_10K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_10K CAN_SET_BITRATE(199)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 2500m 81% Sample bit three times */
+#define CAN_SPEED_8M_20K CAN_SET_BITRATE(24)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_16M_20K CAN_SET_BITRATE(49)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+#define CAN_SPEED_32M_20K CAN_SET_BITRATE(99)|CAN_SET_TSEG1(11)|CAN_SET_TSEG2(2)|CAN_THREE_SAMPLES
+
+/* 1000m 87% */
+#define CAN_SPEED_8M_50K CAN_SET_BITRATE(9)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_50K CAN_SET_BITRATE(19)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_50K CAN_SET_BITRATE(39)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 600m 87% */
+#define CAN_SPEED_8M_100K CAN_SET_BITRATE(4)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_100K CAN_SET_BITRATE(9)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_100K CAN_SET_BITRATE(19)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 500m 87% */
+#define CAN_SPEED_8M_125K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_125K CAN_SET_BITRATE(7)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_125K CAN_SET_BITRATE(15)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 250m 87% */
+#define CAN_SPEED_8M_250K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_250K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_250K CAN_SET_BITRATE(7)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 100m 75% @ 8M, 87% @ 16M */
+#define CAN_SPEED_8M_500K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_500K CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_500K CAN_SET_BITRATE(3)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/* 25m 75% */
+#define CAN_SPEED_8M_1M CAN_SET_BITRATE(0)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_16M_1M CAN_SET_BITRATE(1)|CAN_SET_TSEG1(4)|CAN_SET_TSEG2(1)
+#define CAN_SPEED_32M_1M CAN_SET_BITRATE(1)|CAN_SET_TSEG1(12)|CAN_SET_TSEG2(1)
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_ERR | Indicates error condition |
+ | CAN_TSEG1_TOO_SMALL | Value provided to configure TSEG1 is too |
+ | | small |
+ | CAN_TSEG2_TOO_SMALL | Value provided to configure TSEG2 is too |
+ | | small |
+ | CAN_SJW_TOO_BIG | Value provided to configure synchronous jump|
+ | | width (SJW) is too big. |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+ | CAN_NO_RTR_MAILBOX | Indicates that there is no mailbox for |
+ | | remote transmit request (RTR) frame |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ */
+#define CAN_OK 0u
+#define CAN_ERR 1u
+#define CAN_TSEG1_TOO_SMALL 2u
+#define CAN_TSEG2_TOO_SMALL 3u
+#define CAN_SJW_TOO_BIG 4u
+#define CAN_BASIC_CAN_MAILBOX 5u
+#define CAN_NO_RTR_MAILBOX 6u
+#define CAN_INVALID_MAILBOX 7u
+
+/* Flag bits */
+#define CAN_NO_MSG 0x00u
+#define CAN_VALID_MSG 0x01u
+
+/*
+ * A couple of definitions just to make the code more readable so we know
+ * what a 1 and 0 mean.
+#define CAN_RTR 1<<21
+#define CAN_EXT_IDE 1<<20
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used in the MSS CAN driver for Interrupt Bit
+ Definitions
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ */
+#define CAN_INT_GLOBAL 1<<0 /* Global interrupt */
+#define CAN_INT_ARB_LOSS 1<<2 /* Arbitration loss interrupt */
+#define CAN_INT_OVR_LOAD 1<<3 /*Overload interrupt */
+#define CAN_INT_BIT_ERR 1<<4 /* Bit error interrupt */
+#define CAN_INT_STUFF_ERR 1<<5 /* Bit stuffing error interrupt */
+#define CAN_INT_ACK_ERR 1<<6 /* Acknowledgement error interrupt */
+#define CAN_INT_FORM_ERR 1<<7 /* Format error interrupt */
+#define CAN_INT_CRC_ERR 1<<8 /* CRC error interrupt */
+#define CAN_INT_BUS_OFF 1<<9 /* Bus-off interrupt */
+#define CAN_INT_RX_MSG_LOST 1<<10 /* Rx message lost interrupt */
+#define CAN_INT_TX_MSG 1<<11 /* Tx message interupt */
+#define CAN_INT_RX_MSG 1<<12 /* Rx message interrupt */
+#define CAN_INT_RTR_MSG 1<<13 /* RTR message interrupt */
+#define CAN_INT_STUCK_AT_0 1<<14 /* Stuck-at-0 error interrupt */
+#define CAN_INT_SST_FAILURE 1<<15 /* Single-shot transmission error interrupt*/
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for transmit message buffer control bit
+ definitions:
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_TX_WPNH_EBL | Indicates “WPNH” bit mask |
+ | CAN_TX_WPNL_EBL | Indicates WPNL bit mask |
+ | CAN_TX_REQ | Indicates transmit request flag bit position |
+ | CAN_TX_INT_EBL | Indicates transmit Interrupt enable bit mask |
+ | CAN_TX_ABORT | Indicates Transmit abort mask |
+
+ */
+#define CAN_TX_WPNH_EBL 1<<23
+#define CAN_TX_WPNL_EBL 1<<3
+#define CAN_TX_INT_EBL 1<<2
+#define CAN_TX_ABORT 1<<1
+#define CAN_TX_REQ 0x01u
+
+/*-------------------------------------------------------------------------*//**
+ The following constants are used for receive message buffer control bit
+ definitions:
+
+ | Constants | Description |
+ |--------------------------|------------------------------------------------|
+ | CAN_RX_WPNH_EBL | Indicates WPNH bit mask. |
+ | CAN_RX_WPNL_EBL | Indicates WPNL bit mask |
+ | CAN_RX_LINK_EBL | Indicates link flag bit mask |
+ | CAN_RX_INT_EBL | Indicates receive interrupt enable bit mask |
+ | CAN_RX_RTR_REPLY_EBL | Indicates RTR reply bit mask |
+ | CAN_RX_BUFFER_EBL | Indicates Transaction buffer enable bit mask |
+ | CAN_RX_RTR_ABORT | Indicates RTR abort request mask |
+ | CAN_RX_RTRP | Indicates RTReply pending status mask |
+ | CAN_RX_MSGAV | Indicates receive message available status mask|
+
+ */
+#define CAN_RX_WPNH_EBL 1<<23
+#define CAN_RX_WPNL_EBL 1<<7
+#define CAN_RX_LINK_EBL 1<<6
+#define CAN_RX_INT_EBL 1<<5
+#define CAN_RX_RTR_REPLY_EBL 1<<4
+#define CAN_RX_BUFFER_EBL 1<<3
+#define CAN_RX_RTR_ABORT 1<<2
+#define CAN_RX_RTRP 1<<1
+#define CAN_RX_MSGAV 0x01
+
+/*-------------------------------------------------------------------------*//**
+ The mss_can_mode_t enumeration specifies the possible operating modes of CAN
+ controller. The meaning of the constants is as described below
+
+ | Modes | Description |
+ |----------------------------|------------------------------------------|
+ | CANOP_MODE_NORMAL | Indicates CAN controller is in normal |
+ | | operational mode. |
+ | CANOP_MODE_LISTEN_ONLY | Indicates CAN controller is in listen |
+ | | only mode. |
+ | CANOP_MODE_EXT_LOOPBACK | Indicates CAN controller is in external |
+ | | loop back mode. |
+ | CANOP_MODE_INT_LOOPBACK | Indicates CAN controller is in internal |
+ | | loop back mode. |
+ | CANOP_SRAM_TEST_MODE | Indicates CAN controller is in test mode.|
+ | CANOP_SW_RESET | Indicates CAN controller is in stop mode.|
+
+ */
+typedef enum mss_can_mode
+{
+ CANOP_MODE_NORMAL = 0x01u,
+ CANOP_MODE_LISTEN_ONLY = 0x03u,
+ CANOP_MODE_EXT_LOOPBACK = 0x05u,
+ CANOP_MODE_INT_LOOPBACK = 0x07u,
+ CANOP_SRAM_TEST_MODE = 0x08u,
+ CANOP_SW_RESET = 0x10u
+} mss_can_mode_t;
+
+typedef struct _mss_can_msgobject
+{
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields. */
+ union
+ {
+ __IO uint32_t L; /* 32 bit flag */
+ struct
+ {
+ /* Flags structure. */
+ __IO uint32_t NA0:16;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:10;
+ };
+ };
+} mss_can_msgobject;
+
+typedef mss_can_msgobject * pmss_can_msgobject;
+
+/* _CAN_filterobject */
+
+typedef struct _CAN_filterobject
+{
+ /* Acceptance mask settings */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } AMR;
+
+ /* Acceptance code settings */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } ACR;
+
+ /* Acceptance mask and code settings for first two data bytes */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t MASK:16;
+ __IO uint32_t CODE:16;
+ };
+ } AMCR_D;
+} mss_can_filterobject;
+
+typedef mss_can_filterobject * pmss_can_filterobject;
+
+/*_CAN_txmsgobject */
+
+typedef struct _CAN_txmsgobject
+{
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields.*/
+ union
+ {
+ __IO uint32_t L;
+
+ /* Tx Flags structure. */
+ struct
+ {
+ __IO uint32_t TXREQ:1;
+ __IO uint32_t TXABORT:1;
+ __IO uint32_t TXINTEBL:1;
+ __IO uint32_t WPNL:1;
+ __IO uint32_t NA0:12;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:1;
+ __IO uint32_t WPNH:1;
+ __IO uint32_t NA2:8;
+ };
+ } TXB;
+
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+} mss_can_txmsgobject;
+
+/* _mss_can_rxmsgobject */
+
+typedef struct _mss_can_rxmsgobject
+{
+ /* CAN Message flags and smaller values organized as one single 32 bit word
+ or a number of bit fields. */
+ union
+ {
+ __IO uint32_t L; /* 32 bit flag */
+
+ /* Tx Flags structure. */
+ struct
+ {
+ __IO uint32_t MSGAV:1;
+ __IO uint32_t RTRREPLYPEND:1;
+ __IO uint32_t RTRABORT:1;
+ __IO uint32_t BUFFEREBL:1;
+ __IO uint32_t RTRREPLY:1;
+ __IO uint32_t RXINTEBL:1;
+ __IO uint32_t LINKFLAG:1;
+ __IO uint32_t WPNL:1;
+ __IO uint32_t NA0:8;
+ __IO uint32_t DLC:4;
+ __IO uint32_t IDE:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t NA1:1;
+ __IO uint32_t WPNH:1;
+ __IO uint32_t NA2:8;
+ };
+ } RXB;
+
+ /* CAN Message ID. */
+ struct
+ {
+ __IO uint32_t N_ID:3;
+ __IO uint32_t ID:29;
+ };
+
+ /* CAN Message Data organized as two 32 bit words or 8 data bytes */
+ union
+ {
+ struct
+ {
+ __IO uint32_t DATAHIGH;
+ __IO uint32_t DATALOW;
+ };
+ __IO int8_t DATA[8];
+ };
+
+ /* CAN Message Filter: Acceptance mask register */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } AMR;
+
+ /* CAN Message Filter: Acceptance code register */
+ union
+ {
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A:1;
+ __IO uint32_t RTR:1;
+ __IO uint32_t IDE:1;
+ __IO uint32_t ID:29;
+ };
+ } ACR;
+
+ __IO uint32_t AMR_D;
+ __IO uint32_t ACR_D;
+
+} mss_can_rxmsgobject;
+typedef mss_can_rxmsgobject * pmss_can_rxmsgobject;
+
+/* Error status register */
+typedef union error_status
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t TX_ERR_CNT:8;
+ __IO uint32_t RX_ERR_CNT:8;
+ __IO uint32_t ERROR_STAT:2;
+ __IO uint32_t TXGTE96:1;
+ __IO uint32_t RXGTE96:1;
+ __IO uint32_t N_A:12;
+ };
+} mss_can_error_status;
+
+/*
+ * Buffer status register For CANMOD3X,
+ * this are two 32-bit registers, for can, it is only one 32-bit register.
+ */
+#ifdef CANMOD3
+typedef union buffer_status
+{
+ __I uint32_t L;
+ struct
+ {
+ __I uint32_t RXMSGAV:16;
+ __I uint32_t TXREQ:8;
+ __I uint32_t N_A:8;
+ };
+#else
+typedef struct buffer_status
+{
+ __I uint32_t RXMSGAV;
+ __I uint32_t TXREQ;
+#endif
+} mss_can_buffer_status;
+
+/* Interrupt enable register */
+typedef union int_enable
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t INT_EBL:1;
+ __IO uint32_t N_A0:1;
+ __IO uint32_t ARB_LOSS:1;
+ __IO uint32_t OVR_LOAD:1;
+ __IO uint32_t BIT_ERR:1;
+ __IO uint32_t STUFF_ERR:1;
+ __IO uint32_t ACK_ERR:1;
+ __IO uint32_t FORM_ERR:1;
+ __IO uint32_t CRC_ERR:1;
+ __IO uint32_t BUS_OFF:1;
+ __IO uint32_t RX_MSG_LOSS:1;
+ __IO uint32_t TX_MSG:1;
+ __IO uint32_t RX_MSG:1;
+ __IO uint32_t RTR_MSG:1;
+ __IO uint32_t STUCK_AT_0:1;
+ __IO uint32_t SST_FAILURE:1;
+ __IO uint32_t N_A1:16;
+ };
+} mss_can_int_enable;
+
+typedef mss_can_int_enable * pmss_can_int_enable;
+
+/* Interrupt status register */
+typedef union int_status
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t N_A0:2;
+ __IO uint32_t ARB_LOSS:1;
+ __IO uint32_t OVR_LOAD:1;
+ __IO uint32_t BIT_ERR:1;
+ __IO uint32_t STUFF_ERR:1;
+ __IO uint32_t ACK_ERR:1;
+ __IO uint32_t FORM_ERR:1;
+ __IO uint32_t CRC_ERR:1;
+ __IO uint32_t BUS_OFF:1;
+ __IO uint32_t RX_MSG_LOSS:1;
+ __IO uint32_t TX_MSG:1;
+ __IO uint32_t RX_MSG:1;
+ __IO uint32_t RTR_MSG:1;
+ __IO uint32_t STUCK_AT_0:1;
+ __IO uint32_t SST_FAILURE:1;
+ __IO uint32_t N_A1:16;
+ };
+} mss_can_int_status;
+typedef mss_can_int_status * pmss_can_int_status;
+
+/* Command register */
+typedef union command_reg
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t RUN_STOP:1;
+ __IO uint32_t LISTEN_ONLY:1;
+ __IO uint32_t LOOP_BACK:1;
+ __IO uint32_t SRAM_TEST:1;
+ __IO uint32_t SW_RESET:1;
+ __IO uint32_t N_A:27;
+ };
+} mss_can_command_reg;
+
+/* Configuration register */
+typedef union can_config_reg
+{
+ __IO uint32_t L;
+ struct
+ {
+ __IO uint32_t EDGE_MODE:1;
+ __IO uint32_t SAMPLING_MODE:1;
+ __IO uint32_t CFG_SJW:2;
+ __IO uint32_t AUTO_RESTART:1;
+ __IO uint32_t CFG_TSEG2:3;
+ __IO uint32_t CFG_TSEG1:4;
+ __IO uint32_t CFG_ARBITER:1;
+ __IO uint32_t ENDIAN:1;
+ __IO uint32_t ECR_MODE:1;
+ __IO uint32_t N_A0:1;
+ __IO uint32_t CFG_BITRATE:15;
+ __IO uint32_t N_A1:1;
+ };
+} mss_can_config_reg;
+typedef mss_can_config_reg * pmss_can_config_reg ;
+
+/* Register mapping of CAN controller */
+typedef struct CAN_device
+{
+ mss_can_int_status IntStatus; /* Interrupt status register */
+ mss_can_int_enable IntEbl; /* Interrupt enable register */
+ mss_can_buffer_status BufferStatus; /* Buffer status indicators */
+ mss_can_error_status ErrorStatus; /* Error status */
+ mss_can_command_reg Command; /* CAN operating mode */
+ mss_can_config_reg Config; /* Configuration register */
+#ifdef CANMOD3
+ uint32_t NA[2];
+#else
+ uint32_t NA;
+#endif
+ mss_can_txmsgobject TxMsg[CAN_TX_MAILBOX]; /* Tx message buffers */
+ mss_can_rxmsgobject RxMsg[CAN_RX_MAILBOX]; /* Rx message buffers */
+
+} CAN_DEVICE;
+
+typedef CAN_DEVICE * PCAN_DEVICE;
+
+#define MSS_CAN_0_LO_BASE (CAN_DEVICE*)0x2010C000
+#define MSS_CAN_1_LO_BASE (CAN_DEVICE*)0x2010D000
+#define MSS_CAN_0_HI_BASE (CAN_DEVICE*)0x2810C000
+#define MSS_CAN_1_HI_BASE (CAN_DEVICE*)0x2810D000
+
+#define SYSREG_CAN_A_SOFTRESET_MASK ( (uint32_t)0x01u << 14u )
+#define SYSREG_CAN_B_SOFTRESET_MASK ( (uint32_t)0x01u << 15u )
+
+/*-------------------------------------------------------------------------*//**
+ The structure mss_can_instance_t is used by the driver to manage the
+ configuration and operation of each MSS CAN peripheral. The instance content
+ should only be accessed by using the respective API functions.
+
+ Each API function has a pointer to this instance as first argument.
+
+ */
+typedef struct can_instance
+{
+ /* Hardware related entries (pointer to device, interrupt number etc) */
+ CAN_DEVICE * hw_reg; /* Pointer to CAN registers. */
+ uint8_t irqn; /* refer to local or PLIC */
+ uint8_t int_type; /*!< 0 => local, 1 => PLIC */
+ /* Local data (eg pointer to local FIFO, irq number etc) */
+ uint8_t basic_can_rx_mb; /* number of rx mailboxes */
+ uint8_t basic_can_tx_mb; /* number of tx mailboxes */
+ } mss_can_instance_t;
+
+ /*------------------------------------------------------------------------*//**
+ This instances of mss_can_instance_t holds all data related to the operations
+ performed by CAN. A pointer to instance is passed as the first parameter
+ to CAN driver functions to indicate that which CAN instance should perform the
+ requested operation.
+ */
+extern mss_can_instance_t g_mss_can_0_lo;
+extern mss_can_instance_t g_mss_can_1_lo;
+extern mss_can_instance_t g_mss_can_0_hi;
+extern mss_can_instance_t g_mss_can_1_hi;
+
+/*----------------------------------------------------------------------------*/
+/*-----------------------MSS CAN Public APIs ---------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_init() function initializes the CAN driver as well as the CAN
+ controller. The basic_can_rx_mb and basic_can_tx_mb are used to configure the
+ number of receive and transmit mailboxes in basic CAN operation. This function
+ configures the CAN channel speed as per the “bitrate” parameter. It
+ initializes all receive mailboxes and make it ready for configuration. This is
+ the first function to be called before using any other function.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param bitrate
+ The bitRate parameter is used to configure CAN speed. The following standard
+ preset definitions are provided for systems with a PCLK1 of 8MHz, 16MHz or
+ 32MHz:
+ +-------------------+--------------------+--------------------+
+ | 8MHz PCLK1 | 16MHz PCLK1 | 32MHz PCLK1 |
+ +-------------------+--------------------+--------------------+
+ | CAN_SPEED_8M_5K | CAN_SPEED_16M_5K | CAN_SPEED_32M_5K |
+ | CAN_SPEED_8M_10K | CAN_SPEED_16M_10K | CAN_SPEED_32M_10K |
+ | CAN_SPEED_8M_20K | CAN_SPEED_16M_20K | CAN_SPEED_32M_20K |
+ | CAN_SPEED_8M_50K | CAN_SPEED_16M_50K | CAN_SPEED_32M_50K |
+ | CAN_SPEED_8M_100K | CAN_SPEED_16M_100K | CAN_SPEED_32M_100K |
+ | CAN_SPEED_8M_125K | CAN_SPEED_16M_125K | CAN_SPEED_32M_125K |
+ | CAN_SPEED_8M_250K | CAN_SPEED_16M_250K | CAN_SPEED_32M_250K |
+ | CAN_SPEED_8M_500K | CAN_SPEED_16M_500K | CAN_SPEED_32M_500K |
+ | CAN_SPEED_8M_1M | CAN_SPEED_16M_1M | CAN_SPEED_32M_1M |
+ +-------------------+--------------------+--------------------+
+
+ For custom settings, use CAN_SPEED_MANUAL and configure the settings via
+ pcan_config.
+
+ The default configurations can be altered by the addition of 0 or more of
+ the following:
+ - CAN_AUTO_RESTART
+ - CAN_ARB_FIXED_PRIO
+ - CAN_LITTLE_ENDIAN
+
+ @param pcan_config
+ The pcan_config parameter is a pointer to a mss_can_config_reg structure. This
+ structure is only used when bitrate is configured as CAN_SPEED_MANUAL.
+
+ When populating the mss_can_config_reg structure, the following should be noted:
+
+ 1. CFG_BITRATE defines the length of a CAN time quantum in terms of PCLK1
+ with 0 = 1 PCLK1, 1 = 2 PCLK1s and so on.
+ 2. A CAN bit time is made up of between 8 and 25 time quanta and the bit
+ rate is PCLK1 / ((CFG_BITRATE + 1) * number of time quanta per bit).
+ 3. There is a fixed overhead of 1 time quantum for synchronization at the
+ start of every CAN bit and the remaining time quanta in the bit are
+ allocated with CFG_TSEG1 and CFG_TSEG2.
+ 4. CFG_TSEG1 can have a value between 2 and 15 which represents between 3
+ and 16 time quanta.
+ 5. If SAMPLING_MODE is 0, CFG_TSEG2 can have a value between 1 and 7 which
+ represents between 2 and 8 time quanta and if SAMPLING_MODE is 1,
+ CFG_TSEG2 can have a value between 2 and 7 which represents between 3
+ and 8 time quanta.
+ 6. Receive sampling takes place at the end of the segment defined by
+ CFG_TSEG1.
+
+ For example, if CFG_TSEG1 = 3 and CFG_TSEG2 = 2 we get:
+
+ |<------------ 1 CAN bit time (8 time quanta)------------>|
+ /------+------+------+------+------+------+------+------\
+ -+ Synch | CFG_TSEG1 + 1 | CFG_TSEG2 + 1 +-
+ \------+------+------+------+------+------+------+------/
+ |
+ Receiver samples date here -->|
+
+ @param basic_can_rx_mb
+ The basic_can_rx_mb parameter is the number of receive mailboxes used in
+ basic CAN mode.
+
+ @param basic_can_tx_mb
+ The basic_can_tx_mb parameter is the number of transmit mailboxes used in
+ basic CAN mode.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_TSEG1_TOO_SMALL | Value provided to configure TSEG1 is too |
+ | | small |
+ | CAN_TSEG2_TOO_SMALL | Value provided to configure TSEG2 is too |
+ | | small |
+ | CAN_SJW_TOO_BIG | Value provided to configure synchronous jump|
+ | | width (SJW) is too big. |
+
+ Example 1: Using a default set for bitrate, tseg1, tseg2, and sjw and
+ additional configuration parameters.
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo, (CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16u,7u);
+
+ return(0);
+ }
+ @endcode
+
+ Example 2: Using custom settings for bitrate, tseg1, tseg2, and sjw.
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+
+ #define SYSTEM_CLOCK 8000000
+ #define BITS_PER_SECOND 10000
+
+ int e51(void)
+ {
+ mss_can_config_reg canreg;
+
+ canreg.CFG_BITRATE = (SYSTEM_CLOCK / (BITS_PER_SECOND * 8) - 1;
+ canreg.CFG_TSEG1 = 4;
+ canreg.CFG_TSEG2 = 1;
+ canreg.AUTO_RESTART = 0;
+ canreg.CFG_SJW = 0;
+ canreg.SAMPLING_MODE = 0;
+ canreg.EDGE_MODE = 0;
+ canreg.ENDIAN = 1;
+
+ MSS_CAN_init(&g_mss_can_0_lo,CAN_SPEED_MANUAL,&canreg,8,4);
+
+ return(0);
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_init
+(
+ mss_can_instance_t* this_can,
+ uint32_t bitrate,
+ pmss_can_config_reg pcan_config,
+ uint8_t basic_can_rx_mb,
+ uint8_t basic_can_tx_mb
+);
+
+ /*------------------------------------------------------------------------*//**
+ The MSS_CAN_set_config_reg() function sets the configuration register and
+ starts the CAN controller for normal mode operation. This function is used
+ when one needs to change the configuration settings while the CAN controller
+ was already initialized using MSS_CAN_init() function and is running.
+ MSS_CAN_set_config_reg() function should not be used when the CAN controller
+ wasn't initialized yet.
+
+ It performs following tasks:
+ - Clears all pending interrupts
+ - Stops CAN controller
+ - Disable interrupts
+ - Sets new configuration
+ - Starts CAN controller
+
+ @param this_can
+ The this_can parameter is a pointer to the MSS_CAN_instance_t structure.
+
+ @param cfg
+ The cfg parameter is a 4 bytes variable used to set the configuration
+ settings.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ mss_can_instance_t g_mss_can_0_lo;
+
+ int e51(void)
+ {
+ Return_status = MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | \
+ CAN_AUTO_RESTART | CAN_LITTLE_ENDIAN),
+ (pmss_can_config_reg)0,16,7);
+ ....
+
+ MSS_CAN_set_config_reg(&g_mss_can_0_lo, (CAN_SPEED_16M_500K | \
+ CAN_AUTO_RESTART | CAN_LITTLE_ENDIAN));
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_config_reg
+(
+ mss_can_instance_t* this_can,
+ uint32_t cfg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_mode() function sets the CAN controller operating mode based
+ on the mode parameter. After this operation CAN controller is not in
+ operational, to do that invoke MSS_CAN_start() function.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mode
+ The mode parameter tells about desired operating mode of CAN controller.
+ Possible operating modes are as mentioned below:
+
+ | Mode | Description |
+ |--------------------------|-----------------------------------------|
+ | CANOP_MODE_INT_LOOPBACK | Sets normal operating mode |
+ | CANOP_MODE_LISTEN_ONLY | In listen-only mode, the CAN controller |
+ | | does not send any messages. Normally |
+ | | used for automatic bitrate detection |
+ | CANOP_MODE_INT_LOOPBACK | Selects internal loopback mode. This is |
+ | | used for self-test |
+ | CANOP_MODE_EXT_LOOPBACK | Selects external loopback. The CAN |
+ | | controller will receive a copy of each |
+ | | message sent. |
+ | CANOP_SRAM_TEST_MODE | Sets SRAM test mode |
+ | CANOP_SW_RESET | Issues a software reset |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+
+ ....
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_mode
+(
+ mss_can_instance_t* this_can,
+ mss_can_mode_t mode
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_start() function clears all pending interrupts and enable CAN
+ controller to perform normal operation. It enables receive interrupts also.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+ MSS_CAN_start(&g_mss_can_0_lo);
+
+ ....
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_start
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_stop() function is used to disable the CAN controller.
+
+ NOTE: Interrupt flags status remain unaffected.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ MSS_CAN_init(&g_mss_can_0_lo,(CAN_SPEED_16M_500K | CAN_AUTO_RESTART | \
+ CAN_LITTLE_ENDIAN),(pmss_can_config_reg)0,16,7);
+ MSS_CAN_set_mode(&g_mss_can_0_lo,CANOP_MODE_INT_LOOPBACK);
+ MSS_CAN_start(&g_mss_can_0_lo);
+
+ ....
+ ....
+
+ MSS_CAN_stop(&g_mss_can_0_lo);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_stop
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_id() function returns the message identifier. Bits right
+ justified based on message identifier (Extended identifier) type.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns message identifier.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ...
+ return_id = MSS_CAN_get_id(&pmsg);
+
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_id
+(
+ pmss_can_msgobject pmsg
+);
+
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_id() function returns ID bits left justified based on IDE
+ type. IDE type might be either standard or extended.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns message identifier.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+ pmsg->ID = 0x120;
+ MSS_CAN_set_id(&pmsg);
+
+ ....
+ return(0);
+ }
+ @endcode
+*/
+uint32_t
+MSS_CAN_set_id
+(
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_msg_filter_mask() function packs the ID, IDE, and RTR bits
+ together as they are used in the message filter mask and returns packed
+ identifier.
+
+ @param id
+ The id parameter is a 4 byte variable to hold message identifier.
+
+ @param ide
+ The ide parameter is a 1 byte variable to indicate IDE type. Acceptable
+ values are as mentioned below:
+
+ | Value | Description |
+ |------------|-------------------------------|
+ | 0 | Standard format |
+ | 1 | Extended format |
+
+ @param rtr
+ The rtr parameter is a 1 byte variable to indicate message type. Acceptable
+ values are as mentioned below:
+
+ | Value | Description |
+ |------------|-------------------------------|
+ | 0 | Regular message (data frame) |
+ | 1 | RTR message (remote frame) |
+
+ @return
+ This function returns packed id.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_msg_filter_mask( 0x120, 1, 0);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_msg_filter_mask
+(
+ uint32_t id,
+ uint8_t ide,
+ uint8_t rtr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_int_ebl() function enable specific interrupt based on
+ irq_flag parameter.
+
+ @param this_can
+ This is a pointer to an mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+
+ | Constants | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_set_int_ebl(&g_mss_can_0_lo,CAN_INT_TX_MSG);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_set_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_clear_int_ebl() function disable specific interrupt based on
+ irq_flag parameter.
+
+ @param this_can
+ This is a pointer to an mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+
+ | Constant | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_clear_int_ebl(&g_mss_can_0_lo,CAN_INT_TX_MSG);
+
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_clear_int_ebl
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_global_int_ebl() function returns the status of global
+ interrupt enable flag.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns global interrupt enable flag status.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_global_int_ebl(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_global_int_ebl
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_int_ebl() function returns the status of interrupt enable
+ flags.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns interrupt enable flag status.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_int_ebl(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_int_ebl
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_clear_int_status() function clears the selected interrupt flags.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param irq_flag
+ The irq_flag parameter is a 4 byte variable indicates Interrupt type.
+ Possible values are:
+ | Constants | Description |
+ |------------------------|------------------------------------------------|
+ | CAN_INT_GLOBAL | Indicates to enable global interrupts |
+ | CAN_INT_ARB_LOSS | Indicates arbitration loss interrupt |
+ | CAN_INT_OVR_LOAD | Indicates overload message detected interrupt |
+ | CAN_INT_BIT_ERR | Indicates bit error interrupt |
+ | CAN_INT_STUFF_ERR | Indicates bit stuffing error interrupt |
+ | CAN_INT_ACK_ERR | Indicates acknowledge error interrupt |
+ | CAN_INT_FORM_ERR | Indicates format error interrupt |
+ | CAN_INT_CRC_ERR | Indicates CRC error interrupt |
+ | CAN_INT_BUS_OFF | Indicates bus off interrupt |
+ | CAN_INT_RX_MSG_LOST | Indicates received message lost interrupt |
+ | CAN_INT_TX_MSG | Indicates message transmit interrupt |
+ | CAN_INT_RX_MSG | Indicates receive message available interrupt |
+ | CAN_INT_RTR_MSG | Indicates RTR auto-reply message sent interrupt|
+ | CAN_INT_STUCK_AT_0 | Indicates stuck at dominant error interrupt |
+ | CAN_INT_SST_FAILURE | Indicates single shot transmission failure |
+ | | interrupt |
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+ MSS_CAN_clear_int_status(&g_mss_can_0_lo,CAN_INT_RX_MSG);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_CAN_clear_int_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t irq_flag
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_int_status() function returns the status of interrupts.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of existed interrupts.
+
+ Example:
+ @code
+ int e51(void)
+ {
+ ....
+
+ MSS_CAN_get_int_status(&g_mss_can_0_lo);
+ ....
+ return(0);
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_int_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_rtr_message_n () function loads mailbox with the given CAN
+ message. This message will be sent out after receipt of a RTR message
+ request. It verifies that whether the given mailbox is configured for Full
+ CAN or not and also checks for RTR auto-reply is enabled or not.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+ | CAN_NO_RTR_MAILBOX | Indicates that there is no mailbox for |
+ | | remote transmit request (RTR) frame |
+
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ pmsg->ID = 0x120;
+ pmsg->DATALOW = 0xAA5555AA;
+ pmsg->DATAHIGH = 0xAA5555AA;
+
+ MSS_CAN_set_rtr_message_n(&g_mss_can_0_lo, 5, &pmsg);
+
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_set_rtr_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rtr_message_abort_n() function aborts a RTR message transmit
+ request on mailbox mailbox_number and checks that message abort was
+ successful.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ ret_status = MSS_CAN_get_rtr_message_abort_n((&g_mss_can_0_lo, 6);
+
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_get_rtr_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_config_buffer() function configures receive mailboxes initialized
+ for Basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pfilter
+ The pfilter parameter is a pointer to the CAN message filter structure.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ pfilter.ACR.L=0x00000000;
+ pfilter.AMR.L= 0xFFFFFFFF;
+ pfilter.AMCR_D.MASK= 0xFFFF;
+ pfilter.AMCR_D.CODE= 0x00;
+
+ ret_status = MSS_CAN_config_buffer(&g_mss_can_0_lo, &pfilter);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_config_buffer
+(
+ mss_can_instance_t* this_can,
+ pmss_can_filterobject pfilter
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_config_buffer_n() function configures the receive mailbox
+ specified in mailbox_number. The function checks that the mailbox is set for
+ Full CAN operation, if not it return with error code.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it will
+ returns following error codes
+ - CAN_BASIC_CAN_MAILBOX
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ rx_msg.ID = 0x200;
+ rx_msg.DATAHIGH = 0u;
+ rx_msg.DATALOW = 0u;
+ rx_msg.AMR.L = 0xFFFFFFFF;
+ rx_msg.ACR.L = 0x00000000;
+ rx_msg.AMR_D = 0x0000FFFF;
+ rx_msg.ACR_D = 0x00000000;
+ rx_msg.RXB.DLC = 8u;
+ rx_msg.RXB.IDE = 0;
+
+ ret_status = MSS_CAN_config_buffer_n(&g_mss_can_0_lo, 3, &rx_msg);
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_config_buffer_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_rxmsgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message_n() function read message from the receive mailbox
+ specified in "mailbox_number" parameter and returns status of operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that will hold the
+ received message.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject msg;
+ ...
+
+ ret_status = MSS_CAN_get_message_n(&g_mss_can_0_lo, 3, &msg);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message() function read message from the first mailbox set
+ for Basic CAN operation that contains a message. Once the message has been
+ read from the mailbox, the message receipt is acknowledged.
+ Note: Since neither a hardware nor a software FIFO exists, message inversion
+ might happen (example, a newer message might be read from the receive
+ buffer prior to an older message).
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object, that will hold the
+ received message.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject rx_buf;
+ ...
+ if(CAN_VALID_MSG == MSS_CAN_get_message_av(&g_mss_can_0_lo))
+ {
+ if(CAN_VALID_MSG != MSS_CAN_get_message(&g_mss_can_0_lo, &rx_buf))
+ {
+ ....
+ }
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_message_av() function indicates if receive buffer contains a
+ new message in Basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject rx_buf;
+ ...
+ if(CAN_VALID_MSG == MSS_CAN_get_message_av(&g_mss_can_0_lo))
+ {
+ MSS_CAN_get_message(&g_mss_can_0_lo, &rx_buf);
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_message_av
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_n() function sends a message using mailbox
+ "mailbox_number". The function verifies that this mailbox is configured for
+ Full CAN operation and is empty.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that holds the CAN
+ message to transmit.
+
+ @return
+ This function returns CAN_VALID_MSG on successful execution, otherwise it
+ will return the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_NO_MSG | Indicates that there is no message received |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID=0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0<<20)| 0x00080000);
+
+ if (CAN_OK != MSS_CAN_send_message_n(&g_mss_can_0_lo, 0, &pmsg))
+ {
+ ...
+ }
+
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_abort_n() function aborts a message transmit
+ request for the specified mailbox number in mailbox_number and checks that
+ message abort status.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @return
+ This function returns CAN_OK on successful execution, otherwise it
+ will return the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ if (CAN_OK != MSS_CAN_send_message_abort_n(&g_mss_can_0_lo, 0))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_abort_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message_ready() function will identify the availability of
+ mailbox to fill with new message in basic CAN operation.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns CAN_OK on successful identification of free mailbox,
+ otherwise it will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID = 0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0 << 20)| 0x00080000);
+
+ if(CAN_OK == MSS_CAN_send_message_ready(&g_mss_can_0_lo))
+ {
+ MSS_CAN_send_message(&g_mss_can_0_lo, &pmsg);
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message_ready
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_send_message() function will copy the data to the first available
+ mailbox set for Basic CAN operation and send data on to the bus.
+ Note: Since neither a hardware nor a software FIFO exists, message inversion
+ might happen (example, a newer message might be send from the transmit
+ buffer prior to an older message).
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param pmsg
+ The pmsg parameter is a pointer to the message object that holds the CAN
+ message to transmit.
+
+ @return
+ This function returns CAN_OK on successful identification of free mailbox,
+ otherwise it will returns following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_ERR | Indicates error condition |
+ | CAN_INVALID_MAILBOX | Indicates invalid mailbox number |
+
+ Example:
+ @code
+ e51()
+ {
+ pmss_can_msgobject pmsg;
+ ...
+ pmsg.ID = 0x120;
+ pmsg.DATALOW = 0x55555555;
+ pmsg.DATAHIGH = 0x55555555;
+ pmsg.L = ((0 << 20)| 0x00080000);
+
+ if (CAN_OK == MSS_CAN_send_message_ready(&g_mss_can_0_lo))
+ {
+ if (CAN_OK != MSS_CAN_send_message(&g_mss_can_0_lo, &pmsg))
+ {
+ ...
+ }
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_send_message
+(
+ mss_can_instance_t* this_can,
+ pmss_can_msgobject pmsg
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_mask_n() function returns the message filter settings of the
+ selected receive mailbox. The function is valid for Full CAN operation only.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param pamr
+ The pamr parameter is a pointer to the acceptance mask.
+
+ @param pacr
+ The pacr parameter is a pointer to the acceptance code.
+
+ @param pdta_amr
+ The pdta_amr parameter is a pointer to the acceptance mask of first two
+ data bytes.
+
+ @param pdta_acr
+ The pdta_acr parameter is a pointer to the acceptance code of first two
+ data bytes.
+
+ @return
+ This function will returns the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+
+ if (CAN_OK != MSS_CAN_get_mask_n(&g_mss_can_0_lo,mailbox_number,&pamr,&pacr,
+ &pdamr, &pdacr))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+*/
+uint8_t
+MSS_CAN_get_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t *pamr,
+ uint32_t *pacr,
+ uint16_t *pdta_amr,
+ uint16_t *pdta_acr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_set_mask_n() function configures the message filter settings for
+ the selected receive mailbox. The function is valid for Full CAN operation
+ only.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param mailbox_number
+ The mailbox_number parameter is a variable to hold the mailbox number to
+ be used for message transfer.
+
+ @param amr
+ The amr parameter is a variable to hold the acceptance mask.
+
+ @param acr
+ The acr parameter is a variable to hold the acceptance code.
+
+ @param dta_amr
+ The dta_amr parameter is a variable to hold the acceptance mask of first two
+ data bytes.
+
+ @param dta_acr
+ The dta_acr parameter is a variable to hold the acceptance code of first two
+ data bytes.
+
+ @return
+ This function returns the following error codes:
+
+ | Constants | Description |
+ |-----------------------|---------------------------------------------|
+ | CAN_OK | Indicates there is no error |
+ | CAN_BASIC_CAN_MAILBOX | Indicates that mailbox is configured for |
+ | | Basic CAN operation |
+
+ Example:
+ @code
+ e51()
+ {
+ ...
+ if (CAN_OK != MSS_CAN_set_mask_n(&g_mss_can_0_lo,mailbox_number,&pamr,&pacr,
+ &pdamr, &pdacr))
+ {
+ ...
+ }
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_set_mask_n
+(
+ mss_can_instance_t* this_can,
+ uint8_t mailbox_number,
+ uint32_t amr,
+ uint32_t acr,
+ uint16_t dta_amr,
+ uint16_t dta_acr
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_buffer_status() function returns the buffer status of all
+ receive (32) mailboxes.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of receive buffers (32 buffers).
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status=0;
+ ...
+ return_status = MSS_CAN_get_rx_buffer_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_buffer_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_buffer_status() function returns the buffer status of all
+ transmit(32) mailboxes.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns status of transmit buffers (32 buffers).
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_buffer_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+*/
+uint32_t
+MSS_CAN_get_tx_buffer_status
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_error_status() function returns the present error state of
+ the CAN controller. Error state might be error active or error passive or
+ bus-off.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @param status
+ The status parameter is a pointer to hold the content of error status
+ register.
+
+ @return
+ The function shall return the following codes:
+ | Codes | Descriptions |
+ |--------|-------------------------------|
+ | 0 | error active |
+ | 1 | error passive |
+ | 2 | bus-off |
+
+ Example:
+ @code
+ e51()
+ {
+ uint8_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_error_status(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint8_t
+MSS_CAN_get_error_status
+(
+ mss_can_instance_t* this_can,
+ uint32_t* status
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_error_count() function returns the current receive error
+ counter value. Counter value ranges from 0x00 - 0xFF.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns the receive error counter value.
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_rx_error_count(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_error_count
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_rx_gte96() function provides information about receive
+ error count. It identifies that receive error count is greater than or equal
+ to 96, and reports 1 if count exceeds 96.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns following values:
+
+ | Value | Description |
+ |-------|------------------------------------------------------|
+ | 0 | if receive error count less than 96. |
+ | 1 | if receive error count greater than or equals to 96. |
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_rx_gte96(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_rx_gte96
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_error_count() function returns the current transmit error
+ counter value. Counter value ranges from 0x00 - 0xFF.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns the transmit error counter value.
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_error_count(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_tx_error_count
+(
+ mss_can_instance_t* this_can
+);
+
+/*-------------------------------------------------------------------------*//**
+ The MSS_CAN_get_tx_gte96() function provides information about transmit
+ error count. It identifies that transmit error count is greater than or equals
+ to 96, and reports 1 if count exceeds 96.
+
+ @param this_can
+ The this_can parameter is a pointer to the mss_can_instance_t structure.
+
+ @return
+ This function returns following values:
+
+ | Value | Description |
+ |-------|-------------------------------------------------------|
+ | 0 | if transmit error count less than 96. |
+ | 1 | if transmit error count greater than or equals to 96. |
+
+ Example:
+ @code
+ e51()
+ {
+ uint32_t return_status = 0;
+ ...
+ return_status = MSS_CAN_get_tx_gte96(&g_mss_can_0_lo);
+ ...
+ }
+ @endcode
+ */
+uint32_t
+MSS_CAN_get_tx_gte96
+(
+ mss_can_instance_t* this_can
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_CAN_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart.c b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart.c
new file mode 100644
index 00000000..3c63ce71
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart.c
@@ -0,0 +1,1841 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver
+ * implementation.
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+#include "mss_uart_regs.h"
+#include "mss_uart.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MSS_UART0_LO_BASE (MSS_UART_TypeDef*)0x20000000UL
+#define MSS_UART1_LO_BASE (MSS_UART_TypeDef*)0x20100000UL
+#define MSS_UART2_LO_BASE (MSS_UART_TypeDef*)0x20102000UL
+#define MSS_UART3_LO_BASE (MSS_UART_TypeDef*)0x20104000UL
+#define MSS_UART4_LO_BASE (MSS_UART_TypeDef*)0x20106000UL
+
+#define MSS_UART0_HI_BASE (MSS_UART_TypeDef*)0x28000000UL
+#define MSS_UART1_HI_BASE (MSS_UART_TypeDef*)0x28100000UL
+#define MSS_UART2_HI_BASE (MSS_UART_TypeDef*)0x28102000UL
+#define MSS_UART3_HI_BASE (MSS_UART_TypeDef*)0x28104000UL
+#define MSS_UART4_HI_BASE (MSS_UART_TypeDef*)0x28106000UL
+
+
+mss_uart_instance_t g_mss_uart0_lo;
+mss_uart_instance_t g_mss_uart1_lo;
+mss_uart_instance_t g_mss_uart2_lo;
+mss_uart_instance_t g_mss_uart3_lo;
+mss_uart_instance_t g_mss_uart4_lo;
+
+mss_uart_instance_t g_mss_uart0_hi;
+mss_uart_instance_t g_mss_uart1_hi;
+mss_uart_instance_t g_mss_uart2_hi;
+mss_uart_instance_t g_mss_uart3_hi;
+mss_uart_instance_t g_mss_uart4_hi;
+
+/* This variable tracks if the UART peripheral is located on S5 or S6 on AXI
+ * switch. This will be used to determine which UART instance to be passed to
+ * UART interrupt handler. value 0 = S5(low). value 1 = S6(high)
+ * Bit positions:
+ * 0 ==> MMUART0
+ * 1 ==> MMUART1
+ * 2 ==> MMUART2
+ * 3 ==> MMUART3
+ * 4 ==> MMUART4
+
+ */
+static uint32_t g_uart_axi_pos = 0x0u;
+
+/*******************************************************************************
+ * Defines
+ */
+#define TX_COMPLETE 0u
+#define TX_FIFO_SIZE 16u
+
+#define FCR_TRIG_LEVEL_MASK 0xC0u
+
+#define IIRF_MASK 0x0Fu
+
+#define INVALID_INTERRUPT 0u
+#define INVALID_IRQ_HANDLER ((mss_uart_irq_handler_t) 0)
+#define NULL_HANDLER ((mss_uart_irq_handler_t) 0)
+
+#define MSS_UART_DATA_READY ((uint8_t) 0x01)
+
+#define SYNC_ASYNC_MODE_MASK (0x7u)
+
+#define UART0_POSITION_MASK 0x01u
+#define UART1_POSITION_MASK 0x02u
+#define UART2_POSITION_MASK 0x04u
+#define UART3_POSITION_MASK 0x08u
+#define UART4_POSITION_MASK 0x10u
+
+/*******************************************************************************
+ * Possible values for Interrupt Identification Register Field.
+ */
+#define IIRF_MODEM_STATUS 0x00u
+#define IIRF_THRE 0x02u
+#define IIRF_MMI 0x03u
+#define IIRF_RX_DATA 0x04u
+#define IIRF_RX_LINE_STATUS 0x06u
+#define IIRF_DATA_TIMEOUT 0x0Cu
+
+/*******************************************************************************
+ * Receiver error status mask.
+ */
+#define STATUS_ERROR_MASK ( MSS_UART_OVERUN_ERROR | MSS_UART_PARITY_ERROR | \
+ MSS_UART_FRAMING_ERROR | MSS_UART_BREAK_ERROR | \
+ MSS_UART_FIFO_ERROR)
+
+/*******************************************************************************
+ * Local functions.
+ */
+static void global_init(mss_uart_instance_t * this_uart, uint32_t baud_rate,
+ uint8_t line_config);
+static void uart_isr(mss_uart_instance_t * this_uart);
+static void default_tx_handler(mss_uart_instance_t * this_uart);
+static void enable_irq(const mss_uart_instance_t * this_uart);
+static void disable_irq(const mss_uart_instance_t * this_uart);
+static void config_baud_divisors
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baudrate
+);
+
+/*******************************************************************************
+ * Public Functions
+ *******************************************************************************/
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Disable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+
+ /* set default tx handler for automated TX using interrupt in USART mode */
+ this_uart->tx_handler = default_tx_handler;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void MSS_UART_lin_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Enable LIN mode */
+ this_uart->hw_reg->MM0 |= ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_irda_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config,
+ mss_uart_rzi_polarity_t rxpol,
+ mss_uart_rzi_polarity_t txpol,
+ mss_uart_rzi_pulsewidth_t pw
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Enable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 |= EIRD_MASK;
+
+ ((rxpol == MSS_UART_ACTIVE_LOW) ? (this_uart->hw_reg->MM1 &= ~EIRX_MASK) :
+ (this_uart->hw_reg->MM1 |= EIRX_MASK));
+
+ ((txpol == MSS_UART_ACTIVE_LOW) ? (this_uart->hw_reg->MM1 &= ~EITX_MASK) :
+ (this_uart->hw_reg->MM1 |= EITX_MASK));
+
+ ((pw == MSS_UART_3_BY_16) ? (this_uart->hw_reg->MM1 &= ~EITP_MASK) :
+ (this_uart->hw_reg->MM1 |= EITP_MASK));
+ /* Disable SmartCard Mode */
+ this_uart->hw_reg->MM2 &= ~EERR_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_smartcard_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ /* Perform generic initialization */
+ global_init(this_uart, baud_rate, line_config);
+
+ /* Disable LIN mode */
+ this_uart->hw_reg->MM0 &= ~ELIN_MASK;
+
+ /* Disable IrDA mode */
+ this_uart->hw_reg->MM1 &= ~EIRD_MASK;
+
+ /* Enable SmartCard Mode : Only when data is 8-bit and 2 stop bits */
+ if ((MSS_UART_DATA_8_BITS | MSS_UART_TWO_STOP_BITS) ==
+ (line_config & (MSS_UART_DATA_8_BITS | MSS_UART_TWO_STOP_BITS)))
+ {
+ this_uart->hw_reg->MM2 |= EERR_MASK;
+
+ /* Enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 |= ESWM_MASK;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_polled_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+)
+{
+ uint32_t char_idx = 0u;
+ uint32_t size_sent;
+ uint8_t status;
+ uint32_t temp_tx_size = tx_size;
+
+ ASSERT(pbuff != ( (uint8_t*)0));
+ ASSERT(tx_size > 0u);
+
+ if ((pbuff != ((uint8_t*)0)) && (temp_tx_size > 0u))
+ {
+ /* Remain in this loop until the entire input buffer
+ * has been transferred to the UART.
+ */
+ do
+ {
+ /* Read the Line Status Register and update the sticky record */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /* Check if TX FIFO is empty. */
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t fill_size = TX_FIFO_SIZE;
+
+ /* Calculate the number of bytes to transmit. */
+ if (temp_tx_size < TX_FIFO_SIZE)
+ {
+ fill_size = temp_tx_size;
+ }
+
+ /* Fill the TX FIFO with the calculated the number of bytes. */
+ for (size_sent = 0u; size_sent < fill_size; ++size_sent)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = pbuff[char_idx];
+ char_idx++;
+ }
+
+ /* find the number of bytes remaining(not transmitted yet) */
+ temp_tx_size -= size_sent;
+ }
+ }while (temp_tx_size);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_polled_tx_string
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * p_sz_string
+)
+{
+ uint32_t char_idx = 0u;
+ uint32_t fill_size;
+ uint8_t data_byte;
+ uint8_t status;
+
+ ASSERT(p_sz_string != ((uint8_t*)0));
+
+ if (p_sz_string != ((uint8_t*)0))
+ {
+ /* Get the first data byte from the input buffer */
+ data_byte = p_sz_string[char_idx];
+
+ /* First check for the NULL terminator byte.
+ * Then remain in this loop until the entire string in the input buffer
+ * has been transferred to the UART.
+ */
+ while (0u != data_byte)
+ {
+ /* Wait until TX FIFO is empty. */
+ do
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+ }while (0u == (status & MSS_UART_THRE));
+
+ /* Send bytes from the input buffer until the TX FIFO is full
+ * or we reach the NULL terminator byte.
+ */
+ fill_size = 0u;
+
+ while ((0u != data_byte) && (fill_size < TX_FIFO_SIZE))
+ {
+ /* Send the data byte */
+ this_uart->hw_reg->THR = data_byte;
+ ++fill_size;
+ char_idx++;
+ /* Get the next data byte from the input buffer */
+ data_byte = p_sz_string[char_idx];
+ }
+ }
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_irq_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+)
+{
+ ASSERT(pbuff != ((uint8_t*)0));
+ ASSERT(tx_size > 0u);
+
+ if ((tx_size > 0u) && (pbuff != ((uint8_t*)0)))
+ {
+ /* Initialize the transmit info for the UART instance with the
+ * arguments */
+ this_uart->tx_buffer = pbuff;
+ this_uart->tx_buff_size = tx_size;
+ this_uart->tx_idx = 0u;
+
+ /* assign default handler for data transfer */
+ this_uart->tx_handler = default_tx_handler;
+
+ /* enables TX interrupt */
+ this_uart->hw_reg->IER |= ETBEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+int8_t
+MSS_UART_tx_complete
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ int8_t ret_value = 0;
+ uint8_t status = 0u;
+
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ if ((TX_COMPLETE == this_uart->tx_buff_size) &&
+ ((status & MSS_UART_TEMT) != 0u))
+ {
+ ret_value = (int8_t)1;
+ }
+
+ return ret_value;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+size_t
+MSS_UART_get_rx
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t * rx_buff,
+ size_t buff_size
+)
+{
+ size_t rx_size = 0u;
+ uint8_t status = 0u;
+
+ ASSERT(rx_buff != ((uint8_t*)0));
+ ASSERT(buff_size > 0u);
+
+ if ((rx_buff != (uint8_t*)0) && (buff_size > 0u))
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ while (((status & MSS_UART_DATA_READY) != 0u) && (rx_size < buff_size))
+ {
+ rx_buff[rx_size] = this_uart->hw_reg->RBR;
+ ++rx_size;
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+ }
+ }
+
+ return rx_size;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+)
+{
+ ASSERT(MSS_UART_INVALID_IRQ > irq_mask);
+
+ enable_irq(this_uart);
+
+ if (MSS_UART_INVALID_IRQ > irq_mask)
+ {
+ /* irq_mask encoding: 1- enable
+ * bit 0 - Receive Data Available Interrupt
+ * bit 1 - Transmitter Holding Register Empty Interrupt
+ * bit 2 - Receiver Line Status Interrupt
+ * bit 3 - Modem Status Interrupt
+ */
+ this_uart->hw_reg->IER |= ((uint8_t)(((uint32_t)irq_mask &
+ (uint32_t)IIRF_MASK)));
+
+
+ /*
+ * bit 4 - Receiver time-out interrupt
+ * bit 5 - NACK / ERR signal interrupt
+ * bit 6 - PID parity error interrupt
+ * bit 7 - LIN break detection interrupt
+ * bit 8 - LIN Sync detection interrupt
+ */
+ this_uart->hw_reg->IEM |= (uint8_t)(((uint32_t)irq_mask >> 4u) &
+ ((uint32_t)IIRF_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+)
+{
+ /* irq_mask encoding: 1 - disable
+ * bit 0 - Receive Data Available Interrupt
+ * bit 1 - Transmitter Holding Register Empty Interrupt
+ * bit 2 - Receiver Line Status Interrupt
+ * bit 3 - Modem Status Interrupt
+ */
+ this_uart->hw_reg->IER &= ((uint8_t)(~((uint32_t)irq_mask &
+ (uint32_t)IIRF_MASK)));
+
+ /*
+ * bit 4 - Receiver time-out interrupt
+ * bit 5 - NACK / ERR signal interrupt
+ * bit 6 - PID parity error interrupt
+ * bit 7 - LIN break detection interrupt
+ * bit 8 - LIN Sync detection interrupt
+ */
+ this_uart->hw_reg->IEM &= (uint8_t)(~(((uint32_t)irq_mask >> 4u) &
+ ((uint32_t)IIRF_MASK)));
+
+ if(1 == this_uart->local_irq_enabled)
+ {
+ __disable_local_irq((int8_t)MMUART0_E51_INT);
+ }
+ else
+ {
+ disable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler,
+ mss_uart_rx_trig_level_t trigger_level
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER );
+ ASSERT(trigger_level < MSS_UART_FIFO_INVALID_TRIG_LEVEL);
+
+ if ((handler != INVALID_IRQ_HANDLER) &&
+ (trigger_level < MSS_UART_FIFO_INVALID_TRIG_LEVEL))
+ {
+ this_uart->rx_handler = handler;
+
+ /* Set the receive interrupt trigger level. */
+ this_uart->hw_reg->FCR = (this_uart->hw_reg->FCR &
+ (uint8_t)(~((uint8_t)FCR_TRIG_LEVEL_MASK))) |
+ (uint8_t)trigger_level;
+
+ /* Enable receive interrupt. */
+ this_uart->hw_reg->IER |= ERBFI_MASK;
+
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_loopback
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_loopback_t loopback
+)
+{
+ ASSERT(MSS_UART_INVALID_LOOPBACK > loopback);
+
+ if (MSS_UART_INVALID_LOOPBACK > loopback)
+ {
+ switch (loopback)
+ {
+ case MSS_UART_LOCAL_LOOPBACK_OFF:
+ /* Disable local loopback */
+ this_uart->hw_reg->MCR &= ~LOOP_MASK;
+ break;
+
+ case MSS_UART_LOCAL_LOOPBACK_ON:
+ /* Enable local loopback */
+ this_uart->hw_reg->MCR |= LOOP_MASK;
+ break;
+
+ case MSS_UART_REMOTE_LOOPBACK_OFF:
+ case MSS_UART_AUTO_ECHO_OFF:
+ /* Disable remote loopback & automatic echo */
+ this_uart->hw_reg->MCR &= ~(RLOOP_MASK|ECHO_MASK);
+ break;
+
+ case MSS_UART_REMOTE_LOOPBACK_ON:
+ /* Enable remote loopback */
+ this_uart->hw_reg->MCR |= (1u << RLOOP);
+ break;
+
+ case MSS_UART_AUTO_ECHO_ON:
+ /* Enable automatic echo */
+ this_uart->hw_reg->MCR |= (1u << ECHO);
+ break;
+
+ case MSS_UART_INVALID_LOOPBACK:
+ /* Fall through to default. */
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+}
+
+/***************************************************************************//**
+ * interrupt service routine.
+ */
+uint8_t mmuart0_plic_77_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART0_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart0_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart0_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart1_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART1_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart1_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart1_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart2_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART2_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart2_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart2_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart3_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART3_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart3_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart3_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+uint8_t mmuart4_plic_IRQHandler(void)
+{
+ if (g_uart_axi_pos & UART4_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart4_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart4_lo);
+ }
+
+ return EXT_IRQ_KEEP_ENABLED;
+}
+
+void mmuart0_e51_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART0_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart0_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart0_lo);
+ }
+}
+
+void mmuart_u54_h1_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART1_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart1_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart1_lo);
+ }
+}
+
+void mmuart_u54_h2_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART2_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart2_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart2_lo);
+ }
+}
+
+void mmuart_u54_h3_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART3_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart3_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart3_lo);
+ }
+}
+
+void mmuart_u54_h4_local_IRQHandler_11(void)
+{
+ if (g_uart_axi_pos & UART4_POSITION_MASK)
+ {
+ uart_isr(&g_mss_uart4_hi);
+ }
+ else
+ {
+ uart_isr(&g_mss_uart4_lo);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rxstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->linests_handler = handler;
+
+ /* Enable receiver line status interrupt. */
+ this_uart->hw_reg->IER |= ELSI_MASK;
+
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_tx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->tx_handler = handler;
+
+ /* Make TX buffer info invalid */
+ this_uart->tx_buffer = (const uint8_t*)0;
+ this_uart->tx_buff_size = 0u;
+
+ /* Enable transmitter holding register Empty interrupt. */
+ this_uart->hw_reg->IER |= ETBEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_modemstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->modemsts_handler = handler;
+
+ /* Enable modem status interrupt. */
+ this_uart->hw_reg->IER |= EDSSI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+size_t
+MSS_UART_fill_tx_fifo
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * tx_buffer,
+ size_t tx_size
+)
+{
+ uint8_t status = 0u;
+ uint32_t size_sent = 0u;
+
+ ASSERT(tx_buffer != ( (uint8_t*)0));
+ ASSERT(tx_size > 0);
+
+ /* Fill the UART's Tx FIFO until the FIFO is full or the complete input
+ * buffer has been written. */
+ if ((tx_buffer != ((uint8_t*)0)) && (tx_size > 0u))
+ {
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t fill_size = TX_FIFO_SIZE;
+
+ if (tx_size < TX_FIFO_SIZE)
+ {
+ fill_size = tx_size;
+ }
+
+ /* Fill up FIFO */
+ for (size_sent = 0u; size_sent < fill_size; size_sent++)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = tx_buffer[size_sent];
+ }
+ }
+ }
+
+ return size_sent;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_rx_status
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_INVALID_PARAM;
+
+ /*
+ * Extract UART receive error status.
+ * Bit 1 - Overflow error status
+ * Bit 2 - Parity error status
+ * Bit 3 - Frame error status
+ * Bit 4 - Break interrupt indicator
+ * Bit 7 - FIFO data error status
+ */
+ this_uart->status |= (this_uart->hw_reg->LSR);
+ status = (this_uart->status & STATUS_ERROR_MASK);
+ /* Clear the sticky status after reading */
+ this_uart->status = 0u;
+
+ return status;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_modem_status
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_INVALID_PARAM;
+
+ /*
+ * Extract UART modem status and place in lower bits of "status".
+ * Bit 0 - Delta Clear to Send Indicator
+ * Bit 1 - Delta Clear to Receive Indicator
+ * Bit 2 - Trailing edge of Ring Indicator detector
+ * Bit 3 - Delta Data Carrier Detect indicator
+ * Bit 4 - Clear To Send
+ * Bit 5 - Data Set Ready
+ * Bit 6 - Ring Indicator
+ * Bit 7 - Data Carrier Detect
+ */
+ status = this_uart->hw_reg->MSR;
+
+ return status;
+}
+
+/***************************************************************************//**
+ * MSS_UART_get_tx_status.
+ * See mss_uart.h for details of how to use this function.
+ */
+uint8_t
+MSS_UART_get_tx_status
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status = MSS_UART_TX_BUSY;
+
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /*
+ * Extract the transmit status bits from the UART's Line Status Register.
+ * Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status.
+ (If = 1, TX FIFO is empty)
+ * Bit 6 - Transmitter Empty (TEMT) status.
+ (If = 1, both TX FIFO and shift register are empty)
+ */
+ status &= (MSS_UART_THRE | MSS_UART_TEMT);
+
+ return status;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_break
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* set break character on Tx line */
+ this_uart->hw_reg->LCR |= SB_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_clear_break
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* remove break character from Tx line */
+ this_uart->hw_reg->LCR &= ~SB_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_pidpei_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->pid_pei_handler = handler;
+
+ /* Enable PID parity error interrupt. */
+ this_uart->hw_reg->IEM |= EPID_PEI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_linbreak_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->break_handler = handler;
+
+ /* Enable LIN break detection interrupt. */
+ this_uart->hw_reg->IEM |= ELINBI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_linsync_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->sync_handler = handler;
+
+ /* Enable LIN sync detection interrupt. */
+ this_uart->hw_reg->IEM |= ELINSI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_nack_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->nack_handler = handler;
+
+ /* Enable LIN sync detection interrupt. */
+ this_uart->hw_reg->IEM |= ENACKI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_timeout_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+)
+{
+ ASSERT(handler != INVALID_IRQ_HANDLER);
+
+ if (handler != INVALID_IRQ_HANDLER)
+ {
+ this_uart->rto_handler = handler;
+
+ /* Enable receiver timeout interrupt. */
+ this_uart->hw_reg->IEM |= ERTOI_MASK;
+ enable_irq(this_uart);
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 |= ESWM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* enable single wire half-duplex mode */
+ this_uart->hw_reg->MM2 &= ~ESWM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_rx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+)
+{
+ ASSERT(MSS_UART_INVALID_ENDIAN > endian);
+
+ if (MSS_UART_INVALID_ENDIAN > endian)
+ {
+ /* Configure MSB first / LSB first for receiver */
+ ((MSS_UART_LITTLEEND == endian) ? (this_uart->hw_reg->MM1 &= ~E_MSB_RX_MASK) :
+ (this_uart->hw_reg->MM1 |= E_MSB_RX_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_tx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+)
+{
+ ASSERT(MSS_UART_INVALID_ENDIAN > endian);
+
+ if (MSS_UART_INVALID_ENDIAN > endian)
+ {
+ /* Configure MSB first / LSB first for transmitter */
+ ((MSS_UART_LITTLEEND == endian) ? (this_uart->hw_reg->MM1 &= ~E_MSB_TX_MASK) :
+ (this_uart->hw_reg->MM1 |= E_MSB_TX_MASK));
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_filter_length
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_filter_length_t length
+)
+{
+ ASSERT(MSS_UART_INVALID_FILTER_LENGTH > length);
+
+ if (MSS_UART_INVALID_FILTER_LENGTH > length)
+ {
+ /* Configure glitch filter length */
+ this_uart->hw_reg->GFR = (uint8_t)length;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_afm
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable RX FIFO till address flag with correct address is received */
+ this_uart->hw_reg->MM2 |= EAFM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_afm
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Enable RX FIFO irrespective of address flag and
+ correct address is received */
+ this_uart->hw_reg->MM2 &= ~EAFM_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_afclear
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Enable address flag clearing */
+ /* Disable RX FIFO till another address flag with
+ correct address is received */
+ this_uart->hw_reg->MM2 |= EAFC_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_afclear
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable address flag clearing */
+ this_uart->hw_reg->MM2 &= ~EAFC_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_rx_timeout
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeout
+)
+{
+ /* Load the receive timeout value */
+ this_uart->hw_reg->RTO = timeout;
+
+ /*Enable receiver time-out */
+ this_uart->hw_reg->MM0 |= ERTO_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_rx_timeout
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable receiver time-out */
+ this_uart->hw_reg->MM0 &= ~ERTO_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeguard
+)
+{
+ /* Load the transmitter time guard value */
+ this_uart->hw_reg->TTG = timeguard;
+
+ /* Enable transmitter time guard */
+ this_uart->hw_reg->MM0 |= ETTG_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_disable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Disable transmitter time guard */
+ this_uart->hw_reg->MM0 &= ~ETTG_MASK;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_address
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t address
+)
+{
+ this_uart->hw_reg->ADR = address;
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_ready_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_ready_mode_t mode
+)
+{
+ ASSERT(MSS_UART_INVALID_READY_MODE > mode);
+
+ if (MSS_UART_INVALID_READY_MODE > mode )
+ {
+ /* Configure mode 0 or mode 1 for TXRDY and RXRDY */
+ ((MSS_UART_READY_MODE0 == mode) ? (this_uart->hw_reg->FCR &= ~RDYMODE_MASK) :
+ (this_uart->hw_reg->FCR |= RDYMODE_MASK) );
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_set_usart_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_usart_mode_t mode
+)
+{
+ ASSERT(MSS_UART_INVALID_SYNC_MODE > mode);
+
+ if (MSS_UART_INVALID_SYNC_MODE > mode)
+ {
+ /* Nothing to do for the baudrate:
+ operates at PCLK / 2 + glitch filter length */
+ /* Clear the ESYN bits 2:0 */
+ this_uart->hw_reg->MM0 &= ~SYNC_ASYNC_MODE_MASK;
+ this_uart->hw_reg->MM0 |= (uint8_t)mode;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+void
+MSS_UART_enable_local_irq
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ /* Make sure to disable interrupt on PLIC as it might have been enabled
+ * when application registered an interrupt handler function or
+ * used MSS_UART_enable_irq() to enable PLIC interrupt */
+ disable_irq(this_uart);
+
+ this_uart->local_irq_enabled = 1u;
+
+ /* Enable local interrupt UART instance.
+ * Local interrupt will be enabled on the HART on which the application
+ * calling this API is being executed*/
+ __enable_local_irq((int8_t)MMUART0_E51_INT);
+}
+
+/*******************************************************************************
+ * Local Functions
+ ******************************************************************************/
+/*******************************************************************************
+ * Global initialization for all modes
+ */
+static void global_init
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+)
+{
+ if ((&g_mss_uart0_lo == this_uart))
+ {
+ this_uart->hw_reg = MSS_UART0_LO_BASE;
+ g_uart_axi_pos &= ~0x01u;
+ }
+
+ else if (&g_mss_uart1_lo == this_uart)
+ {
+
+ this_uart->hw_reg = MSS_UART1_LO_BASE;
+ g_uart_axi_pos &= ~0x02u;
+ }
+
+ else if (&g_mss_uart2_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART2_LO_BASE;
+ g_uart_axi_pos &= ~0x04u;
+ }
+
+ else if (&g_mss_uart3_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART3_LO_BASE;
+ g_uart_axi_pos &= ~0x08u;
+ }
+
+ else if (&g_mss_uart4_lo == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART4_LO_BASE;
+ g_uart_axi_pos &= ~0x10u;
+ }
+
+ else if ((&g_mss_uart0_hi == this_uart))
+ {
+ this_uart->hw_reg = MSS_UART0_HI_BASE;
+ g_uart_axi_pos |= 0x01u;
+ }
+
+ else if (&g_mss_uart1_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART1_HI_BASE;
+ g_uart_axi_pos |= 0x02u;
+ }
+
+ else if (&g_mss_uart2_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART2_HI_BASE;
+ g_uart_axi_pos |= 0x04u;
+ }
+
+ else if (&g_mss_uart3_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART3_HI_BASE;
+ g_uart_axi_pos |= 0x08u;
+ }
+
+ else if (&g_mss_uart4_hi == this_uart)
+ {
+ this_uart->hw_reg = MSS_UART4_HI_BASE;
+ g_uart_axi_pos |= 0x10u;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* disable interrupts */
+ this_uart->hw_reg->IER = 0u;
+
+ /* FIFO configuration */
+ this_uart->hw_reg->FCR = 0u;
+
+ /* clear receiver FIFO */
+ this_uart->hw_reg->FCR |= CLEAR_RX_FIFO_MASK;
+
+ /* clear transmitter FIFO */
+ this_uart->hw_reg->FCR |= CLEAR_TX_FIFO_MASK;
+
+ /* set default READY mode : Mode 0*/
+ /* enable RXRDYN and TXRDYN pins. The earlier FCR write to set the TX FIFO
+ * trigger level inadvertently disabled the FCR_RXRDY_TXRDYN_EN bit. */
+ this_uart->hw_reg->FCR |= RXRDY_TXRDYN_EN_MASK;
+
+ /* disable loopback : local * remote */
+ this_uart->hw_reg->MCR &= ~LOOP_MASK;
+
+ this_uart->hw_reg->MCR &= ~RLOOP_MASK;
+
+ /* set default TX endian */
+ this_uart->hw_reg->MM1 &= ~E_MSB_TX_MASK;
+
+ /* set default RX endian */
+ this_uart->hw_reg->MM1 &= ~E_MSB_RX_MASK;
+
+ /* default AFM : disabled */
+ this_uart->hw_reg->MM2 &= ~EAFM_MASK;
+
+ /* disable TX time guard */
+ this_uart->hw_reg->MM0 &= ~ETTG_MASK;
+
+ /* set default RX timeout */
+ this_uart->hw_reg->MM0 &= ~ERTO_MASK;
+
+ /* disable fractional baud-rate */
+ this_uart->hw_reg->MM0 &= ~EFBR_MASK;
+
+ /* disable single wire mode */
+ this_uart->hw_reg->MM2 &= ~ESWM_MASK;
+
+ /* set filter to minimum value */
+ this_uart->hw_reg->GFR = 0u;
+
+ /* set default TX time guard */
+ this_uart->hw_reg->TTG = 0u;
+
+ /* set default RX timeout */
+ this_uart->hw_reg->RTO = 0u;
+
+ /*
+ * Configure baud rate divisors. This uses the fractional baud rate divisor
+ * where possible to provide the most accurate baud rat possible.
+ */
+ config_baud_divisors(this_uart, baud_rate);
+
+ /* set the line control register (bit length, stop bits, parity) */
+ this_uart->hw_reg->LCR = line_config;
+
+ /* Instance setup */
+ this_uart->baudrate = baud_rate;
+ this_uart->lineconfig = line_config;
+ this_uart->tx_buff_size = TX_COMPLETE;
+ this_uart->tx_buffer = (const uint8_t*)0;
+ this_uart->tx_idx = 0u;
+
+ /* Default handlers for MSS UART interrupts */
+ this_uart->rx_handler = NULL_HANDLER;
+ this_uart->tx_handler = NULL_HANDLER;
+ this_uart->linests_handler = NULL_HANDLER;
+ this_uart->modemsts_handler = NULL_HANDLER;
+ this_uart->rto_handler = NULL_HANDLER;
+ this_uart->nack_handler = NULL_HANDLER;
+ this_uart->pid_pei_handler = NULL_HANDLER;
+ this_uart->break_handler = NULL_HANDLER;
+ this_uart->sync_handler = NULL_HANDLER;
+
+ this_uart->local_irq_enabled = 0u;
+
+ /* Initialize the sticky status */
+ this_uart->status = 0u;
+}
+
+/***************************************************************************//**
+ * Configure baud divisors using fractional baud rate if possible.
+ */
+static void
+config_baud_divisors
+(
+ mss_uart_instance_t * this_uart,
+ uint32_t baudrate
+)
+{
+ uint32_t baud_value;
+ uint32_t baud_value_by_64;
+ uint32_t baud_value_by_128;
+ uint32_t fractional_baud_value;
+ uint64_t pclk_freq;
+
+ this_uart->baudrate = baudrate;
+
+ pclk_freq = LIBERO_SETTING_MSS_APB_AHB_CLK;
+
+ /*
+ * Compute baud value based on requested baud rate and PCLK frequency.
+ * The baud value is computed using the following equation:
+ * baud_value = PCLK_Frequency / (baud_rate * 16)
+ */
+ baud_value_by_128 = (uint32_t)((8UL * pclk_freq) / baudrate);
+ baud_value_by_64 = baud_value_by_128 / 2u;
+ baud_value = baud_value_by_64 / 64u;
+ fractional_baud_value = baud_value_by_64 - (baud_value * 64u);
+ fractional_baud_value += (baud_value_by_128 - (baud_value * 128u))
+ - (fractional_baud_value * 2u);
+
+ /* Assert if integer baud value fits in 16-bit. */
+ ASSERT(baud_value <= UINT16_MAX);
+
+ if (baud_value <= (uint32_t)UINT16_MAX)
+ {
+ if (baud_value > 1u)
+ {
+ /* Use Fractional baud rate divisors */
+ /* set divisor latch */
+ this_uart->hw_reg->LCR |= DLAB_MASK;
+
+ /* MSB of baud value */
+ this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8);
+
+ /* LSB of baud value */
+ this_uart->hw_reg->DLR = (uint8_t)baud_value;
+
+ /* reset divisor latch */
+ this_uart->hw_reg->LCR &= ~DLAB_MASK;
+
+ /* Enable Fractional baud rate */
+ this_uart->hw_reg->MM0 |= EFBR_MASK;
+
+ /* Load the fractional baud rate register */
+ ASSERT(fractional_baud_value <= (uint32_t)UINT8_MAX);
+ this_uart->hw_reg->DFR = (uint8_t)fractional_baud_value;
+ }
+ else
+ {
+ /* Do NOT use Fractional baud rate divisors. */
+ /* set divisor latch */
+ this_uart->hw_reg->LCR |= DLAB_MASK;
+
+ /* MSB of baud value */
+ this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8u);
+
+ /* LSB of baud value */
+ this_uart->hw_reg->DLR = (uint8_t)baud_value;
+
+ /* reset divisor latch */
+ this_uart->hw_reg->LCR &= ~DLAB_MASK;
+
+ /* Disable Fractional baud rate */
+ this_uart->hw_reg->MM0 &= ~EFBR_MASK;
+ }
+ }
+}
+
+/***************************************************************************//**
+ * Interrupt service routine triggered by any MSS UART interrupt. This routine
+ * will call the handler function appropriate to the interrupt from the
+ * handlers previously registered with the driver through calls to the
+ * MSS_UART_set_*_handler() functions, or it will call the default_tx_handler()
+ * function in response to transmit interrupts if MSS_UART_irq_tx() is used to
+ * transmit data.
+ */
+static void
+uart_isr
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t iirf;
+
+ iirf = this_uart->hw_reg->IIR & IIRF_MASK;
+
+ switch (iirf)
+ {
+ case IIRF_MODEM_STATUS: /* Modem status interrupt */
+ {
+ ASSERT(NULL_HANDLER != this_uart->modemsts_handler);
+ if (NULL_HANDLER != this_uart->modemsts_handler)
+ {
+ (*(this_uart->modemsts_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_THRE: /* Transmitter Holding Register Empty */
+ {
+ ASSERT(NULL_HANDLER != this_uart->tx_handler);
+ if (NULL_HANDLER != this_uart->tx_handler)
+ {
+ (*(this_uart->tx_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_RX_DATA: /* Received Data Available */
+ case IIRF_DATA_TIMEOUT: /* Received Data Timed-out */
+ {
+ ASSERT(NULL_HANDLER != this_uart->rx_handler);
+ if (NULL_HANDLER != this_uart->rx_handler)
+ {
+ (*(this_uart->rx_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_RX_LINE_STATUS: /* Line Status Interrupt */
+ {
+ ASSERT(NULL_HANDLER != this_uart->linests_handler);
+ if (NULL_HANDLER != this_uart->linests_handler)
+ {
+ (*(this_uart->linests_handler))(this_uart);
+ }
+ }
+ break;
+
+ case IIRF_MMI:
+ {
+ /* Identify multi-mode interrupts and handle */
+
+ /* Receiver time-out interrupt */
+ if (this_uart->hw_reg->IIM & ERTOI_MASK)
+ {
+ ASSERT(NULL_HANDLER != this_uart->rto_handler);
+
+ if (NULL_HANDLER != this_uart->rto_handler)
+ {
+ (*(this_uart->rto_handler))(this_uart);
+ }
+ }
+
+ /* NACK interrupt */
+ if (this_uart->hw_reg->IIM &ENACKI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->nack_handler);
+
+ if (NULL_HANDLER != this_uart->nack_handler)
+ {
+ (*(this_uart->nack_handler))(this_uart);
+ }
+ }
+
+ /* PID parity error interrupt */
+ if (this_uart->hw_reg->IIM & EPID_PEI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->pid_pei_handler);
+
+ if (NULL_HANDLER != this_uart->pid_pei_handler)
+ {
+ (*(this_uart->pid_pei_handler))(this_uart);
+ }
+ }
+
+ /* LIN break detection interrupt */
+ if (this_uart->hw_reg->IIM & ELINBI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->break_handler);
+
+ if (NULL_HANDLER != this_uart->break_handler)
+ {
+ (*(this_uart->break_handler))(this_uart);
+ }
+ }
+
+ /* LIN Sync detection interrupt */
+ if (this_uart->hw_reg->IIM & ELINSI)
+ {
+ ASSERT(NULL_HANDLER != this_uart->sync_handler);
+
+ if (NULL_HANDLER != this_uart->sync_handler)
+ {
+ (*(this_uart->sync_handler))(this_uart);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ ASSERT(INVALID_INTERRUPT); /* Comment to avoid LDRA warning */
+ }
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * See mss_uart.h for details of how to use this function.
+ */
+static void
+default_tx_handler
+(
+ mss_uart_instance_t * this_uart
+)
+{
+ uint8_t status;
+
+ ASSERT(( (uint8_t*)0 ) != this_uart->tx_buffer);
+ ASSERT(0u < this_uart->tx_buff_size);
+
+ if ((((uint8_t*)0 ) != this_uart->tx_buffer) &&
+ (0u < this_uart->tx_buff_size))
+ {
+ /* Read the Line Status Register and update the sticky record. */
+ status = this_uart->hw_reg->LSR;
+ this_uart->status |= status;
+
+ /*
+ * This function should only be called as a result of a THRE interrupt.
+ * Verify that this is true before proceeding to transmit data.
+ */
+ if (status & MSS_UART_THRE)
+ {
+ uint32_t cnt;
+ uint32_t fill_size = TX_FIFO_SIZE;
+ uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;
+
+ /* Calculate the number of bytes to transmit. */
+ if (tx_remain < TX_FIFO_SIZE)
+ {
+ fill_size = tx_remain;
+ }
+
+ /* Fill the TX FIFO with the calculated the number of bytes. */
+ for (cnt = 0u; cnt < fill_size; ++cnt)
+ {
+ /* Send next character in the buffer. */
+ this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx];
+ ++this_uart->tx_idx;
+ }
+ }
+
+ /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */
+ if (this_uart->tx_idx == this_uart->tx_buff_size)
+ {
+ this_uart->tx_buff_size = TX_COMPLETE;
+
+ /* disables TX interrupt */
+ this_uart->hw_reg->IER &= ~ETBEI_MASK;
+ }
+ }
+}
+
+static void
+enable_irq
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ PLIC_IRQn_Type plic_num = 0;
+
+ if(0u == this_uart->local_irq_enabled)
+ {
+ if (((&g_mss_uart0_lo == this_uart)) || ((&g_mss_uart0_hi == this_uart)))
+ {
+ plic_num = MMUART0_PLIC_77;
+ }
+ else if (((&g_mss_uart1_lo == this_uart)) || ((&g_mss_uart1_hi == this_uart)))
+ {
+ plic_num = MMUART1_PLIC;
+ }
+ else if (((&g_mss_uart2_lo == this_uart)) || ((&g_mss_uart2_hi == this_uart)))
+ {
+ plic_num = MMUART2_PLIC;
+ }
+ else if (((&g_mss_uart3_lo == this_uart)) || ((&g_mss_uart3_hi == this_uart)))
+ {
+ plic_num = MMUART3_PLIC;
+ }
+ else if (((&g_mss_uart4_lo == this_uart)) || ((&g_mss_uart4_hi == this_uart)))
+ {
+ plic_num = MMUART4_PLIC;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* Enable UART instance interrupt in PLIC. */
+ PLIC_EnableIRQ(plic_num);
+ }
+}
+
+static void
+disable_irq
+(
+ const mss_uart_instance_t * this_uart
+)
+{
+ PLIC_IRQn_Type plic_num = 0;
+
+ if (((&g_mss_uart0_lo == this_uart)) || ((&g_mss_uart0_hi == this_uart)))
+ {
+ plic_num = MMUART0_PLIC_77;
+ }
+ else if (((&g_mss_uart1_lo == this_uart)) || ((&g_mss_uart1_hi == this_uart)))
+ {
+ plic_num = MMUART1_PLIC;
+ }
+ else if (((&g_mss_uart2_lo == this_uart)) || ((&g_mss_uart2_hi == this_uart)))
+ {
+ plic_num = MMUART2_PLIC;
+ }
+ else if (((&g_mss_uart3_lo == this_uart)) || ((&g_mss_uart3_hi == this_uart)))
+ {
+ plic_num = MMUART3_PLIC;
+ }
+ else if (((&g_mss_uart4_lo == this_uart)) || ((&g_mss_uart4_hi == this_uart)))
+ {
+ plic_num = MMUART4_PLIC;
+ }
+ else
+ {
+ ASSERT(0); /* Comment to avoid LDRA warning */
+ }
+
+ /* Disable UART instance interrupt in PLIC. */
+ PLIC_DisableIRQ(plic_num);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart.h b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart.h
new file mode 100644
index 00000000..49e18448
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart.h
@@ -0,0 +1,3335 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver
+ * public API.
+ *
+ */
+/*=========================================================================*//**
+ @mainpage PolarFire SoC MSS UART Bare Metal Driver.
+
+ ==============================================================================
+ Introduction
+ ==============================================================================
+ The PolarFire SoC Microprocessor subsystem (MSS) includes five multi-mode UART
+ (MMUART) peripherals for serial communication. This driver provides a set of
+ functions for controlling the MSS MMUARTs as part of a bare metal system
+ where no operating system is available. These drivers can be adapted for use
+ as part of an operating system, but the implementation of the adaptation layer
+ between this driver and the operating system's driver model is outside the
+ scope of this driver.
+ Note: MSS UART is synonymous with MSS MMUART in this document.
+
+ ==============================================================================
+ Hardware Flow Dependencies
+ ==============================================================================
+ The configuration of all features of the MSS MMUART peripherals is covered by
+ this driver with the exception of the PolarFire SoC IOMUX configuration.
+ PolarFire SoC allows multiple non-concurrent uses of some external pins
+ through IOMUX configuration. This feature allows optimization of external pin
+ usage by assigning external pins for use by either the microprocessor
+ subsystem or the FPGA fabric. The MSS MMUART serial signals are routed through
+ IOMUXs to the PolarFire SoC device external pins. The MSS MMUART serial
+ signals may also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
+ For more information on IOMUX, refer to the I/O Configuration section of the
+ PolarFire SoC Microprocessor Subsystem (MSS) User's Guide.
+
+ The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
+ must ensure that the MSS MMUART peripherals are enabled and configured in the
+ PolarFire SoC MSS configurator if you wish to use them. For more information
+ on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
+ Subsystem (MSS) User's Guide.
+
+ On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
+ masters and multiple slaves. Five RISC-V CPUs connect to the Master ports
+ M10 to M14 of the AXI switch. By default, all the APB peripherals are
+ accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB
+ bridges (referred as main APB bus). However, to support logical separation in
+ the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals
+ can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to
+ APB bridges (referred as the AMP APB bus).
+
+ Application must make sure that the desired MMUART instance is appropriately
+ configured on one of the APB bus described above by configuring the PolarFire
+ SoC system registers (SYSREG) as per the application need and that the
+ appropriate data structures are provided to this driver as parameter to the
+ functions provided by this driver.
+
+ The base address and register addresses are defined in this driver as
+ constants. The interrupt number assignment for the MSS MMUART peripherals are
+ defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
+ is included in the project settings of the SoftConsole tool chain and that it
+ is generated into your project.
+
+ ==============================================================================
+ Theory of Operation
+ ==============================================================================
+ The MSS MMUART driver functions are grouped into the following categories:
+ - Initialization and configuration functions
+ - Polled transmit and receive functions
+ - Interrupt driven transmit and receive functions
+
+ --------------------------------
+ Initialization and Configuration
+ --------------------------------
+ The MSS MMUART supports the following four broad modes of operation:
+ - UART or USART mode
+ - LIN mode
+ - IrDA mode
+ - Smartcard or ISO 7816 mode
+
+ The MSS MMUART driver provides the MSS_UART_init(), MSS_UART_lin_init(),
+ MSS_UART_irda_init() and MSS_UART_smartcard_init() functions to initialize the
+ MSS MMUARTs for operation in one of these modes. One of these initialization
+ functions must be called before any other MSS MMUART driver functions can be
+ called. The MSS MMUART operating modes are mutually exclusive; therefore only
+ one of the initialization functions must be called. The first parameter of the
+ initialization functions is a pointer to one of ten global data structures
+ used to store state information for each MSS MMUART. A pointer to these data
+ structures is also used as the first parameter to many of the driver functions
+ to identify which MSS MMUART will be used by the called function. The names of
+ these data structures are:
+ - g_mss_uart0_lo
+ - g_mss_uart1_lo
+ - g_mss_uart2_lo
+ - g_mss_uart3_lo
+ - g_mss_uart4_lo
+ - g_mss_uart0_hi
+ - g_mss_uart1_hi
+ - g_mss_uart2_hi
+ - g_mss_uart3_hi
+ - g_mss_uart4_hi
+
+ Therefore, any call to an MSS MMUART function should be of the form
+ MSS_UART_function_name( &g_mss_uart0_lo, ... ) or
+ MSS_UART_function_name( &g_mss_uart1_hi, ... ).
+
+ UART or USART Mode
+ For the UART or USART modes of operation, the MSS MMUART driver is initialized
+ through a call to the MSS_UART_init() function. This function takes the UART's
+ configuration as its parameters. The MSS_UART_init() function must be called
+ before any other MSS MMUART driver functions can be called.
+ The MSS_UART_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the LIN, IrDA and SmartCard modes.
+
+ LIN mode
+ For the LIN mode of operation, the MSS MMUART driver is initialized through a
+ call to the MSS_UART_lin_init() function. This function takes the LIN node's
+ configuration as its parameters. The MSS_UART_lin_init() function must be
+ called before any other MSS MMUART driver functions can be called. The
+ MSS_UART_lin_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the IrDA and SmartCard modes.
+ The driver also provides the following LIN mode configuration functions:
+ - MSS_UART_set_break()
+ - MSS_UART_clear_break()
+ - MSS_UART_set_pidpei_handler()
+ - MSS_UART_set_linbreak_handler()
+ - MSS_UART_set_linsync_handler()
+
+ Note: These LIN mode configuration functions can only be called after the
+ MSS_UART_lin_init() function is called.
+
+ IrDA mode
+ For the IrDA mode of operation, the driver is initialized through a call to
+ the MSS_UART_irda_init() function. This function takes the IrDA node's
+ configuration as its parameters. The MSS_UART_irda_init() function must be
+ called before any other MSS MMUART driver functions can be called. The
+ MSS_UART_irda_init() function configures the baud rate based on the input baud
+ rate parameter and if possible uses a fractional baud rate for greater
+ precision. This function disables the LIN and SmartCard modes.
+
+ Smartcard or ISO 7816 mode
+ For the Smartcard or ISO 7816 mode of operation, the driver is initialized
+ through a call to the MSS_UART_smartcard_init() function. This function takes
+ the smartcard configuration as its parameters. The MSS_UART_smartcard_init()
+ function must be called before any other MSS MMUART driver functions can be
+ called. The MSS_UART_smartcard_init() function configures the baud rate based
+ on the input baud rate parameter and if possible uses a fractional baud rate
+ for greater precision. This function disables the LIN and IrDA modes.
+ The driver also provides the following Smartcard mode configuration functions:
+ - MSS_UART_enable_halfduplex()
+ - MSS_UART_disable_halfduplex()
+ - MSS_UART_set_nack_handler()
+
+ Note: These Smartcard mode configuration functions can only be called after
+ the MSS_UART_smartcard_init() function is called.
+
+ Common Configuration Functions
+ The driver also provides the configuration functions that can be used with all
+ MSS MMUART operating modes. These common configuration functions are as
+ follows:
+ - MSS_UART_set_rx_endian()
+ - MSS_UART_set_tx_endian()
+ - MSS_UART_enable_afclear()
+ - MSS_UART_disable_afclear()
+ - MSS_UART_enable_rx_timeout()
+ - MSS_UART_disable_rx_timeout()
+ - MSS_UART_enable_tx_time_guard()
+ - MSS_UART_disable_tx_time_guard()
+ - MSS_UART_set_address()
+ - MSS_UART_set_ready_mode()
+ - MSS_UART_set_usart_mode()
+ - MSS_UART_set_filter_length()
+ - MSS_UART_enable_afm()
+ - MSS_UART_disable_afm()
+
+ Note: These configuration functions can only be called after one of the
+ MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init() or
+ MSS_UART_smartcard_init() functions is called.
+
+ --------------------------------------
+ Polled Transmit and Receive Operations
+ --------------------------------------
+ The driver can be used to transmit and receive data once initialized.
+ Data is transmitted using the MSS_UART_polled_tx() function. This function is
+ blocking, meaning that it will only return once the data passed to the
+ function has been sent to the MSS MMUART hardware transmitter. Data received
+ by the MSS MMUART hardware receiver can be read by the MSS_UART_get_rx()
+ function.
+ The MSS_UART_polled_tx_string() function is provided to transmit a NUL ('\0')
+ terminated string in polled mode. This function is blocking, meaning that it
+ will only return once the data passed to the function has been sent to the MSS
+ MMUART hardware transmitter.
+ The MSS_UART_fill_tx_fifo() function fills the MSS MMUART hardware transmit
+ FIFO with data from a buffer passed as a parameter and returns the number of
+ bytes transferred to the FIFO. If the transmit FIFO is not empty when the
+ MSS_UART_fill_tx_fifo() function is called it returns immediately without
+ transferring any data to the FIFO.
+
+ ---------------------------
+ Interrupt Driven Operations
+ ---------------------------
+ The driver can also transmit or receive data under interrupt control, freeing
+ your application to perform other tasks until an interrupt occurs indicating
+ that the driver's attention is required.
+
+ Local or PLIC interrupt:
+ PolarFire SoC architecture provides flexibility in terms of how the MMUART
+ interrupt is seen by the PolarFire SoC Core Complex. Each of the 5 MMUART
+ instance interrupt line is connected to the PolarFire SoC Core Complex PLIC.
+ The MMUART0 instance interrupt line is also available as local interrupt on
+ E51 processor. The MMUART1 instance interrupt onwards are available as local
+ interrupt on the U54_1 processor onwards. e.g. MMUART2 interrupt is available
+ as local interrupt on U54_2.
+
+ Interrupt Handlers
+ The MSS MMUART driver supports all types of interrupt triggered by the MSS
+ MMUART. The driver's internal top level interrupt handler identifies the
+ source of the MSS MMUART interrupt and calls the corresponding lower level
+ handler function that you previously registered with the driver through calls
+ to the MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(),
+ MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler()
+ functions. You are responsible for creating these lower level interrupt
+ handlers as part of your application program and registering them with the
+ driver.
+ Note: The PolarFire SoC HAL defines the interrupt handler functions for all
+ 5 MMUART instances(with weak linkage) and assigns them as the interrupt
+ service routines (ISR) for the MSS MMUART interrupt inputs to the
+ PolarFire SoC Core Complex PLIC or the Local interrupts on each of the
+ respective CPUs. The MSS MMUART driver provides the implementation
+ functions all these ISRs from which it calls its own internal top level,
+ interrupt handler function.
+
+ The MSS_UART_enable_irq() and MSS_UART_disable_irq() functions are used to
+ enable or disable the received line status, received data available/character
+ time-out, transmit holding register empty and modem status interrupts at the
+ MSS MMUART level. The MSS_UART_enable_irq() function also enables the MSS
+ MMUART instance interrupt at the PolarFire SoC Core Complex level.
+
+ Note that the MSS_UART_enable_irq() and MSS_UART_disable_irq() and all the
+ calls to set the handler functions assume that the MMUART interrupt is
+ connected to the PolarFire SoC Core Complex PLIC. If you want the MMUART
+ interrupt to appear as a local interrupt to the corresponding HART then you
+ must explicitly call the MSS_UART_enable_local_irq() function. This function
+ will disable the PLIC interrupt (if it was previously enable) and enable the
+ local interrupt on the HART on which this function is being executed.
+
+ Transmitting Data
+ Interrupt-driven transmit is initiated by a call to MSS_UART_irq_tx(),
+ specifying the block of data to transmit. Your application is then free to
+ perform other tasks and inquire later whether transmit has completed by
+ calling the MSS_UART_tx_complete() function. The MSS_UART_irq_tx() function
+ enables the UART's transmit holding register empty (THRE) interrupt and then,
+ when the interrupt goes active, the driver's default THRE interrupt handler
+ transfers the data block to the UART until the entire block is transmitted.
+ Note: You can use the MSS_UART_set_tx_handler() function to assign an
+ alternative handler to the THRE interrupt. In this case, you must not
+ use the MSS_UART_irq_tx() function to initiate the transmit, as this
+ will re-assign the driver's default THRE interrupt handler to the THRE
+ interrupt. Instead, your alternative THRE interrupt handler must include
+ a call to the MSS_UART_fill_tx_fifo() function to transfer the data to
+ the UART.
+
+ Receiving Data
+ Interrupt-driven receive is performed by first calling
+ MSS_UART_set_rx_handler() to register a receive handler function that will be
+ called by the driver whenever receive data is available. You must provide this
+ receive handler function which must include a call to the MSS_UART_get_rx()
+ function to actually read the received data.
+
+ -----------
+ UART Status
+ -----------
+ The function MSS_UART_get_rx_status() is used to read the receiver error
+ status. This function returns the overrun, parity, framing, break, and FIFO
+ error status of the receiver.
+ The function MSS_UART_get_tx_status() is used to read the transmitter status.
+ This function returns the transmit empty (TEMT) and transmit holding register
+ empty (THRE) status of the transmitter.
+ The function MSS_UART_get_modem_status() is used to read the modem status
+ flags. This function returns the current value of the modem status register.
+
+ --------
+ Loopback
+ --------
+ The MSS_UART_set_loopback() function can be used to locally loopback the Tx
+ and Rx lines of a UART. This is not to be confused with the loopback of UART0
+ to UART1, which can be achieved through the microprocessor subsystem's system
+ registers.
+
+ *//*=========================================================================*/
+#ifndef __MSS_UART_H_
+#define __MSS_UART_H_ 1
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************************************************************//**
+ Baud rates
+ ==========
+ The following definitions are used to specify standard baud rates as a
+ parameter to the MSS_UART_init() function.
+
+ | Constant | Description |
+ |----------------------|------------------|
+ | MSS_UART_110_BAUD | 110 baud rate |
+ | MSS_UART_300_BAUD | 300 baud rate |
+ | MSS_UART_600_BAUD | 600 baud rate |
+ | MSS_UART_1200_BAUD | 1200 baud rate |
+ | MSS_UART_2400_BAUD | 2400 baud rate |
+ | MSS_UART_4800_BAUD | 4800 baud rate |
+ | MSS_UART_9600_BAUD | 9600 baud rate |
+ | MSS_UART_19200_BAUD | 19200 baud rate |
+ | MSS_UART_38400_BAUD | 38400 baud rate |
+ | MSS_UART_57600_BAUD | 57600 baud rate |
+ | MSS_UART_115200_BAUD | 115200 baud rate |
+ | MSS_UART_230400_BAUD | 230400 baud rate |
+ | MSS_UART_460800_BAUD | 460800 baud rate |
+ | MSS_UART_921600_BAUD | 921600 baud rate |
+
+ */
+#define MSS_UART_110_BAUD 110U
+#define MSS_UART_300_BAUD 300U
+#define MSS_UART_600_BAUD 600U
+#define MSS_UART_1200_BAUD 1200U
+#define MSS_UART_2400_BAUD 2400U
+#define MSS_UART_4800_BAUD 4800U
+#define MSS_UART_9600_BAUD 9600U
+#define MSS_UART_19200_BAUD 19200U
+#define MSS_UART_38400_BAUD 38400U
+#define MSS_UART_57600_BAUD 57600U
+#define MSS_UART_115200_BAUD 115200U
+#define MSS_UART_230400_BAUD 230400U
+#define MSS_UART_460800_BAUD 460800U
+#define MSS_UART_921600_BAUD 921600U
+
+/***************************************************************************//**
+ Data Bits Length
+ ================
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |----------------------|----------------------------|
+ | MSS_UART_DATA_5_BITS | 5 bits of data transmitted |
+ | MSS_UART_DATA_6_BITS | 6 bits of data transmitted |
+ | MSS_UART_DATA_7_BITS | 7 bits of data transmitted |
+ | MSS_UART_DATA_8_BITS | 8 bits of data transmitted |
+
+ */
+#define MSS_UART_DATA_5_BITS ((uint8_t) 0x00)
+#define MSS_UART_DATA_6_BITS ((uint8_t) 0x01)
+#define MSS_UART_DATA_7_BITS ((uint8_t) 0x02)
+#define MSS_UART_DATA_8_BITS ((uint8_t) 0x03)
+
+/***************************************************************************//**
+ Parity
+ ======
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |-------------------------|--------------------------|
+ | MSS_UART_NO_PARITY | No parity |
+ | MSS_UART_ODD_PARITY | Odd Parity |
+ | MSS_UART_EVEN_PARITY | Even parity |
+ | MSS_UART_STICK_PARITY_0 | Stick parity bit to zero |
+ | MSS_UART_STICK_PARITY_1 | Stick parity bit to one |
+
+ */
+#define MSS_UART_NO_PARITY ((uint8_t) 0x00)
+#define MSS_UART_ODD_PARITY ((uint8_t) 0x08)
+#define MSS_UART_EVEN_PARITY ((uint8_t) 0x18)
+#define MSS_UART_STICK_PARITY_0 ((uint8_t) 0x38)
+#define MSS_UART_STICK_PARITY_1 ((uint8_t) 0x28)
+
+/***************************************************************************//**
+ Number of Stop Bits
+ ===================
+ The following defines are used to build the value of the MSS_UART_init()
+ function line_config parameter.
+
+ | Constant | Description |
+ |---------------------------|--------------------------|
+ | MSS_UART_ONE_STOP_BIT | One stop bit |
+ | MSS_UART_ONEHALF_STOP_BIT | One and a half stop bits |
+ | MSS_UART_TWO_STOP_BITS | Two stop bits |
+
+ */
+#define MSS_UART_ONE_STOP_BIT ((uint8_t) 0x00)
+#define MSS_UART_ONEHALF_STOP_BIT ((uint8_t) 0x04)
+#define MSS_UART_TWO_STOP_BITS ((uint8_t) 0x04)
+
+/***************************************************************************//**
+ Receiver Error Status
+ =====================
+ The following defines are used to determine the UART receiver error type.
+ These bit mask constants are used with the return value of the
+ MSS_UART_get_rx_status() function to find out if any errors occurred while
+ receiving data.
+
+
+ | Constant | Description |
+ |------------------------|--------------------------------------------|
+ | MSS_UART_NO_ERROR | No error bit mask (0x00) |
+ | MSS_UART_OVERUN_ERROR | Overrun error bit mask (0x02) |
+ | MSS_UART_PARITY_ERROR | Parity error bit mask (0x04) |
+ | MSS_UART_FRAMING_ERROR | Framing error bit mask (0x08) |
+ | MSS_UART_BREAK_ERROR | Break error bit mask (0x10) |
+ | MSS_UART_FIFO_ERROR | FIFO error bit mask (0x80) |
+ | MSS_UART_INVALID_PARAM | Invalid function parameter bit mask (0xFF) |
+
+ */
+#define MSS_UART_INVALID_PARAM ((uint8_t)0xFF)
+#define MSS_UART_NO_ERROR ((uint8_t)0x00 )
+#define MSS_UART_OVERUN_ERROR ((uint8_t)0x02)
+#define MSS_UART_PARITY_ERROR ((uint8_t)0x04)
+#define MSS_UART_FRAMING_ERROR ((uint8_t)0x08)
+#define MSS_UART_BREAK_ERROR ((uint8_t)0x10)
+#define MSS_UART_FIFO_ERROR ((uint8_t)0x80)
+
+/***************************************************************************//**
+ Transmitter Status
+ ==================
+ The following definitions are used to determine the UART transmitter status.
+ These bit mask constants are used with the return value of the
+ MSS_UART_get_tx_status() function to find out the status of the transmitter.
+
+ | Constant | Description |
+ |------------------|----------------------------------------------------|
+ | MSS_UART_TX_BUSY | Transmitter busy (0x00) |
+ | MSS_UART_THRE | Transmitter holding register empty bit mask (0x20) |
+ | MSS_UART_TEMT | Transmitter empty bit mask (0x40) |
+
+ */
+#define MSS_UART_TX_BUSY ((uint8_t) 0x00)
+#define MSS_UART_THRE ((uint8_t) 0x20)
+#define MSS_UART_TEMT ((uint8_t) 0x40)
+
+/***************************************************************************//**
+ Modem Status
+ ============
+ The following defines are used to determine the modem status. These bit
+ mask constants are used with the return value of the
+ MSS_UART_get_modem_status() function to find out the modem status of
+ the UART.
+
+ | Constant | Description |
+ |---------------|-------------------------------------------------|
+ | MSS_UART_DCTS | Delta clear to send bit mask (0x01) |
+ | MSS_UART_DDSR | Delta data set ready bit mask (0x02) |
+ | MSS_UART_TERI | Trailing edge of ring indicator bit mask (0x04) |
+ | MSS_UART_DDCD | Delta data carrier detect bit mask (0x08) |
+ | MSS_UART_CTS | Clear to send bit mask (0x10) |
+ | MSS_UART_DSR | Data set ready bit mask (0x20) |
+ | MSS_UART_RI | Ring indicator bit mask (0x40) |
+ | MSS_UART_DCD | Data carrier detect bit mask (0x80) |
+
+ */
+#define MSS_UART_DCTS ((uint8_t) 0x01)
+#define MSS_UART_DDSR ((uint8_t) 0x02)
+#define MSS_UART_TERI ((uint8_t) 0x04)
+#define MSS_UART_DDCD ((uint8_t) 0x08)
+#define MSS_UART_CTS ((uint8_t) 0x10)
+#define MSS_UART_DSR ((uint8_t) 0x20)
+#define MSS_UART_RI ((uint8_t) 0x40)
+#define MSS_UART_DCD ((uint8_t) 0x80)
+
+/***************************************************************************//**
+ This typedef specifies the irq_mask parameter for the MSS_UART_enable_irq()
+ and MSS_UART_disable_irq() functions. The driver defines a set of bit masks
+ that are used to build the value of the irq_mask parameter. A bitwise OR of
+ these bit masks is used to enable or disable multiple MSS MMUART interrupts.
+ */
+typedef uint16_t mss_uart_irq_t;
+
+/***************************************************************************//**
+ MSS MMUART Interrupts
+ =====================
+ The following defines specify the interrupt masks to enable and disable MSS
+ MMUART interrupts. They are used to build the value of the irq_mask parameter
+ for the MSS_UART_enable_irq() and MSS_UART_disable_irq() functions. A bitwise
+ OR of these constants is used to enable or disable multiple interrupts.
+
+
+ | Constant | Description |
+ |--------------------|---------------------------------------------------------------|
+ | MSS_UART_RBF_IRQ | Receive Data Available Interrupt bit mask (0x001) |
+ | MSS_UART_TBE_IRQ | Transmitter Holding Register Empty interrupt bit mask (0x002) |
+ | MSS_UART_LS_IRQ | Receiver Line Status interrupt bit mask (0x004) |
+ | MSS_UART_MS_IRQ | Modem Status interrupt bit mask (0x008) |
+ | MSS_UART_RTO_IRQ | Receiver time-out interrupt bit mask (0x010) |
+ | MSS_UART_NACK_IRQ | NACK / ERR signal interrupt bit mask (0x020) |
+ | MSS_UART_PIDPE_IRQ | PID parity error interrupt bit mask (0x040) |
+ | MSS_UART_LINB_IRQ | LIN break detection interrupt bit mask (0x080) |
+ | MSS_UART_LINS_IRQ | LIN Sync detection interrupt bit mask (0x100) |
+
+ */
+#define MSS_UART_RBF_IRQ 0x001
+#define MSS_UART_TBE_IRQ 0x002
+#define MSS_UART_LS_IRQ 0x004
+#define MSS_UART_MS_IRQ 0x008
+#define MSS_UART_RTO_IRQ 0x010
+#define MSS_UART_NACK_IRQ 0x020
+#define MSS_UART_PIDPE_IRQ 0x040
+#define MSS_UART_LINB_IRQ 0x080
+#define MSS_UART_LINS_IRQ 0x100
+#define MSS_UART_INVALID_IRQ UINT16_MAX
+
+/***************************************************************************//**
+ This enumeration specifies the receiver FIFO trigger level. This is the number
+ of bytes that must be received before the UART generates a receive data
+ available interrupt. It provides the allowed values for the
+ MSS_UART_set_rx_handler() function trigger_level parameter.
+ */
+typedef enum {
+ MSS_UART_FIFO_SINGLE_BYTE = 0x00,
+ MSS_UART_FIFO_FOUR_BYTES = 0x40,
+ MSS_UART_FIFO_EIGHT_BYTES = 0x80,
+ MSS_UART_FIFO_FOURTEEN_BYTES = 0xC0,
+ MSS_UART_FIFO_INVALID_TRIG_LEVEL
+
+} mss_uart_rx_trig_level_t;
+
+/***************************************************************************//**
+ This enumeration specifies the loopback configuration of the UART. It provides
+ the allowed values for the MSS_UART_set_loopback() function's loopback
+ parameter. Use MSS_UART_LOCAL_LOOPBACK_ON to set up the UART to locally
+ loopback its Tx and Rx lines. Use MSS_UART_REMOTE_LOOPBACK_ON to set up the
+ UART in remote loopback mode.
+ */
+typedef enum {
+ MSS_UART_LOCAL_LOOPBACK_OFF,
+ MSS_UART_LOCAL_LOOPBACK_ON,
+ MSS_UART_REMOTE_LOOPBACK_OFF,
+ MSS_UART_REMOTE_LOOPBACK_ON,
+ MSS_UART_AUTO_ECHO_OFF,
+ MSS_UART_AUTO_ECHO_ON,
+ MSS_UART_INVALID_LOOPBACK
+
+} mss_uart_loopback_t;
+
+/***************************************************************************//**
+ IrDA input / output polarity.
+ This enumeration specifies the RZI modem polarity for input and output signals.
+ This is passed as parameters in MSS_UART_irda_init() function.
+ */
+typedef enum {
+ MSS_UART_ACTIVE_LOW = 0u,
+ MSS_UART_ACTIVE_HIGH = 1u,
+ MSS_UART_INVALID_POLARITY
+
+} mss_uart_rzi_polarity_t;
+
+/***************************************************************************//**
+ IrDA input / output pulse width.
+ This enumeration specifies the RZI modem pulse width for input and output
+ signals. This is passed as parameters in MSS_UART_irda_init() function.
+ */
+typedef enum {
+ MSS_UART_3_BY_16 = 0u,
+ MSS_UART_1_BY_4 = 1u,
+ MSS_UART_INVALID_PW
+
+} mss_uart_rzi_pulsewidth_t;
+
+/***************************************************************************//**
+ Tx / Rx endianess.
+ This enumeration specifies the MSB first or LSB first for MSS UART transmitter
+ and receiver. The parameter of this type shall be passed in
+ MSS_UART_set_rx_endian()and MSS_UART_set_tx_endian() functions.
+ */
+typedef enum {
+ MSS_UART_LITTLEEND,
+ MSS_UART_BIGEND,
+ MSS_UART_INVALID_ENDIAN
+
+} mss_uart_endian_t;
+
+/***************************************************************************//**
+ Glitch filter length.
+ This enumeration specifies the glitch filter length. The function
+ MSS_UART_set_filter_length() accepts the parameter of this type.
+ */
+typedef enum {
+ MSS_UART_LEN0 = 0,
+ MSS_UART_LEN1 = 1,
+ MSS_UART_LEN2 = 2,
+ MSS_UART_LEN3 = 3,
+ MSS_UART_LEN4 = 4,
+ MSS_UART_LEN5 = 5,
+ MSS_UART_LEN6 = 6,
+ MSS_UART_LEN7 = 7,
+ MSS_UART_INVALID_FILTER_LENGTH = 8
+
+} mss_uart_filter_length_t;
+
+/***************************************************************************//**
+ TXRDY and RXRDY mode.
+ This enumeration specifies the TXRDY and RXRDY signal modes. The function
+ MSS_UART_set_ready_mode() accepts the parameter of this type.
+ */
+typedef enum {
+ MSS_UART_READY_MODE0,
+ MSS_UART_READY_MODE1,
+ MSS_UART_INVALID_READY_MODE
+
+} mss_uart_ready_mode_t;
+
+/***************************************************************************//**
+ USART mode of operation.
+ This enumeration specifies the mode of operation of MSS UART when operating
+ as USART. The function MSS_UART_set_usart_mode() accepts the parameter of this
+ type.
+ */
+typedef enum {
+ MSS_UART_ASYNC_MODE = 0,
+ MSS_UART_SYNC_SLAVE_POS_EDGE_CLK = 1,
+ MSS_UART_SYNC_SLAVE_NEG_EDGE_CLK = 2,
+ MSS_UART_SYNC_MASTER_POS_EDGE_CLK = 3,
+ MSS_UART_SYNC_MASTER_NEG_EDGE_CLK = 4,
+ MSS_UART_INVALID_SYNC_MODE = 5
+
+} mss_uart_usart_mode_t;
+
+
+typedef enum {
+ MSS_UART0_LO = 0,
+ MSS_UART1_LO = 1,
+ MSS_UART2_LO = 2,
+ MSS_UART3_LO = 3,
+ MSS_UART4_LO = 4,
+ MSS_UART0_HI = 5,
+ MSS_UART1_HI = 6,
+ MSS_UART2_HI = 7,
+ MSS_UART3_HI = 8,
+ MSS_UAR4_HI = 9,
+
+} mss_uart_num_t;
+
+/***************************************************************************//**
+ MSS UART instance type.
+ This is type definition for MSS UART instance. You need to create and
+ maintain a record of this type. This holds all data regarding the MSS UART
+ instance
+ */
+typedef struct mss_uart_instance mss_uart_instance_t;
+
+/***************************************************************************//**
+ Interrupt handler prototype.
+ This typedef specifies the function prototype for MSS UART interrupt handlers.
+ All interrupt handlers registered with the MSS UART driver must be of this type.
+ The interrupt handlers are registered with the driver through the
+ MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(),
+ MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler()
+ functions.
+ The this_uart parameter is a pointer to either g_mss_uart0 or g_mss_uart1 to
+ identify the MSS UART to associate with the handler function.
+ */
+typedef void (*mss_uart_irq_handler_t)( mss_uart_instance_t * this_uart );
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------- UART -----------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+typedef struct
+{
+ union
+ {
+ volatile const uint8_t RBR;
+ volatile uint8_t THR;
+ volatile uint8_t DLR;
+ uint32_t RESERVED0;
+ };
+
+ union
+ {
+ volatile uint8_t DMR;
+ volatile uint8_t IER;
+ uint32_t RESERVED1;
+ };
+
+ union
+ {
+ volatile uint8_t IIR;
+ volatile uint8_t FCR;
+ uint32_t RESERVED2;
+ };
+
+ volatile uint8_t LCR;
+ uint8_t RESERVED3[3];
+
+ volatile uint8_t MCR;
+ uint8_t RESERVED4[3];
+
+ volatile const uint8_t LSR;
+ uint8_t RESERVED5[3];
+
+ volatile const uint8_t MSR;
+ uint8_t RESERVED6[3];
+
+ volatile uint8_t SR;
+ uint8_t RESERVED7[7];
+
+ volatile uint8_t IEM;
+ uint8_t RESERVED8[3];
+
+ volatile uint8_t IIM;
+ uint8_t RESERVED9[7];
+
+ volatile uint8_t MM0;
+ uint8_t RESERVED10[3];
+
+ volatile uint8_t MM1;
+ uint8_t RESERVED11[3];
+
+ volatile uint8_t MM2;
+ uint8_t RESERVED12[3];
+
+ volatile uint8_t DFR;
+ uint8_t RESERVED13[7];
+
+ volatile uint8_t GFR;
+ uint8_t RESERVED14[3];
+
+ volatile uint8_t TTG;
+ uint8_t RESERVED15[3];
+
+ volatile uint8_t RTO;
+ uint8_t RESERVED16[3];
+
+ volatile uint8_t ADR;
+ uint8_t RESERVED17[3];
+
+} MSS_UART_TypeDef;
+
+
+/***************************************************************************//**
+ mss_uart_instance.
+ There is one instance of this structure for each instance of the
+ microprocessor subsystem's UARTs. Instances of this structure are used to
+ identify a specific UART. A pointer to an initialized instance of the
+ mss_uart_instance_t structure is passed as the first parameter to
+ MSS UART driver functions to identify which UART should perform the
+ requested operation.
+ */
+struct mss_uart_instance{
+ /* CMSIS related defines identifying the UART hardware. */
+ MSS_UART_TypeDef * hw_reg; /*!< Pointer to UART registers. */
+ uint32_t baudrate; /*!< Operating baud rate. */
+ uint8_t lineconfig; /*!< Line configuration parameters. */
+ uint8_t status; /*!< Sticky line status. */
+
+ /* transmit related info (used with interrupt driven transmit): */
+ const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */
+ uint32_t tx_buff_size; /*!< Transmit buffer size. */
+ uint32_t tx_idx; /*!< Index within transmit buffer of next byte to transmit.*/
+
+ /* line status interrupt handler:*/
+ mss_uart_irq_handler_t linests_handler; /*!< Pointer to user registered line status handler. */
+ /* receive interrupt handler:*/
+ mss_uart_irq_handler_t rx_handler; /*!< Pointer to user registered receiver handler. */
+ /* transmit interrupt handler:*/
+ mss_uart_irq_handler_t tx_handler; /*!< Pointer to user registered transmit handler. */
+ /* modem status interrupt handler:*/
+ mss_uart_irq_handler_t modemsts_handler; /*!< Pointer to user registered modem status handler. */
+ /* receiver timeout interrupt handler */
+ mss_uart_irq_handler_t rto_handler; /*!< Pointer to user registered receiver timeout handler. */
+ /* NACK interrupt handler */
+ mss_uart_irq_handler_t nack_handler; /*!< Pointer to user registered NACK handler. */
+ /* PID parity perror interrupt handler */
+ mss_uart_irq_handler_t pid_pei_handler; /*!< Pointer to user registered PID parity error handler. */
+ /* LIN break interrupt handler */
+ mss_uart_irq_handler_t break_handler; /*!< Pointer to user registered LIN break handler. */
+ /* LIN sync detection interrupt handler */
+ mss_uart_irq_handler_t sync_handler; /*!< Pointer to user registered LIN sync detection handler. */
+ uint8_t local_irq_enabled; /*!< check if local interrupt were enabled on this instance*/
+ void* user_data; /*!< Pointer to user provided pointer for user specific use. */
+
+};
+
+/***************************************************************************//**
+ This instance of mss_uart_instance_t holds all data related to the operations
+ performed by the MMUART. The function MSS_UART_init() initializes this structure.
+ A pointer to g_mss_uart0_lo is passed as the first parameter to MSS UART driver
+ functions to indicate that MMUART0 should perform the requested operation.
+ */
+
+extern mss_uart_instance_t g_mss_uart0_lo;
+extern mss_uart_instance_t g_mss_uart1_lo;
+extern mss_uart_instance_t g_mss_uart2_lo;
+extern mss_uart_instance_t g_mss_uart3_lo;
+extern mss_uart_instance_t g_mss_uart4_lo;
+
+extern mss_uart_instance_t g_mss_uart0_hi;
+extern mss_uart_instance_t g_mss_uart1_hi;
+extern mss_uart_instance_t g_mss_uart2_hi;
+extern mss_uart_instance_t g_mss_uart3_hi;
+extern mss_uart_instance_t g_mss_uart4_hi;
+
+
+/***************************************************************************//**
+ The MSS_UART_init() function initializes and configures one of the PolarFire SoC
+ MSS UARTs with the configuration passed as a parameter. The configuration
+ parameters are the baud_rate which is used to generate the baud value and the
+ line_config which is used to specify the line configuration (bit length,
+ stop bits and parity).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit length,
+ number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The MSS_UART_lin_init() function is used to initialize the MSS UART for
+ LIN mode of operation. The configuration parameters are the baud_rate which is
+ used to generate the baud value and the line_config which is used to specify
+ the line configuration (bit length, stop bits and parity).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit length,
+ number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_lin_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The MSS_UART_irda_init() function is used to initialize the MSS UART instance
+ referenced by the parameter this_uart for IrDA mode of operation. This
+ function must be called before calling any other IrDA functionality specific
+ functions.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit
+ length, number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_irda_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT,
+ MSS_UART_ACTIVE_LOW,
+ MSS_UART_ACTIVE_LOW,
+ MSS_UART_3_BY_16);
+ @endcode
+ */
+void
+MSS_UART_irda_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config,
+ mss_uart_rzi_polarity_t rxpol,
+ mss_uart_rzi_polarity_t txpol,
+ mss_uart_rzi_pulsewidth_t pw
+);
+
+/***************************************************************************//**
+ The MSS_UART_smartcard_init() function is used to initialize the MSS UART
+ for ISO 7816 (smartcard) mode of operation. The configuration parameters are
+ the baud_rate which is used to generate the baud value and the line_config
+ which is used to specify the line configuration (bit length, stop bits and
+ parity). This function disables all other modes of the MSS UART instance
+ pointed by the parameter this_uart.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param baud_rate
+ The baud_rate parameter specifies the baud rate. It can be specified for
+ common baud rates using the following defines:
+ - MSS_UART_110_BAUD
+ - MSS_UART_300_BAUD
+ - MSS_UART_600_BAUD
+ - MSS_UART_1200_BAUD
+ - MSS_UART_2400_BAUD
+ - MSS_UART_4800_BAUD
+ - MSS_UART_9600_BAUD
+ - MSS_UART_19200_BAUD
+ - MSS_UART_38400_BAUD
+ - MSS_UART_57600_BAUD
+ - MSS_UART_115200_BAUD
+ - MSS_UART_230400_BAUD
+ - MSS_UART_460800_BAUD
+ - MSS_UART_921600_BAUD
+
+ Alternatively, any nonstandard baud rate can be specified by simply passing
+ the actual required baud rate as the value for this parameter.
+
+ @param line_config
+ The line_config parameter is the line configuration specifying the bit
+ length, number of stop bits and parity settings.
+
+ This is a bitwise OR of one value from each of the following groups of
+ allowed values:
+
+ One of the following to specify the transmit/receive data bit length:
+ - MSS_UART_DATA_5_BITS
+ - MSS_UART_DATA_6_BITS,
+ - MSS_UART_DATA_7_BITS
+ - MSS_UART_DATA_8_BITS
+
+ One of the following to specify the parity setting:
+ - MSS_UART_NO_PARITY
+ - MSS_UART_EVEN_PARITY
+ - MSS_UART_ODD_PARITY
+ - MSS_UART_STICK_PARITY_0
+ - MSS_UART_STICK_PARITY_1
+
+ One of the following to specify the number of stop bits:
+ - MSS_UART_ONE_STOP_BIT
+ - MSS_UART_ONEHALF_STOP_BIT
+ - MSS_UART_TWO_STOP_BITS
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ MSS_UART_smartcard_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_smartcard_init
+(
+ mss_uart_instance_t* this_uart,
+ uint32_t baud_rate,
+ uint8_t line_config
+);
+
+/***************************************************************************//**
+ The function MSS_UART_polled_tx() is used to transmit data. It transfers the
+ contents of the transmitter data buffer, passed as a function parameter, into
+ the UART's hardware transmitter FIFO. It returns when the full content of the
+ transmit data buffer has been transferred to the UART's transmit FIFO. It is
+ safe to release or reuse the memory used as the transmitter data buffer once
+ this function returns.
+
+ Note: This function reads the UART's line status register (LSR) to poll
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. It
+ transfers data to the transmitter FIFO in blocks of 16 bytes or less and
+ allows the FIFO to empty before transferring the next block of data.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param pbuff
+ The pbuff parameter is a pointer to a buffer containing the data to
+ be transmitted.
+
+ @param tx_size
+ The tx_size parameter specifies the size, in bytes, of the data to
+ be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello World";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ SS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx(&g_mss_uart0_lo, message, sizeof(message));
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_polled_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+
+/***************************************************************************//**
+ The function MSS_UART_polled_tx_string() is used to transmit a NUL ('\0')
+ terminated string. It transfers the text string, from the buffer starting at
+ the address pointed to by p_sz_string into the UART's hardware transmitter
+ FIFO. It returns when the complete string has been transferred to the UART's
+ transmit FIFO. It is safe to release or reuse the memory used as the string
+ buffer once this function returns.
+
+ Note: This function reads the UART's line status register (LSR) to poll
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. It
+ transfers data to the transmitter FIFO in blocks of 16 bytes or less and
+ allows the FIFO to empty before transferring the next block of data.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param p_sz_string
+ The p_sz_string parameter is a pointer to a buffer containing the NUL ('\0')
+ terminated string to be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello World";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx_string(&g_mss_uart0_lo, message);
+
+ return(0);
+ }
+ @endcode
+
+ */
+void
+MSS_UART_polled_tx_string
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * p_sz_string
+);
+
+/***************************************************************************//**
+ The function MSS_UART_irq_tx() is used to initiate an interrupt-driven
+ transmit. It returns immediately after making a note of the transmit buffer
+ location and enabling transmit interrupts both at the UART and the PolarFire
+ SoC Core Complex PLIC level. This function takes a pointer via the pbuff
+ parameter to a memory buffer containing the data to transmit. The memory
+ buffer specified through this pointer must remain allocated and contain the
+ data to transmit until the transmit completion has been detected through calls
+ to function MSS_UART_tx_complete(). The actual transmission over the serial
+ connection is still in progress until calls to the MSS_UART_tx_complete()
+ function indicate transmit completion.
+
+ Note: The MSS_UART_irq_tx() function enables both the transmit holding
+ register empty (THRE) interrupt in the UART and the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC as part of its implementation.
+
+ Note: The MSS_UART_irq_tx() function assigns an internal default transmit
+ interrupt handler function to the UART's THRE interrupt. This interrupt
+ handler overrides any custom interrupt handler that you may have previously
+ registered using the MSS_UART_set_tx_handler() function.
+
+ Note: The MSS_UART_irq_tx() function's default transmit interrupt
+ handler disables the UART's THRE interrupt when all of the data has
+ been transferred to the UART's transmit FIFO.
+
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param pbuff
+ The pbuff parameter is a pointer to a buffer containing the data
+ to be transmitted.
+
+ @param tx_size
+ The tx_size parameter specifies the size, in bytes, of the data
+ to be transmitted.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_irq_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff));
+
+ while(0 == MSS_UART_tx_complete(&g_mss_uart0_lo))
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_irq_tx
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * pbuff,
+ uint32_t tx_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_tx_complete() function is used to find out if the
+ interrupt-driven transmit previously initiated through a call to
+ MSS_UART_irq_tx() is complete. This is typically used to find out when it is
+ safe to reuse or release the memory buffer holding transmit data.
+
+ Note: The transfer of all of the data from the memory buffer to the UART's
+ transmit FIFO and the actual transmission over the serial connection are both
+ complete when a call to the MSS_UART_tx_complete() function indicates transmit
+ completion.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function return a non-zero value if transmit has completed, otherwise
+ it returns zero.
+
+ Example:
+ See the MSS_UART_irq_tx() function for an example that uses the
+ MSS_UART_tx_complete() function.
+
+ */
+int8_t
+MSS_UART_tx_complete
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_rx() function reads the content of the UART receiver's FIFO
+ and stores it in the receive buffer that is passed via the rx_buff function
+ parameter. It copies either the full contents of the FIFO into the receive
+ buffer, or just enough data from the FIFO to fill the receive buffer,
+ dependent upon the size of the receive buffer passed by the buff_size
+ parameter. The MSS_UART_get_rx() function returns the number of bytes copied
+ into the receive buffer .This function is non-blocking and will return 0
+ immediately if no data has been received.
+
+ Note: The MSS_UART_get_rx() function reads and accumulates the receiver
+ status of the MSS UART instance before reading each byte from the receiver's
+ data register/FIFO. This allows the driver to maintain a sticky record of any
+ receiver errors that occur as the UART receives each data byte; receiver
+ errors would otherwise be lost after each read from the receiver's data
+ register. A call to the MSS_UART_get_rx_status() function returns any receiver
+ errors accumulated during the execution of the MSS_UART_get_rx() function.
+
+ Note: If you need to read the error status for each byte received, set
+ the buff_size to 1 and read the receive line error status for each byte
+ using the MSS_UART_get_rx_status() function.
+
+ The MSS_UART_get_rx() function can be used in polled mode, where it is called
+ at regular intervals to find out if any data has been received, or in
+ interrupt driven-mode, where it is called as part of a receive handler that is
+ called by the driver as a result of data being received.
+
+ Note: In interrupt driven mode you should call the MSS_UART_get_rx()
+ function as part of the receive handler function that you register with
+ the MSS UART driver through a call to MSS_UART_set_rx_handler().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param rx_buff
+ The rx_buff parameter is a pointer to a buffer where the received
+ data is copied.
+
+ @param buff_size
+ The buff_size parameter specifies the size of the receive buffer in bytes.
+
+ @return
+ This function returns the number of bytes that were copied into the
+ rx_buff buffer. It returns 0 if no data has been received.
+
+ Polled mode example:
+ @code
+ int main( void )
+ {
+ uint8_t rx_buff[RX_BUFF_SIZE];
+ uint32_t rx_idx = 0;
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ while(1)
+ {
+ rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_buff, sizeof(rx_buff));
+ if(rx_size > 0)
+ {
+ process_rx_data(rx_buff, rx_size);
+ }
+ task_a();
+ task_b();
+ }
+ return 0;
+ }
+ @endcode
+
+ Interrupt driven example:
+ @code
+ int main( void )
+ {
+ MSS_UART_init(&g_mss_uart1,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart1,
+ uart1_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ while(1)
+ {
+ task_a();
+ task_b();
+ }
+ return 0;
+ }
+
+ void uart1_rx_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t rx_buff[RX_BUFF_SIZE];
+ uint32_t rx_idx = 0;
+ rx_size = MSS_UART_get_rx(this_uart, rx_buff, sizeof(rx_buff));
+ process_rx_data(rx_buff, rx_size);
+ }
+ @endcode
+ */
+size_t
+MSS_UART_get_rx
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t * rx_buff,
+ size_t buff_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_handler() function is used to register a receive handler
+ function that is called by the driver when a UART receive data available (RDA)
+ interrupt occurs. You must create and register the receive handler function
+ to suit your application and it must include a call to the MSS_UART_get_rx()
+ function to actually read the received data.
+
+ Note: The MSS_UART_set_rx_handler() function enables both the RDA
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part
+ of its implementation.
+
+ Note: You can disable the RDA interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a receive interrupt handler function
+ provided by your application that will be called as a result of a UART RDA
+ interrupt. This handler function must be of type mss_uart_irq_handler_t.
+
+ @param trigger_level
+ The trigger_level parameter is the receive FIFO trigger level. This
+ specifies the number of bytes that must be received before the UART
+ triggers an RDA interrupt.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ #define RX_BUFF_SIZE 64
+
+ uint8_t g_rx_buff[RX_BUFF_SIZE];
+
+ void uart0_rx_handler(mss_uart_instance_t * this_uart)
+ {
+ MSS_UART_get_rx(this_uart, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff));
+ }
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart0_lo,
+ uart0_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_rx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler,
+ mss_uart_rx_trig_level_t trigger_level
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_loopback() function is used to locally loop-back the Tx and
+ Rx lines of a UART. This is not to be confused with the loop-back of UART0
+ to UART1, which can be achieved through the microprocessor subsystem's
+ system registers.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param loopback
+ The loopback parameter indicates whether or not the UART's transmit and
+ receive lines should be looped back. Allowed values are as follows:
+ - MSS_UART_LOCAL_LOOPBACK_ON
+ - MSS_UART_LOCAL_LOOPBACK_OFF
+ - MSS_UART_REMOTE_LOOPBACK_ON
+ - MSS_UART_REMOTE_LOOPBACK_OFF
+ - MSS_UART_AUTO_ECHO_ON
+ - MSS_UART_AUTO_ECHO_OFF
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_loopback(&g_mss_uart0_lo, MSS_UART_LOCAL_LOOPBACK_OFF);
+ @endcode
+ */
+void
+MSS_UART_set_loopback
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_loopback_t loopback
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_irq() function enables the MSS UART interrupts specified
+ by the irq_mask parameter. The irq_mask parameter identifies the MSS UART
+ interrupts by bit position, as defined in the interrupt enable register (IER)
+ of MSS UART. The MSS UART interrupts and their identifying irq_mask bit
+ positions are as follows:
+ When an irq_mask bit position is set to 1, this function enables the
+ corresponding MSS UART interrupt in the IER register. When an irq_mask bit
+ position is set to 0, the state of the corresponding interrupt remains
+ unchanged in the IER register.
+
+ Note: The MSS_UART_enable_irq() function also enables the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param irq_mask
+ The irq_mask parameter is used to select which of the MSS UART's interrupts
+ you want to enable. The allowed value for the irq_mask parameter is one of
+ the following constants or a bitwise OR of more than one:
+ - MSS_UART_RBF_IRQ (bit mask = 0x001)
+ - MSS_UART_TBE_IRQ (bit mask = 0x002)
+ - MSS_UART_LS_IRQ (bit mask = 0x004)
+ - MSS_UART_MS_IRQ (bit mask = 0x008)
+ - MSS_UART_RTO_IRQ (bit mask = 0x010)
+ - MSS_UART_NACK_IRQ (bit mask = 0x020)
+ - MSS_UART_PIDPE_IRQ (bit mask = 0x040)
+ - MSS_UART_LINB_IRQ (bit mask = 0x080)
+ - MSS_UART_LINS_IRQ (bit mask = 0x100)
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_irq(&g_mss_uart0_lo,(MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ));
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_enable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_irq() function disables the MSS UART interrupts specified
+ by the irq_mask parameter. The irq_mask parameter identifies the MSS UART
+ interrupts by bit position, as defined in the interrupt enable register (IER)
+ of MSS UART. The MSS UART interrupts and their identifying bit positions are
+ as follows:
+ When an irq_mask bit position is set to 1, this function disables the
+ corresponding MSS UART interrupt in the IER register. When an irq_mask bit
+ position is set to 0, the state of the corresponding interrupt remains
+ unchanged in the IER register.
+
+ Note: If you disable all four of the UART's interrupts, the
+ MSS_UART_disable_irq() function also disables the MSS UART instance
+ interrupt in the PolarFire SoC Core Complex PLIC.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param irq_mask
+ The irq_mask parameter is used to select which of the MSS UART's interrupts
+ you want to disable. The allowed value for the irq_mask parameter is one of
+ the following constants or a bitwise OR of more than one:
+ - MSS_UART_RBF_IRQ (bit mask = 0x001)
+ - MSS_UART_TBE_IRQ (bit mask = 0x002)
+ - MSS_UART_LS_IRQ (bit mask = 0x004)
+ - MSS_UART_MS_IRQ (bit mask = 0x008)
+ - MSS_UART_RTO_IRQ (bit mask = 0x010)
+ - MSS_UART_NACK_IRQ (bit mask = 0x020)
+ - MSS_UART_PIDPE_IRQ (bit mask = 0x040)
+ - MSS_UART_LINB_IRQ (bit mask = 0x080)
+ - MSS_UART_LINS_IRQ (bit mask = 0x100)
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_irq(&g_mss_uart0_lo,(MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ));
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_disable_irq
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_t irq_mask
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_pidpei_handler() function is used assign a custom interrupt
+ handler for the PIDPEI (PID parity error interrupt) when the MSS UART is
+ operating in LIN mode.
+
+ Note: The MSS_UART_set_pidpei_handler() function enables both the PIDPEI
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the PIDPEI interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_pidpei_handler(&g_mss_uart0_lo, my_pidpei_handler);
+
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_pidpei_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_linbreak_handler () function is used assign a custom
+ interrupt handler for the LIN Break detection interrupt when the MSS UART
+ is operating in LIN mode.
+
+ Note: The MSS_UART_set_linbreak_handler() function enables both the LIN
+ BREAK interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the LIN BREAK interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_linbreak_handler(&g_mss_uart0_lo, my_break_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_linbreak_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_linsync_handler() function is used assign a custom interrupt
+ handler for the LIN Sync character detection interrupt when the MSS UART is
+ operating in LIN mode.
+
+ Note: The MSS_UART_set_linsync_handler() function enables both the LIN
+ SYNC interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the LIN SYNC interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_linsync_handler(&g_mss_uart0_lo, my_linsync_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_linsync_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_nack_handler() function is used assign a custom interrupt
+ handler for the NACK character detection interrupt when the MSS UART
+ is operating in Smartcard mode.
+
+ Note: The MSS_UART_set_nack_handler() function enables both the NAK
+ interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the NAK interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_nack_handler(&g_mss_uart0_lo, my_nack_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_nack_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_timeout_handler() function is used assign a custom
+ interrupt handler for the receiver timeout interrupt when the MSS UART is
+ operating in mode. It finds application in IrDA mode of operation.
+
+ Note: The MSS_UART_set_rx_timeout_handler() function enables both the
+ time-out interrupt in the MSS UART instance. It also enables the corresponding
+ MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of
+ its implementation.
+
+ Note: You can disable the RX time-out interrupt when required by calling
+ the MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is the pointer to the custom handler function.
+ This parameter is of type mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ int main(void)
+ {
+ uint8_t tx_buff[10] = "abcdefghi";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_timeout_handler(&g_mss_uart0_lo, my_rxtimeout_handler);
+
+ return(0);
+ }
+
+ @endcode
+ */
+void
+MSS_UART_set_rx_timeout_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rxstatus_handler() function is used to register a receiver
+ status handler function that is called by the driver when a UART receiver
+ line status (RLS) interrupt occurs. You must create and register the handler
+ function to suit your application.
+
+ Note: The MSS_UART_set_rxstatus_handler() function enables both the RLS
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+ Note: You can disable the RLS interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a receiver line status interrupt
+ handler function provided by your application that will be called as a
+ result of a UART RLS interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ void uart_rxsts_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_rx_status(this_uart);
+ if(status & MSS_UART_OVERUN_ERROR)
+ {
+ discard_rx_data();
+ }
+ }
+
+ int main(void)
+ {
+ MSS_UART_init( &g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rxstatus_handler(&g_mss_uart0_lo, uart_rxsts_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_rxstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_tx_handler() function is used to register a transmit handler
+ function that is called by the driver when a UART transmit holding register
+ empty (THRE) interrupt occurs. You must create and register the transmit
+ handler function to suit your application. You can use the
+ MSS_UART_fill_tx_fifo() function in your transmit handler function to
+ write data to the transmitter.
+
+ Note: The MSS_UART_set_tx_handler() function enables both the THRE
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+
+ Note: You can disable the THRE interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent upon
+ your application.
+
+ Note: The MSS_UART_irq_tx() function does not use the transmit handler
+ function that you register with the MSS_UART_set_tx_handler() function.
+ It uses its own internal THRE interrupt handler function that overrides
+ any custom interrupt handler that you register using the
+ MSS_UART_set_tx_handler() function.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a transmit interrupt handler
+ function provided by your application that will be called as a result
+ of a UART THRE interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ uint8_t * g_tx_buffer;
+ size_t g_tx_size = 0;
+
+ void uart_tx_handler(mss_uart_instance_t * this_uart)
+ {
+ size_t size_in_fifo;
+ size_in_fifo = MSS_UART_fill_tx_fifo(this_uart,
+ (const uint8_t *)g_tx_buffer,
+ g_tx_size);
+
+ if(size_in_fifo == g_tx_size)
+ {
+ g_tx_size = 0;
+ MSS_UART_disable_irq(this_uart, MSS_UART_TBE_IRQ);
+ }
+ else
+ {
+ g_tx_buffer = &g_tx_buffer[size_in_fifo];
+ g_tx_size = g_tx_size - size_in_fifo;
+ }
+ }
+
+ int main(void)
+ {
+ uint8_t message[12] = "Hello world";
+
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ g_tx_buffer = message;
+ g_tx_size = sizeof(message);
+
+ MSS_UART_set_tx_handler(&g_mss_uart0_lo, uart_tx_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+void
+MSS_UART_set_tx_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_modemstatus_handler() function is used to register a modem
+ status handler function that is called by the driver when a UART modem status
+ (MS) interrupt occurs. You must create and register the handler function to
+ suit your application.
+
+ Note: The MSS_UART_set_modemstatus_handler() function enables both the MS
+ interrupt in the MSS UART instance. It also enables the corresponding MSS UART
+ instance interrupt in the PolarFire SoC Core Complex PLIC as part of its
+ implementation.
+
+ Note: You can disable the MS interrupt when required by calling the
+ MSS_UART_disable_irq() function. This is your choice and is dependent
+ upon your application.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param handler
+ The handler parameter is a pointer to a modem status interrupt handler
+ function provided by your application that will be called as a result
+ of a UART MS interrupt. This handler function must be of type
+ mss_uart_irq_handler_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ #include "mss_uart.h"
+
+ void uart_modem_handler(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_modem_status(this_uart);
+ if(status & MSS_UART_CTS)
+ {
+ uart_cts_handler();
+ }
+ }
+
+ int main(void)
+ {
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_modemstatus_handler(&g_mss_uart0_lo, uart_modem_handler);
+
+ while(1)
+ {
+ ;
+ }
+ return(0);
+ }
+ @endcode
+ */
+
+void
+MSS_UART_set_modemstatus_handler
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_irq_handler_t handler
+);
+
+/***************************************************************************//**
+ The MSS_UART_fill_tx_fifo() function fills the UART's hardware transmitter
+ FIFO with the data found in the transmitter buffer that is passed via the
+ tx_buffer function parameter. If the transmitter FIFO is not empty when
+ the function is called, the function returns immediately without transferring
+ any data to the FIFO; otherwise, the function transfers data from the
+ transmitter buffer to the FIFO until it is full or until the complete
+ contents of the transmitter buffer have been copied into the FIFO. The
+ function returns the number of bytes copied into the UART's transmitter FIFO.
+
+ Note: This function reads the UART's line status register (LSR) to check
+ for the active state of the transmitter holding register empty (THRE) bit
+ before transferring data from the data buffer to the transmitter FIFO. If
+ THRE is 0, the function returns immediately, without transferring any data
+ to the FIFO. If THRE is 1, the function transfers up to 16 bytes of data
+ to the FIFO and then returns.
+
+ Note: The actual transmission over the serial connection will still be
+ in progress when this function returns. Use the MSS_UART_get_tx_status()
+ function if you need to know when the transmitter is empty.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param tx_buffer
+ The tx_buffer parameter is a pointer to a buffer containing the data
+ to be transmitted.
+
+ @param tx_size
+ The tx_size parameter is the size in bytes, of the data to be transmitted.
+
+ @return
+ This function returns the number of bytes copied into the UART's
+ transmitter FIFO.
+
+ Example:
+ @code
+ void send_using_interrupt(uint8_t * pbuff, size_t tx_size)
+ {
+ size_t size_in_fifo;
+ size_in_fifo = MSS_UART_fill_tx_fifo(&g_mss_uart0_lo, pbuff, tx_size);
+ }
+ @endcode
+ */
+size_t
+MSS_UART_fill_tx_fifo
+(
+ mss_uart_instance_t * this_uart,
+ const uint8_t * tx_buffer,
+ size_t tx_size
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_rx_status() function returns the receiver error status of the
+ MSS UART instance. It reads both the current error status of the receiver from
+ the UART's line status register (LSR) and the accumulated error status from
+ preceding calls to the MSS_UART_get_rx() function, and it combines them using
+ a bitwise OR. It returns the cumulative overrun, parity, framing, break and
+ FIFO error status of the receiver, since the previous call to
+ MSS_UART_get_rx_status(), as an 8-bit encoded value.
+
+ Note: The MSS_UART_get_rx() function reads and accumulates the receiver
+ status of the MSS UART instance before reading each byte from the receiver's
+ data register/FIFO. The driver maintains a sticky record of the cumulative
+ receiver error status, which persists after the MSS_UART_get_rx() function
+ returns. The MSS_UART_get_rx_status() function clears the driver's sticky
+ receiver error record before returning.
+
+ Note: The driver's transmit functions also read the line status
+ register (LSR) as part of their implementation. When the driver reads the
+ LSR, the UART clears any active receiver error bits in the LSR. This could
+ result in the driver losing receiver errors. To avoid any loss of receiver
+ errors, the transmit functions also update the driver's sticky record of the
+ cumulative receiver error status whenever they read the LSR.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns the UART's receiver error status as an 8-bit unsigned
+ integer. The returned value is 0 if no receiver errors occurred. The driver
+ provides a set of bit mask constants that should be compared with and/or
+ used to mask the returned value to determine the receiver error status.
+ When the return value is compared to the following bit masks, a non-zero
+ result indicates that the corresponding error occurred:
+ - MSS_UART_OVERRUN_ERROR (bit mask = 0x02)
+ - MSS_UART_PARITY_ERROR (bit mask = 0x04)
+ - MSS_UART_FRAMING_ERROR (bit mask = 0x08)
+ - MSS_UART_BREAK_ERROR (bit mask = 0x10)
+ - MSS_UART_FIFO_ERROR (bit mask = 0x80)
+
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that no error occurred:
+ - MSS_UART_NO_ERROR (bit mask = 0x00)
+
+ Upon unsuccessful execution, this function returns:
+ - MSS_UART_INVALID_PARAM (bit mask = 0xFF)
+
+ Example:
+ @code
+ uint8_t rx_data[MAX_RX_DATA_SIZE];
+ uint8_t err_status;
+ err_status = MSS_UART_get_rx_status(&g_mss_uart0);
+
+ if(MSS_UART_NO_ERROR == err_status)
+ {
+ rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_data, MAX_RX_DATA_SIZE);
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_rx_status
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_modem_status() function returns the modem status of the
+ MSS UART instance. It reads the modem status register (MSR) and returns
+ the 8 bit value. The bit encoding of the returned value is exactly the
+ same as the definition of the bits in the MSR.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns current state of the UART's MSR as an 8 bit
+ unsigned integer. The driver provides the following set of bit mask
+ constants that should be compared with and/or used to mask the
+ returned value to determine the modem status:
+ - MSS_UART_DCTS (bit mask = 0x01)
+ - MSS_UART_DDSR (bit mask = 0x02)
+ - MSS_UART_TERI (bit mask = 0x04)
+ - MSS_UART_DDCD (bit mask = 0x08)
+ - MSS_UART_CTS (bit mask = 0x10)
+ - MSS_UART_DSR (bit mask = 0x20)
+ - MSS_UART_RI (bit mask = 0x40)
+ - MSS_UART_DCD (bit mask = 0x80)
+
+ Example:
+ @code
+ void uart_modem_status_isr(mss_uart_instance_t * this_uart)
+ {
+ uint8_t status;
+ status = MSS_UART_get_modem_status(this_uart);
+ if( status & MSS_UART_DCTS )
+ {
+ uart_dcts_handler();
+ }
+ if( status & MSS_UART_CTS )
+ {
+ uart_cts_handler();
+ }
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_modem_status
+(
+ const mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_get_tx_status() function returns the transmitter status of the
+ MSS UART instance. It reads both the UART's line status register (LSR) and
+ returns the status of the transmit holding register empty (THRE) and
+ transmitter empty (TEMT) bits.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function returns the UART's transmitter status as an 8-bit unsigned
+ integer. The returned value is 0 if the transmitter status bits are not
+ set or the function execution failed. The driver provides a set of bit
+ mask constants that should be compared with and/or used to mask the
+ returned value to determine the transmitter status.
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that the corresponding transmitter status bit is set:
+ - MSS_UART_THRE (bit mask = 0x20)
+ - MSS_UART_TEMT (bit mask = 0x40)
+
+ When the return value is compared to the following bit mask, a non-zero
+ result indicates that the transmitter is busy or the function execution
+ failed.
+ - MSS_UART_TX_BUSY (bit mask = 0x00)
+
+ Example:
+ @code
+ uint8_t tx_buff[10] = "abcdefghi";
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_polled_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff));
+
+ while(!(MSS_UART_TEMT & MSS_UART_get_tx_status(&g_mss_uart0)))
+ {
+ ;
+ }
+ @endcode
+ */
+uint8_t
+MSS_UART_get_tx_status
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_break() function is used to send the break
+ (9 zeros after stop bit) signal on the TX line. This function can be used
+ only when the MSS UART is initialized in LIN mode by using MSS_UART_lin_init().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_break(&g_mss_uart0);
+ @endcode
+ */
+void
+MSS_UART_set_break
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_clear_break() function is used to remove the break signal on the
+ TX line. This function can be used only when the MSS UART is initialized in
+ LIN mode by using MSS_UART_lin_init().
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_lin_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_clear_break(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_clear_break
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_half_duplex() function is used to enable the half-duplex
+ (single wire) mode for the MSS UART. Though it finds application in Smartcard
+ mode, half-duplex mode can be used in other modes as well.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_half_duplex(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_half_duplex() function is used to disable the half-duplex
+ (single wire) mode for the MSS UART. Though it finds application in Smartcard
+ mode, half-duplex mode can be used in other modes as well.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_half_duplex(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_half_duplex
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_rx_endian() function is used to configure the LSB first or
+ MSB first setting for MSS UART receiver
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param endian
+ The endian parameter tells the LSB first or MSB first configuration.
+ This parameter is of type mss_uart_endian_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_endian(&g_mss_uart0_lo, MSS_UART_LITTLEEND);
+ @endcode
+ */
+void
+MSS_UART_set_rx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_tx_endian() function is used to configure the LSB first or
+ MSB first setting for MSS UART transmitter.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param endian
+ The endian parameter tells the LSB first or MSB first configuration.
+ This parameter is of type mss_uart_endian_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_tx_endian(&g_mss_uart0_lo, MSS_UART_LITTLEEND);
+ @endcode
+ */
+void
+MSS_UART_set_tx_endian
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_endian_t endian
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_filter_length () function is used to configure the glitch
+ filter length of the MSS UART. This should be configured in accordance with
+ the chosen baud rate.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param length
+ The length parameter is of mss_uart_filter_length_t type that determines
+ the length of the glitch filter.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_filter_length(&g_mss_uart0_lo, MSS_UART_LEN2);
+ @endcode
+ */
+void
+MSS_UART_set_filter_length
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_filter_length_t length
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_afm() function is used to enable address flag detection
+ mode of the MSS UART
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_afm(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_afm
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_afm() function is used to disable address flag detection
+ mode of the MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_afm(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_afm
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_afclear () function is used to enable address flag clear
+ of the MSS UART. This should be used in conjunction with address flag
+ detection mode (AFM).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_afclear(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_enable_afclear
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_afclear () function is used to disable address flag
+ clear of the MSS UART. This should be used in conjunction with address flag
+ detection mode (AFM).
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_afclear(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_afclear
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_rx_timeout() function is used to enable and configure
+ the receiver timeout functionality of MSS UART. This function accepts the
+ timeout parameter and applies the timeout based up on the baud rate as per
+ the formula 4 x timeout x bit time.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param timeout
+ The timeout parameter specifies the receiver timeout multiple.
+ It should be configured according to the baud rate in use.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_rx_timeout(&g_mss_uart0_lo, 24);
+ @endcode
+ */
+void
+MSS_UART_enable_rx_timeout
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeout
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_rx_timeout() function is used to disable the receiver
+ timeout functionality of MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_rx_timeout(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_rx_timeout
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_tx_time_guard() function is used to enable and configure
+ the transmitter time guard functionality of MSS UART. This function accepts
+ the timeguard parameter and applies the timeguard based up on the baud rate
+ as per the formula timeguard x bit time.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @param timeguard
+ The timeguard parameter specifies the transmitter time guard multiple.
+ It should be configured according to the baud rate in use.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_enable_tx_time_guard(&g_mss_uart0_lo, 24);
+ @endcode
+ */
+void
+MSS_UART_enable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t timeguard
+);
+
+/***************************************************************************//**
+ The MSS_UART_disable_tx_time_guard() function is used to disable the
+ transmitter time guard functionality of MSS UART.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ Note that if you are using the UART on the AMP APB bus, the hardware
+ configuration to connect UART on AMP APB bus must already be done by the
+ application using SYSREG registers before initializing the UART instance
+ structure.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_disable_tx_time_guard(&g_mss_uart0_lo);
+ @endcode
+ */
+void
+MSS_UART_disable_tx_time_guard
+(
+ mss_uart_instance_t * this_uart
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_address() function is used to set the 8-bit address for
+ the MSS UART referenced by this_uart parameter.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param address
+ The address parameter is the 8-bit address which is to be configured
+ to the MSS UART referenced by this_uart parameter.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_address(&g_mss_uart0_lo, 0xAA);
+ @endcode
+ */
+void
+MSS_UART_set_address
+(
+ mss_uart_instance_t * this_uart,
+ uint8_t address
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_ready_mode() function is used to configure the MODE0 or MODE1
+ to the TXRDY and RXRDY signals of the MSS UART referenced by this_uart
+ parameter. The mode parameter is used to provide the mode to be configured.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param mode
+ The mode parameter is the mss_uart_ready_mode_t type which is used to
+ configure the TXRDY and RXRDY signal modes.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_ready_mode(&g_mss_uart0_lo, MSS_UART_READY_MODE0);
+ @endcode
+ */
+void
+MSS_UART_set_ready_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_ready_mode_t mode
+);
+
+/***************************************************************************//**
+ The MSS_UART_set_usart_mode() function is used to configure the MSS UART
+ referenced by the parameter this_uart in USART mode. Various USART modes
+ are supported which can be configured by the parameter mode of type
+ mss_uart_usart_mode_t.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @param mode
+ The mode parameter is the USART mode to be configured.
+ This parameter is of type mss_uart_usart_mode_t.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_usart_mode(&g_mss_uart0_lo, MSS_UART_SYNC_MASTER_POS_EDGE_CLK);
+ @endcode
+ */
+void
+MSS_UART_set_usart_mode
+(
+ mss_uart_instance_t * this_uart,
+ mss_uart_usart_mode_t mode
+);
+
+/***************************************************************************//**
+ The MSS_UART_enable_local_irq() function is used to enable the MMUART
+ interrupt as a local interrupt to the hart rather than via PLIC.
+ MMUART interrupt can be configured to trigger an interrupt via PLIC or it
+ can be configured to trigger a local interrupt. The arrangement is such that
+ the UART0 interrupt can appear as local interrupt on E51. The UART1 to UART4
+ interrupts can appear as local interrupt to U51_1 to U54_4 respectively.
+ The UART0 to UART4 can appear as PLIC interrupt. Multiple HARTs can enable
+ and receive the PLIC interrupt, the HART that claims the interrupt processes
+ it. For rest of the HARTs the IRQ gets silently skipped as the interrupt
+ claim has already been taken.
+
+ By default, the PLIC interrupt is enabled by this driver when
+ MSS_UART_enable_irq() or the APIs to set the interrupt handler is called.
+ To enable the local interrupt application must explicitly call
+ MSS_UART_enable_local_irq() function. Note that this function disables the
+ interrupt over PLIC if it was previously enabled.
+
+ This function must be called after the MMUART is initialized, the required
+ interrupt hander functions are set and before initiating any data transfers.
+ If you want to register multiple register handlers such as tx handler, rx
+ handler etc. then this function must be called after all such handlers are set.
+
+ Call to this function is treated as one time activity. The driver gives no
+ option to disable the local interrupt and enable the PLIC interrupt again at
+ runtime.
+
+ @param this_uart
+ The this_uart parameter is a pointer to an mss_uart_instance_t
+ structure identifying the MSS UART hardware block that will perform
+ the requested function. There are ten such data structures,
+ g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 5 (main APB bus) and
+ g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4
+ when they are connected on the AXI switch slave 6 (AMP APB bus).
+ This parameter must point to one of these ten global data structure defined
+ within the UART driver.
+
+ @return
+ This function does not return a value.
+
+ Example:
+ @code
+
+
+ __enable_irq();
+ MSS_UART_init(&g_mss_uart0_lo,
+ MSS_UART_57600_BAUD,
+ MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
+
+ MSS_UART_set_rx_handler(&g_mss_uart0_lo,
+ uart0_rx_handler,
+ MSS_UART_FIFO_SINGLE_BYTE);
+
+ MSS_UART_enable_local_irq(&g_mss_uart0_lo);
+
+ @endcode
+ */
+void
+MSS_UART_enable_local_irq
+(
+ mss_uart_instance_t * this_uart
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_UART_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h
new file mode 100644
index 00000000..d550810a
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h
@@ -0,0 +1,133 @@
+ /*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Register bit offsets and masks definitions for PolarFire SoC MSS MMUART
+ *
+ */
+
+#ifndef MSS_UART_REGS_H_
+#define MSS_UART_REGS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ Register Bit definitions
+ */
+
+/* Line Control register bit definitions */
+#define SB 6u /* Set break */
+#define DLAB 7u /* Divisor latch access bit */
+
+/* Line Control register bit masks */
+#define SB_MASK (0x01u << SB) /* Set break */
+#define DLAB_MASK (0x01u << DLAB) /* Divisor latch access bit */
+
+/* FIFO Control register bit definitions */
+#define RXRDY_TXRDYN_EN 0u /* Enable TXRDY and RXRDY signals */
+#define CLEAR_RX_FIFO 1u /* Clear receiver FIFO */
+#define CLEAR_TX_FIFO 2u /* Clear transmitter FIFO */
+#define RDYMODE 3u /* Mode 0 or Mode 1 for TXRDY and RXRDY */
+
+/* FIFO Control register bit MASKS */
+#define RXRDY_TXRDYN_EN_MASK (0x01u << 0u) /* Enable TXRDY and RXRDY signals */
+#define CLEAR_RX_FIFO_MASK (0x01u << 1u) /* Clear receiver FIFO */
+#define CLEAR_TX_FIFO_MASK (0x01u << 2u) /* Clear transmitter FIFO */
+#define RDYMODE_MASK (0x01u << 3u) /* Mode 0 or Mode 1 for TXRDY and RXRDY */
+
+/* Modem Control register bit definitions */
+#define LOOP 4u /* Local loopback */
+#define RLOOP 5u /* Remote loopback */
+#define ECHO 6u /* Automatic echo */
+
+/* Modem Control register bit MASKS */
+#define LOOP_MASK (0x01u << 4u) /* Local loopback */
+#define RLOOP_MASK (0x01u << 5u) /* Remote loopback & Automatic echo*/
+#define ECHO_MASK (0x01u << 6u) /* Automatic echo */
+
+/* Line Status register bit definitions */
+#define DR 0u /* Data ready */
+#define THRE 5u /* Transmitter holding register empty */
+#define TEMT 6u /* Transmitter empty */
+
+/* Line Status register bit MASKS */
+#define DR_MASK (0x01u << 0u) /* Data ready */
+#define THRE_MASK (0x01u << 5u) /* Transmitter holding register empty */
+#define TEMT_MASK (0x01u << 6u) /* Transmitter empty */
+
+/* Interrupt Enable register bit definitions */
+#define ERBFI 0u /* Enable receiver buffer full interrupt */
+#define ETBEI 1u /* Enable transmitter buffer empty interrupt */
+#define ELSI 2u /* Enable line status interrupt */
+#define EDSSI 3u /* Enable modem status interrupt */
+
+/* Interrupt Enable register bit MASKS */
+#define ERBFI_MASK (0x01u << 0u) /* Enable receiver buffer full interrupt */
+#define ETBEI_MASK (0x01u << 1u) /* Enable transmitter buffer empty interrupt */
+#define ELSI_MASK (0x01u << 2u) /* Enable line status interrupt */
+#define EDSSI_MASK (0x01u << 3u) /* Enable modem status interrupt */
+
+/* Multimode register 0 bit definitions */
+#define ELIN 3u /* Enable LIN header detection */
+#define ETTG 5u /* Enable transmitter time guard */
+#define ERTO 6u /* Enable receiver time-out */
+#define EFBR 7u /* Enable fractional baud rate mode */
+
+/* Multimode register 0 bit MASKS */
+#define ELIN_MASK (0x01u << 3u) /* Enable LIN header detection */
+#define ETTG_MASK (0x01u << 5u) /* Enable transmitter time guard */
+#define ERTO_MASK (0x01u << 6u) /* Enable receiver time-out */
+#define EFBR_MASK (0x01u << 7u) /* Enable fractional baud rate mode */
+
+/* Multimode register 1 bit definitions */
+#define E_MSB_RX 0u /* MSB / LSB first for receiver */
+#define E_MSB_TX 1u /* MSB / LSB first for transmitter */
+#define EIRD 2u /* Enable IrDA modem */
+#define EIRX 3u /* Input polarity for IrDA modem */
+#define EITX 4u /* Output polarity for IrDA modem */
+#define EITP 5u /* Output pulse width for IrDA modem */
+
+/* Multimode register 1 bit MASKS */
+#define E_MSB_RX_MASK (0x01u << 0u) /* MSB / LSB first for receiver */
+#define E_MSB_TX_MASK (0x01u << 1u) /* MSB / LSB first for transmitter */
+#define EIRD_MASK (0x01u << 2u) /* Enable IrDA modem */
+#define EIRX_MASK (0x01u << 3u) /* Input polarity for IrDA modem */
+#define EITX_MASK (0x01u << 4u) /* Output polarity for IrDA modem */
+#define EITP_MASK (0x01u << 5u) /* Output pulse width for IrDA modem */
+
+/* Multimode register 2 bit definitions */
+#define EERR 0u /* Enable ERR / NACK during stop time */
+#define EAFM 1u /* Enable 9-bit address flag mode */
+#define EAFC 2u /* Enable address flag clear */
+#define ESWM 3u /* Enable single wire half-duplex mode */
+
+/* Multimode register 2 bit MASKS */
+#define EERR_MASK (0x01u << 0u) /* Enable ERR / NACK during stop time */
+#define EAFM_MASK (0x01u << 1u) /* Enable 9-bit address flag mode */
+#define EAFC_MASK (0x01u << 2u) /* Enable address flag clear */
+#define ESWM_MASK (0x01u << 3u) /* Enable single wire half-duplex mode */
+
+/* Multimode Interrupt Enable register and
+ Multimode Interrupt Identification register definitions */
+#define ERTOI 0u /* Enable receiver timeout interrupt */
+#define ENACKI 1u /* Enable NACK / ERR interrupt */
+#define EPID_PEI 2u /* Enable PID parity error interrupt */
+#define ELINBI 3u /* Enable LIN break interrupt */
+#define ELINSI 4u /* Enable LIN sync detection interrupt */
+
+/* Multimode Interrupt Enable register and
+ Multimode Interrupt Identification register MASKS */
+#define ERTOI_MASK (0x01u << 0u) /* Enable receiver timeout interrupt */
+#define ENACKI_MASK (0x01u << 1u) /* Enable NACK / ERR interrupt */
+#define EPID_PEI_MASK (0x01u << 2u) /* Enable PID parity error interrupt */
+#define ELINBI_MASK (0x01u << 3u) /* Enable LIN break interrupt */
+#define ELINSI_MASK (0x01u << 4u) /* Enable LIN sync detection interrupt */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_UART_REGS_H_ */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/cpu_types.h b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/cpu_types.h
new file mode 100644
index 00000000..55cfac93
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/cpu_types.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+#ifndef CPU_TYPES_H
+#define CPU_TYPES_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long size_t;
+
+/*------------------------------------------------------------------------------
+ * addr_t: address type.
+ * Used to specify the address of peripherals present in the processor's memory
+ * map.
+ */
+typedef unsigned long addr_t;
+
+/*------------------------------------------------------------------------------
+ * psr_t: processor state register.
+ * Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the
+ * processor's state between disabling and restoring interrupts.
+ */
+typedef unsigned long psr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CPU_TYPES_H */
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal.h b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal.h
new file mode 100644
index 00000000..658ab2a0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal.h
@@ -0,0 +1,241 @@
+/***************************************************************************//**
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Hardware abstraction layer functions.
+ *
+ * Legacy register interrupt functions
+ * Pointers are now recommended for use in drivers
+ *
+ */
+#ifndef HAL_H
+#define HAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cpu_types.h"
+#include "hw_reg_access.h"
+#include "hal/hal_assert.h"
+/***************************************************************************//**
+ * Enable all interrupts at the processor level.
+ */
+void HAL_enable_interrupts( void );
+
+/***************************************************************************//**
+ * Disable all interrupts at the processor core level.
+ * Return the interrupts enable state before disabling occurred so that it can
+ * later be restored.
+ */
+psr_t HAL_disable_interrupts( void );
+
+/***************************************************************************//**
+ * Restore the interrupts enable state at the processor core level.
+ * This function is normally passed the value returned from a previous call to
+ * HAL_disable_interrupts().
+ */
+void HAL_restore_interrupts( psr_t saved_psr );
+
+/***************************************************************************//**
+ */
+#define FIELD_OFFSET(FIELD_NAME) (FIELD_NAME##_OFFSET)
+#define FIELD_SHIFT(FIELD_NAME) (FIELD_NAME##_SHIFT)
+#define FIELD_MASK(FIELD_NAME) (FIELD_NAME##_MASK)
+
+/***************************************************************************//**
+ * The macro HAL_set_32bit_reg() allows writing a 32 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint32_t containing the value to write.
+ */
+#define HAL_set_32bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_32bit_reg() is used to read the value of a 32 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint32_t value.
+ */
+#define HAL_get_32bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)) ))
+
+/***************************************************************************//**
+ * The macro HAL_set_32bit_reg_field() is used to write a field within a
+ * 32 bits wide register. The field written can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint32_t containing the field value to write.
+ */
+#define HAL_set_32bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_32bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_32bit_reg_field() is used to read a register field from
+ * within a 32 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint32_t value.
+ */
+#define HAL_get_32bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_32bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+/***************************************************************************//**
+ * The macro HAL_set_16bit_reg() allows writing a 16 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint_fast16_t containing the value to write.
+ */
+#define HAL_set_16bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_16bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_16bit_reg() is used to read the value of a 16 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint16_t value.
+ */
+#define HAL_get_16bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_16bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
+
+/***************************************************************************//**
+ * The macro HAL_set_16bit_reg_field() is used to write a field within a
+ * 16 bits wide register. The field written can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint16_t containing the field value to write.
+ */
+#define HAL_set_16bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_16bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_16bit_reg_field() is used to read a register field from
+ * within a 8 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint16_t value.
+ */
+#define HAL_get_16bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_16bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+/***************************************************************************//**
+ * The macro HAL_set_8bit_reg() allows writing a 8 bits wide register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to write. These strings are
+ * specified in a header file associated with the peripheral.
+ * VALUE: A variable of type uint_fast8_t containing the value to write.
+ */
+#define HAL_set_8bit_reg(BASE_ADDR, REG_NAME, VALUE) \
+ (HW_set_8bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
+
+/***************************************************************************//**
+ * The macro HAL_get_8bit_reg() is used to read the value of a 8 bits wide
+ * register.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * REG_NAME: A string identifying the register to read. These strings are
+ * specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint8_t value.
+ */
+#define HAL_get_8bit_reg(BASE_ADDR, REG_NAME) \
+ (HW_get_8bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
+
+/***************************************************************************//**
+ */
+#define HAL_set_8bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
+ (HW_set_8bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME),\
+ (VALUE)))
+
+/***************************************************************************//**
+ * The macro HAL_get_8bit_reg_field() is used to read a register field from
+ * within a 8 bit wide peripheral register. The field can be one or more bits.
+ *
+ * BASE_ADDR: A variable of type addr_t specifying the base address of the
+ * peripheral containing the register.
+ * FIELD_NAME: A string identifying the register field to write. These strings
+ * are specified in a header file associated with the peripheral.
+ * RETURN: This function-like macro returns a uint8_t value.
+ */
+#define HAL_get_8bit_reg_field(BASE_ADDR, FIELD_NAME) \
+ (HW_get_8bit_reg_field(\
+ (BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
+ FIELD_SHIFT(FIELD_NAME),\
+ FIELD_MASK(FIELD_NAME)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*HAL_H*/
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_assert.h b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_assert.h
new file mode 100644
index 00000000..8d64b3c5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_assert.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+#ifndef HAL_ASSERT_HEADER
+#define HAL_ASSERT_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * ASSERT() implementation.
+ ******************************************************************************/
+/* Disable assertions if we do not recognize the compiler. */
+#if defined ( __GNUC__ )
+#if defined(NDEBUG)
+#define ASSERT(CHECK)
+#else
+#define ASSERT(CHECK)\
+ do { \
+ if (!(CHECK)) \
+ { \
+ __asm volatile ("ebreak"); \
+ }\
+ } while(0);
+#endif /* NDEBUG check */
+#endif /* compiler check */
+
+#if defined(NDEBUG)
+/***************************************************************************//**
+ * HAL_ASSERT() is defined out when the NDEBUG symbol is used.
+ ******************************************************************************/
+#define HAL_ASSERT(CHECK)
+
+#else
+/***************************************************************************//**
+ * Default behaviour for HAL_ASSERT() macro:
+ *------------------------------------------------------------------------------
+ The behaviour is toolchain specific and project setting specific.
+ ******************************************************************************/
+#define HAL_ASSERT(CHECK) ASSERT(CHECK);
+
+#endif /* NDEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_ASSERT_HEADER */
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_irq.c b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_irq.c
new file mode 100644
index 00000000..2fea28e1
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_irq.c
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Legacy interrupt control functions for the Microchip driver library hardware
+ * abstraction layer.
+ *
+ */
+#include
+#include "hal/hal.h"
+#include "mpfs_hal/common/mss_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void HAL_enable_interrupts(void) {
+ __enable_irq();
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+psr_t HAL_disable_interrupts(void) {
+ psr_t psr;
+ psr = read_csr(mstatus);
+ __disable_irq();
+ return(psr);
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void HAL_restore_interrupts(psr_t saved_psr) {
+ write_csr(mstatus, saved_psr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_version.h b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_version.h
new file mode 100644
index 00000000..7d4d31c8
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hal_version.h
@@ -0,0 +1,50 @@
+#ifndef HAL_VERSION_H
+#define HAL_VERSION_H
+
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip Corporation.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ *
+ *
+ */
+
+/*******************************************************************************
+ * @file mpfs_halversion.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MICROCHIP FPGA Embedded Software Hardware Abstraction layer - HAL
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HAL_VERSION_MAJOR 1
+#define HAL_VERSION_MINOR 8
+#define HAL_VERSION_PATCH 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_macros.h b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_macros.h
new file mode 100644
index 00000000..cab09353
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_macros.h
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * Hardware registers access macros.
+ *
+ * THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USE FOR NEW
+ * DEVELOPMENT.
+ *
+ * These macros are used to access peripheral registers. They allow access to
+ * 8, 16 and 32 bit wide registers. All accesses to peripheral registers should
+ * be done through these macros in order to ease porting across different
+ * processors/bus architectures.
+ *
+ * Some of these macros also allow access to a specific register field.
+ *
+ */
+
+#ifndef HW_MACROS_H
+#define HW_MACROS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*------------------------------------------------------------------------------
+ * 32 bits registers access:
+ */
+#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint32_t) \
+ ( \
+ (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 32 bits memory access:
+ */
+#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))
+
+#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))
+
+/*------------------------------------------------------------------------------
+ * 16 bits registers access:
+ */
+#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint16_t) \
+ ( \
+ (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 8 bits registers access:
+ */
+#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
+
+#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
+
+#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \
+ (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
+ ( \
+ (uint8_t) \
+ ( \
+ (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
+ (uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
+ ) \
+ )
+
+#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \
+ (( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
+
+/*------------------------------------------------------------------------------
+ * 8 bits memory access:
+ */
+#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))
+
+#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#endif /* HW_MACROS_ */
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_reg_access.S b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_reg_access.S
new file mode 100644
index 00000000..31352f60
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_reg_access.S
@@ -0,0 +1,214 @@
+/***************************************************************************//**
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ * Hardware registers access functions.
+ * The implementation of these function is platform and toolchain specific.
+ * The functions declared here are implemented using assembler as part of the
+ * processor/toolchain specific HAL.
+ *
+ */
+
+.section .text
+ .globl HW_set_32bit_reg
+ .globl HW_get_32bit_reg
+ .globl HW_set_32bit_reg_field
+ .globl HW_get_32bit_reg_field
+ .globl HW_set_16bit_reg
+ .globl HW_get_16bit_reg
+ .globl HW_set_16bit_reg_field
+ .globl HW_get_16bit_reg_field
+ .globl HW_set_8bit_reg
+ .globl HW_get_8bit_reg
+ .globl HW_set_8bit_reg_field
+ .globl HW_get_8bit_reg_field
+
+
+/***************************************************************************//**
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint32_t value
+ */
+HW_set_32bit_reg:
+ sw a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 32 bits value read from the peripheral register.
+ */
+HW_get_32bit_reg:
+ lw a0, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint32_t mask
+ * a3: uint32_t value
+ */
+HW_set_32bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lw t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sw t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_32bit_reg_field is used to read the content of a field out of a
+ * 32 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint32_t mask
+ *
+ * @return 32 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_32bit_reg_field:
+ lw a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+/***************************************************************************//**
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint_fast16_t value
+ */
+HW_set_16bit_reg:
+ sh a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 16 bits value read from the peripheral register.
+ */
+HW_get_16bit_reg:
+ lh a0, (a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast16_t mask
+ * a3: uint_fast16_t value
+ * @param value Value to be written in the specified field.
+ */
+HW_set_16bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lh t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sh t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_16bit_reg_field is used to read the content of a field from a
+ * 16 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast16_t mask
+ *
+ * @return 16 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_16bit_reg_field:
+ lh a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+/***************************************************************************//**
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+ * a1: uint_fast8_t value
+ */
+HW_set_8bit_reg:
+ sb a1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
+ * register.
+ *
+ * a0: addr_t reg_addr
+
+ * @return 8 bits value read from the peripheral register.
+ */
+HW_get_8bit_reg:
+ lb a0, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
+ * wide peripheral register.
+ *
+ * a0: addr_t reg_addr,
+ * a1: int_fast8_t shift
+ * a2: uint_fast8_t mask
+ * a3: uint_fast8_t value
+ */
+HW_set_8bit_reg_field:
+ mv t3, a3
+ sll t3, t3, a1
+ and t3, t3, a2
+ lb t1, 0(a0)
+ mv t2, a2
+ not t2, t2
+ and t1, t1, t2
+ or t1, t1, t3
+ sb t1, 0(a0)
+ ret
+
+/***************************************************************************//**
+ * HW_get_8bit_reg_field is used to read the content of a field from a
+ * 8 bits wide peripheral register.
+ *
+ * a0: addr_t reg_addr
+ * a1: int_fast8_t shift
+ * a2: uint_fast8_t mask
+ *
+ * @return 8 bits value containing the register field value specified
+ * as parameter.
+ */
+HW_get_8bit_reg_field:
+ lb a0, 0(a0)
+ and a0, a0, a2
+ srl a0, a0, a1
+ ret
+
+.end
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_reg_access.h b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_reg_access.h
new file mode 100644
index 00000000..10ae5469
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/hw_reg_access.h
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/***************************************************************************//**
+ *
+ * Hardware registers access functions.
+ * The implementation of these function is platform and tool-chain specific.
+ * The functions declared here are implemented using assembler as part of the
+ * processor/tool-chain specific HAL.
+ *
+ */
+#ifndef HW_REG_ACCESS
+#define HW_REG_ACCESS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "cpu_types.h"
+/***************************************************************************//**
+ * HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_32bit_reg
+(
+ addr_t reg_addr,
+ uint32_t value
+);
+
+/***************************************************************************//**
+ * HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 32 bits value read from the peripheral register.
+ */
+uint32_t
+HW_get_32bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void
+HW_set_32bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint32_t mask,
+ uint32_t value
+);
+
+/***************************************************************************//**
+ * HW_get_32bit_reg_field is used to read the content of a field out of a
+ * 32 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 32 bits value containing the register field value specified
+ * as parameter.
+ */
+uint32_t
+HW_get_32bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint32_t mask
+);
+
+/***************************************************************************//**
+ * HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_16bit_reg
+(
+ addr_t reg_addr,
+ uint_fast16_t value
+);
+
+/***************************************************************************//**
+ * HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 16 bits value read from the peripheral register.
+ */
+uint16_t
+HW_get_16bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void HW_set_16bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast16_t mask,
+ uint_fast16_t value
+);
+
+/***************************************************************************//**
+ * HW_get_16bit_reg_field is used to read the content of a field from a
+ * 16 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 16 bits value containing the register field value specified
+ * as parameter.
+ */
+uint16_t HW_get_16bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast16_t mask
+);
+
+/***************************************************************************//**
+ * HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * write.
+ * @param value Value to be written into the peripheral register.
+ */
+void
+HW_set_8bit_reg
+(
+ addr_t reg_addr,
+ uint_fast8_t value
+);
+
+/***************************************************************************//**
+ * HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
+ * register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @return 8 bits value read from the peripheral register.
+ */
+uint8_t
+HW_get_8bit_reg
+(
+ addr_t reg_addr
+);
+
+/***************************************************************************//**
+ * HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
+ * wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * be written.
+ * @param shift Bit offset of the register field to be read within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ * @param value Value to be written in the specified field.
+ */
+void HW_set_8bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast8_t mask,
+ uint_fast8_t value
+);
+
+/***************************************************************************//**
+ * HW_get_8bit_reg_field is used to read the content of a field from a
+ * 8 bits wide peripheral register.
+ *
+ * @param reg_addr Address in the processor's memory map of the register to
+ * read.
+ * @param shift Bit offset of the register field to be written within the
+ * register.
+ * @param mask Bit mask to be applied to the raw register value to filter
+ * out the other register fields values.
+ *
+ * @return 8 bits value containing the register field value specified
+ * as parameter.
+ */
+uint8_t HW_get_8bit_reg_field
+(
+ addr_t reg_addr,
+ int_fast8_t shift,
+ uint_fast8_t mask
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HW_REG_ACCESS */
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/hal/readme.md b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/readme.md
new file mode 100644
index 00000000..ce9ae8f6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/hal/readme.md
@@ -0,0 +1,41 @@
+===============================================================================
+# hal folder
+===============================================================================
+
+The HAL folder provides support code for use by the bare metal drivers for the
+fabric IP cores.
+The HAL folder contains files using a combination of C and assembly source code.
+
+The hal folder should be included in a PolarFire SoC Embedded project under the
+platform directory. See location in the drawing below.
+
+The hal folder contains:
+
+* register access functions
+* assert macros
+
+### Project directory strucutre, showing where hal folder sits.
+
+ +---------+ +-----------+
+ | src +----->|application|
+ +---------+ | +-----------+
+ |
+ | +-----------+
+ +-->|modules |
+ | +-----------+
+ |
+ | +-----------+ +---------+
+ +-->|platform +---->|config |
+ +-----------+ | +---------+
+ |
+ | +---------+
+ +->|drivers |
+ | +---------+
+ |
+ | +---------+
+ +->|hal |
+ | +---------+
+ |
+ | +---------+
+ +->|mpfs_hal |
+ +---------+
\ No newline at end of file
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/atomic.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/atomic.h
new file mode 100644
index 00000000..48110f00
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/atomic.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+
+#ifndef RISCV_ATOMIC_H
+#define RISCV_ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define mb() asm volatile ("fence" ::: "memory")
+#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val)
+#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr))
+
+#ifdef __riscv_atomic
+# define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp)
+# define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc)
+#else
+#define atomic_binop(ptr, inc, op) ({ \
+ long flags = disable_irqsave(); \
+ typeof(*(ptr)) res = atomic_read(ptr); \
+ atomic_set(ptr, op); \
+ enable_irqrestore(flags); \
+ res; })
+#define atomic_or(ptr, inc) atomic_binop(ptr, inc, res | (inc))
+#define atomic_swap(ptr, swp) atomic_binop(ptr, swp, (swp))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //RISCV_ATOMIC_H
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/bits.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/bits.h
new file mode 100644
index 00000000..b2df5f55
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/bits.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+#ifndef RISCV_BITS_H
+#define RISCV_BITS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define likely(x) __builtin_expect((x), 1)
+#define unlikely(x) __builtin_expect((x), 0)
+
+#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
+#define ROUNDDOWN(a, b) ((a)/(b)*(b))
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
+
+#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
+#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
+
+#define STR(x) XSTR(x)
+#define XSTR(x) #x
+
+#if __riscv_xlen == 64
+# define SLL32 sllw
+# define STORE sd
+# define LOAD ld
+# define LWU lwu
+# define LOG_REGBYTES 3
+#else
+# define SLL32 sll
+# define STORE sw
+# define LOAD lw
+# define LWU lw
+# define LOG_REGBYTES 2
+#endif
+#define REGBYTES (1 << LOG_REGBYTES)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //RISCV_BITS_H
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/encoding.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/encoding.h
new file mode 100644
index 00000000..c86fb172
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/encoding.h
@@ -0,0 +1,1532 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+
+
+#ifndef RISCV_CSR_ENCODING_H
+#define RISCV_CSR_ENCODING_H
+
+#define MSTATUS_UIE 0x00000001
+#define MSTATUS_SIE 0x00000002
+#define MSTATUS_HIE 0x00000004
+#define MSTATUS_MIE 0x00000008
+#define MSTATUS_UPIE 0x00000010
+#define MSTATUS_SPIE 0x00000020
+#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_MPIE 0x00000080
+#define MSTATUS_SPP 0x00000100
+#define MSTATUS_HPP 0x00000600
+#define MSTATUS_MPP 0x00001800
+#define MSTATUS_FS 0x00006000
+#define MSTATUS_XS 0x00018000
+#define MSTATUS_MPRV 0x00020000
+#define MSTATUS_SUM 0x00040000
+#define MSTATUS_MXR 0x00080000
+#define MSTATUS_TVM 0x00100000
+#define MSTATUS_TW 0x00200000
+#define MSTATUS_TSR 0x00400000
+#define MSTATUS32_SD 0x80000000
+#define MSTATUS64_SD 0x8000000000000000
+
+#define MCAUSE32_CAUSE 0x7FFFFFFF
+#define MCAUSE64_CAUSE 0x7FFFFFFFFFFFFFFF
+#define MCAUSE32_INT 0x80000000
+#define MCAUSE64_INT 0x8000000000000000
+
+#define SSTATUS_UIE 0x00000001
+#define SSTATUS_SIE 0x00000002
+#define SSTATUS_UPIE 0x00000010
+#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_SPP 0x00000100
+#define SSTATUS_FS 0x00006000
+#define SSTATUS_XS 0x00018000
+#define SSTATUS_SUM 0x00040000
+#define SSTATUS_MXR 0x00080000
+#define SSTATUS32_SD 0x80000000
+#define SSTATUS64_SD 0x8000000000000000
+
+#define DCSR_XDEBUGVER (3U<<30)
+#define DCSR_NDRESET (1<<29)
+#define DCSR_FULLRESET (1<<28)
+#define DCSR_EBREAKM (1<<15)
+#define DCSR_EBREAKH (1<<14)
+#define DCSR_EBREAKS (1<<13)
+#define DCSR_EBREAKU (1<<12)
+#define DCSR_STOPCYCLE (1<<10)
+#define DCSR_STOPTIME (1<<9)
+#define DCSR_CAUSE (7<<6)
+#define DCSR_DEBUGINT (1<<5)
+#define DCSR_HALT (1<<3)
+#define DCSR_STEP (1<<2)
+#define DCSR_PRV (3<<0)
+
+#define DCSR_CAUSE_NONE 0
+#define DCSR_CAUSE_SWBP 1
+#define DCSR_CAUSE_HWBP 2
+#define DCSR_CAUSE_DEBUGINT 3
+#define DCSR_CAUSE_STEP 4
+#define DCSR_CAUSE_HALT 5
+
+#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
+#define MCONTROL_SELECT (1U<<19)
+#define MCONTROL_TIMING (1U<<18)
+#define MCONTROL_ACTION (0x3fU<<12)
+#define MCONTROL_CHAIN (1U<<11)
+#define MCONTROL_MATCH (0xfU<<7)
+#define MCONTROL_M (1U<<6)
+#define MCONTROL_H (1U<<5)
+#define MCONTROL_S (1U<<4)
+#define MCONTROL_U (1U<<3)
+#define MCONTROL_EXECUTE (1U<<2)
+#define MCONTROL_STORE (1U<<1)
+#define MCONTROL_LOAD (1U<<0)
+
+#define MCONTROL_TYPE_NONE 0
+#define MCONTROL_TYPE_MATCH 2
+
+#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
+#define MCONTROL_ACTION_DEBUG_MODE 1
+#define MCONTROL_ACTION_TRACE_START 2
+#define MCONTROL_ACTION_TRACE_STOP 3
+#define MCONTROL_ACTION_TRACE_EMIT 4
+
+#define MCONTROL_MATCH_EQUAL 0
+#define MCONTROL_MATCH_NAPOT 1
+#define MCONTROL_MATCH_GE 2
+#define MCONTROL_MATCH_LT 3
+#define MCONTROL_MATCH_MASK_LOW 4
+#define MCONTROL_MATCH_MASK_HIGH 5
+
+#define MIP_SSIP (1U << IRQ_S_SOFT)
+#define MIP_HSIP (1U << IRQ_H_SOFT)
+#define MIP_MSIP (1U << IRQ_M_SOFT)
+#define MIP_STIP (1U << IRQ_S_TIMER)
+#define MIP_HTIP (1U << IRQ_H_TIMER)
+#define MIP_MTIP (1U << IRQ_M_TIMER)
+#define MIP_SEIP (1U << IRQ_S_EXT)
+#define MIP_HEIP (1U << IRQ_H_EXT)
+#define MIP_MEIP (1U << IRQ_M_EXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+#define SPTBR32_MODE 0x80000000
+#define SPTBR32_ASID 0x7FC00000
+#define SPTBR32_PPN 0x003FFFFF
+#define SPTBR64_MODE 0xF000000000000000
+#define SPTBR64_ASID 0x0FFFF00000000000
+#define SPTBR64_PPN 0x00000FFFFFFFFFFF
+
+#define SPTBR_MODE_OFF 0
+#define SPTBR_MODE_SV32 1
+#define SPTBR_MODE_SV39 8
+#define SPTBR_MODE_SV48 9
+#define SPTBR_MODE_SV57 10
+#define SPTBR_MODE_SV64 11
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_L 0x80
+#define PMP_SHIFT 2
+
+#define PMP_TOR 0x08
+#define PMP_NA4 0x10
+#define PMP_NAPOT 0x18
+
+#define IRQ_S_SOFT 1
+#define IRQ_H_SOFT 2
+#define IRQ_M_SOFT 3
+#define IRQ_S_TIMER 5
+#define IRQ_H_TIMER 6
+#define IRQ_M_TIMER 7
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10
+#define IRQ_M_EXT 11
+#define IRQ_COP 12
+#define IRQ_HOST 13
+
+#define DEFAULT_RSTVEC 0x00001000
+#define CLINT_BASE 0x02000000
+#define CLINT_SIZE 0x000c0000
+#define EXT_IO_BASE 0x40000000
+#define DRAM_BASE 0x80000000
+
+// page table entry (PTE) fields
+#define PTE_V 0x001 // Valid
+#define PTE_R 0x002 // Read
+#define PTE_W 0x004 // Write
+#define PTE_X 0x008 // Execute
+#define PTE_U 0x010 // User
+#define PTE_G 0x020 // Global
+#define PTE_A 0x040 // Accessed
+#define PTE_D 0x080 // Dirty
+#define PTE_SOFT 0x300 // Reserved for Software
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
+
+#ifdef __riscv
+
+#if __riscv_xlen == 64
+# define MSTATUS_SD MSTATUS64_SD
+# define SSTATUS_SD SSTATUS64_SD
+# define RISCV_PGLEVEL_BITS 9
+# define SPTBR_MODE SPTBR64_MODE
+# define MCAUSE_INT MCAUSE64_INT //ML added- should we be using later encoding.h?
+# define MCAUSE_CAUSE MCAUSE64_CAUSE //ML added- should we be using later encoding.h?
+#else
+# define MSTATUS_SD MSTATUS32_SD
+# define SSTATUS_SD SSTATUS32_SD
+# define RISCV_PGLEVEL_BITS 10
+# define SPTBR_MODE SPTBR32_MODE
+# define MCAUSE_INT MCAUSE32_INT //ML added- should we be using later encoding.h?
+# define MCAUSE_CAUSE MCAUSE32_CAUSE //ML added- should we be using later encoding.h?
+#endif
+#define RISCV_PGSHIFT 12
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#ifndef __ASSEMBLER__
+
+#ifdef __GNUC__
+
+#define read_reg(reg) ({ unsigned long __tmp; \
+ asm volatile ("mv %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define read_csr(reg) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define write_csr(reg, val) __extension__({ \
+ asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
+
+#define swap_csr(reg, val) ({ unsigned long __tmp; \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
+ __tmp; })
+
+#define set_csr(reg, bit) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#define clear_csr(reg, bit) __extension__({ unsigned long __tmp; \
+ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#if 0
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ asm volatile ("csrw " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+#endif
+
+#define rdtime() read_csr(time)
+#define rdcycle() read_csr(cycle)
+#define rdinstret() read_csr(instret)
+
+#endif
+
+#endif
+
+#endif
+
+#endif
+/* Automatically generated by parse-opcodes. */
+#ifndef RISCV_ENCODING_H
+#define RISCV_ENCODING_H
+#define MATCH_BEQ 0x63
+#define MASK_BEQ 0x707f
+#define MATCH_BNE 0x1063
+#define MASK_BNE 0x707f
+#define MATCH_BLT 0x4063
+#define MASK_BLT 0x707f
+#define MATCH_BGE 0x5063
+#define MASK_BGE 0x707f
+#define MATCH_BLTU 0x6063
+#define MASK_BLTU 0x707f
+#define MATCH_BGEU 0x7063
+#define MASK_BGEU 0x707f
+#define MATCH_JALR 0x67
+#define MASK_JALR 0x707f
+#define MATCH_JAL 0x6f
+#define MASK_JAL 0x7f
+#define MATCH_LUI 0x37
+#define MASK_LUI 0x7f
+#define MATCH_AUIPC 0x17
+#define MASK_AUIPC 0x7f
+#define MATCH_ADDI 0x13
+#define MASK_ADDI 0x707f
+#define MATCH_SLLI 0x1013
+#define MASK_SLLI 0xfc00707f
+#define MATCH_SLTI 0x2013
+#define MASK_SLTI 0x707f
+#define MATCH_SLTIU 0x3013
+#define MASK_SLTIU 0x707f
+#define MATCH_XORI 0x4013
+#define MASK_XORI 0x707f
+#define MATCH_SRLI 0x5013
+#define MASK_SRLI 0xfc00707f
+#define MATCH_SRAI 0x40005013
+#define MASK_SRAI 0xfc00707f
+#define MATCH_ORI 0x6013
+#define MASK_ORI 0x707f
+#define MATCH_ANDI 0x7013
+#define MASK_ANDI 0x707f
+#define MATCH_ADD 0x33
+#define MASK_ADD 0xfe00707f
+#define MATCH_SUB 0x40000033
+#define MASK_SUB 0xfe00707f
+#define MATCH_SLL 0x1033
+#define MASK_SLL 0xfe00707f
+#define MATCH_SLT 0x2033
+#define MASK_SLT 0xfe00707f
+#define MATCH_SLTU 0x3033
+#define MASK_SLTU 0xfe00707f
+#define MATCH_XOR 0x4033
+#define MASK_XOR 0xfe00707f
+#define MATCH_SRL 0x5033
+#define MASK_SRL 0xfe00707f
+#define MATCH_SRA 0x40005033
+#define MASK_SRA 0xfe00707f
+#define MATCH_OR 0x6033
+#define MASK_OR 0xfe00707f
+#define MATCH_AND 0x7033
+#define MASK_AND 0xfe00707f
+#define MATCH_ADDIW 0x1b
+#define MASK_ADDIW 0x707f
+#define MATCH_SLLIW 0x101b
+#define MASK_SLLIW 0xfe00707f
+#define MATCH_SRLIW 0x501b
+#define MASK_SRLIW 0xfe00707f
+#define MATCH_SRAIW 0x4000501b
+#define MASK_SRAIW 0xfe00707f
+#define MATCH_ADDW 0x3b
+#define MASK_ADDW 0xfe00707f
+#define MATCH_SUBW 0x4000003b
+#define MASK_SUBW 0xfe00707f
+#define MATCH_SLLW 0x103b
+#define MASK_SLLW 0xfe00707f
+#define MATCH_SRLW 0x503b
+#define MASK_SRLW 0xfe00707f
+#define MATCH_SRAW 0x4000503b
+#define MASK_SRAW 0xfe00707f
+#define MATCH_LB 0x3
+#define MASK_LB 0x707f
+#define MATCH_LH 0x1003
+#define MASK_LH 0x707f
+#define MATCH_LW 0x2003
+#define MASK_LW 0x707f
+#define MATCH_LD 0x3003
+#define MASK_LD 0x707f
+#define MATCH_LBU 0x4003
+#define MASK_LBU 0x707f
+#define MATCH_LHU 0x5003
+#define MASK_LHU 0x707f
+#define MATCH_LWU 0x6003
+#define MASK_LWU 0x707f
+#define MATCH_SB 0x23
+#define MASK_SB 0x707f
+#define MATCH_SH 0x1023
+#define MASK_SH 0x707f
+#define MATCH_SW 0x2023
+#define MASK_SW 0x707f
+#define MATCH_SD 0x3023
+#define MASK_SD 0x707f
+#define MATCH_FENCE 0xf
+#define MASK_FENCE 0x707f
+#define MATCH_FENCE_I 0x100f
+#define MASK_FENCE_I 0x707f
+#define MATCH_MUL 0x2000033
+#define MASK_MUL 0xfe00707f
+#define MATCH_MULH 0x2001033
+#define MASK_MULH 0xfe00707f
+#define MATCH_MULHSU 0x2002033
+#define MASK_MULHSU 0xfe00707f
+#define MATCH_MULHU 0x2003033
+#define MASK_MULHU 0xfe00707f
+#define MATCH_DIV 0x2004033
+#define MASK_DIV 0xfe00707f
+#define MATCH_DIVU 0x2005033
+#define MASK_DIVU 0xfe00707f
+#define MATCH_REM 0x2006033
+#define MASK_REM 0xfe00707f
+#define MATCH_REMU 0x2007033
+#define MASK_REMU 0xfe00707f
+#define MATCH_MULW 0x200003b
+#define MASK_MULW 0xfe00707f
+#define MATCH_DIVW 0x200403b
+#define MASK_DIVW 0xfe00707f
+#define MATCH_DIVUW 0x200503b
+#define MASK_DIVUW 0xfe00707f
+#define MATCH_REMW 0x200603b
+#define MASK_REMW 0xfe00707f
+#define MATCH_REMUW 0x200703b
+#define MASK_REMUW 0xfe00707f
+#define MATCH_AMOADD_W 0x202f
+#define MASK_AMOADD_W 0xf800707f
+#define MATCH_AMOXOR_W 0x2000202f
+#define MASK_AMOXOR_W 0xf800707f
+#define MATCH_AMOOR_W 0x4000202f
+#define MASK_AMOOR_W 0xf800707f
+#define MATCH_AMOAND_W 0x6000202f
+#define MASK_AMOAND_W 0xf800707f
+#define MATCH_AMOMIN_W 0x8000202f
+#define MASK_AMOMIN_W 0xf800707f
+#define MATCH_AMOMAX_W 0xa000202f
+#define MASK_AMOMAX_W 0xf800707f
+#define MATCH_AMOMINU_W 0xc000202f
+#define MASK_AMOMINU_W 0xf800707f
+#define MATCH_AMOMAXU_W 0xe000202f
+#define MASK_AMOMAXU_W 0xf800707f
+#define MATCH_AMOSWAP_W 0x800202f
+#define MASK_AMOSWAP_W 0xf800707f
+#define MATCH_LR_W 0x1000202f
+#define MASK_LR_W 0xf9f0707f
+#define MATCH_SC_W 0x1800202f
+#define MASK_SC_W 0xf800707f
+#define MATCH_AMOADD_D 0x302f
+#define MASK_AMOADD_D 0xf800707f
+#define MATCH_AMOXOR_D 0x2000302f
+#define MASK_AMOXOR_D 0xf800707f
+#define MATCH_AMOOR_D 0x4000302f
+#define MASK_AMOOR_D 0xf800707f
+#define MATCH_AMOAND_D 0x6000302f
+#define MASK_AMOAND_D 0xf800707f
+#define MATCH_AMOMIN_D 0x8000302f
+#define MASK_AMOMIN_D 0xf800707f
+#define MATCH_AMOMAX_D 0xa000302f
+#define MASK_AMOMAX_D 0xf800707f
+#define MATCH_AMOMINU_D 0xc000302f
+#define MASK_AMOMINU_D 0xf800707f
+#define MATCH_AMOMAXU_D 0xe000302f
+#define MASK_AMOMAXU_D 0xf800707f
+#define MATCH_AMOSWAP_D 0x800302f
+#define MASK_AMOSWAP_D 0xf800707f
+#define MATCH_LR_D 0x1000302f
+#define MASK_LR_D 0xf9f0707f
+#define MATCH_SC_D 0x1800302f
+#define MASK_SC_D 0xf800707f
+#define MATCH_ECALL 0x73
+#define MASK_ECALL 0xffffffff
+#define MATCH_EBREAK 0x100073
+#define MASK_EBREAK 0xffffffff
+#define MATCH_URET 0x200073
+#define MASK_URET 0xffffffff
+#define MATCH_SRET 0x10200073
+#define MASK_SRET 0xffffffff
+#define MATCH_HRET 0x20200073
+#define MASK_HRET 0xffffffff
+#define MATCH_MRET 0x30200073
+#define MASK_MRET 0xffffffff
+#define MATCH_DRET 0x7b200073
+#define MASK_DRET 0xffffffff
+#define MATCH_SFENCE_VMA 0x12000073
+#define MASK_SFENCE_VMA 0xfe007fff
+#define MATCH_WFI 0x10500073
+#define MASK_WFI 0xffffffff
+#define MATCH_CSRRW 0x1073
+#define MASK_CSRRW 0x707f
+#define MATCH_CSRRS 0x2073
+#define MASK_CSRRS 0x707f
+#define MATCH_CSRRC 0x3073
+#define MASK_CSRRC 0x707f
+#define MATCH_CSRRWI 0x5073
+#define MASK_CSRRWI 0x707f
+#define MATCH_CSRRSI 0x6073
+#define MASK_CSRRSI 0x707f
+#define MATCH_CSRRCI 0x7073
+#define MASK_CSRRCI 0x707f
+#define MATCH_FADD_S 0x53
+#define MASK_FADD_S 0xfe00007f
+#define MATCH_FSUB_S 0x8000053
+#define MASK_FSUB_S 0xfe00007f
+#define MATCH_FMUL_S 0x10000053
+#define MASK_FMUL_S 0xfe00007f
+#define MATCH_FDIV_S 0x18000053
+#define MASK_FDIV_S 0xfe00007f
+#define MATCH_FSGNJ_S 0x20000053
+#define MASK_FSGNJ_S 0xfe00707f
+#define MATCH_FSGNJN_S 0x20001053
+#define MASK_FSGNJN_S 0xfe00707f
+#define MATCH_FSGNJX_S 0x20002053
+#define MASK_FSGNJX_S 0xfe00707f
+#define MATCH_FMIN_S 0x28000053
+#define MASK_FMIN_S 0xfe00707f
+#define MATCH_FMAX_S 0x28001053
+#define MASK_FMAX_S 0xfe00707f
+#define MATCH_FSQRT_S 0x58000053
+#define MASK_FSQRT_S 0xfff0007f
+#define MATCH_FADD_D 0x2000053
+#define MASK_FADD_D 0xfe00007f
+#define MATCH_FSUB_D 0xa000053
+#define MASK_FSUB_D 0xfe00007f
+#define MATCH_FMUL_D 0x12000053
+#define MASK_FMUL_D 0xfe00007f
+#define MATCH_FDIV_D 0x1a000053
+#define MASK_FDIV_D 0xfe00007f
+#define MATCH_FSGNJ_D 0x22000053
+#define MASK_FSGNJ_D 0xfe00707f
+#define MATCH_FSGNJN_D 0x22001053
+#define MASK_FSGNJN_D 0xfe00707f
+#define MATCH_FSGNJX_D 0x22002053
+#define MASK_FSGNJX_D 0xfe00707f
+#define MATCH_FMIN_D 0x2a000053
+#define MASK_FMIN_D 0xfe00707f
+#define MATCH_FMAX_D 0x2a001053
+#define MASK_FMAX_D 0xfe00707f
+#define MATCH_FCVT_S_D 0x40100053
+#define MASK_FCVT_S_D 0xfff0007f
+#define MATCH_FCVT_D_S 0x42000053
+#define MASK_FCVT_D_S 0xfff0007f
+#define MATCH_FSQRT_D 0x5a000053
+#define MASK_FSQRT_D 0xfff0007f
+#define MATCH_FADD_Q 0x6000053
+#define MASK_FADD_Q 0xfe00007f
+#define MATCH_FSUB_Q 0xe000053
+#define MASK_FSUB_Q 0xfe00007f
+#define MATCH_FMUL_Q 0x16000053
+#define MASK_FMUL_Q 0xfe00007f
+#define MATCH_FDIV_Q 0x1e000053
+#define MASK_FDIV_Q 0xfe00007f
+#define MATCH_FSGNJ_Q 0x26000053
+#define MASK_FSGNJ_Q 0xfe00707f
+#define MATCH_FSGNJN_Q 0x26001053
+#define MASK_FSGNJN_Q 0xfe00707f
+#define MATCH_FSGNJX_Q 0x26002053
+#define MASK_FSGNJX_Q 0xfe00707f
+#define MATCH_FMIN_Q 0x2e000053
+#define MASK_FMIN_Q 0xfe00707f
+#define MATCH_FMAX_Q 0x2e001053
+#define MASK_FMAX_Q 0xfe00707f
+#define MATCH_FCVT_S_Q 0x40300053
+#define MASK_FCVT_S_Q 0xfff0007f
+#define MATCH_FCVT_Q_S 0x46000053
+#define MASK_FCVT_Q_S 0xfff0007f
+#define MATCH_FCVT_D_Q 0x42300053
+#define MASK_FCVT_D_Q 0xfff0007f
+#define MATCH_FCVT_Q_D 0x46100053
+#define MASK_FCVT_Q_D 0xfff0007f
+#define MATCH_FSQRT_Q 0x5e000053
+#define MASK_FSQRT_Q 0xfff0007f
+#define MATCH_FLE_S 0xa0000053
+#define MASK_FLE_S 0xfe00707f
+#define MATCH_FLT_S 0xa0001053
+#define MASK_FLT_S 0xfe00707f
+#define MATCH_FEQ_S 0xa0002053
+#define MASK_FEQ_S 0xfe00707f
+#define MATCH_FLE_D 0xa2000053
+#define MASK_FLE_D 0xfe00707f
+#define MATCH_FLT_D 0xa2001053
+#define MASK_FLT_D 0xfe00707f
+#define MATCH_FEQ_D 0xa2002053
+#define MASK_FEQ_D 0xfe00707f
+#define MATCH_FLE_Q 0xa6000053
+#define MASK_FLE_Q 0xfe00707f
+#define MATCH_FLT_Q 0xa6001053
+#define MASK_FLT_Q 0xfe00707f
+#define MATCH_FEQ_Q 0xa6002053
+#define MASK_FEQ_Q 0xfe00707f
+#define MATCH_FCVT_W_S 0xc0000053
+#define MASK_FCVT_W_S 0xfff0007f
+#define MATCH_FCVT_WU_S 0xc0100053
+#define MASK_FCVT_WU_S 0xfff0007f
+#define MATCH_FCVT_L_S 0xc0200053
+#define MASK_FCVT_L_S 0xfff0007f
+#define MATCH_FCVT_LU_S 0xc0300053
+#define MASK_FCVT_LU_S 0xfff0007f
+#define MATCH_FMV_X_S 0xe0000053
+#define MASK_FMV_X_S 0xfff0707f
+#define MATCH_FCLASS_S 0xe0001053
+#define MASK_FCLASS_S 0xfff0707f
+#define MATCH_FCVT_W_D 0xc2000053
+#define MASK_FCVT_W_D 0xfff0007f
+#define MATCH_FCVT_WU_D 0xc2100053
+#define MASK_FCVT_WU_D 0xfff0007f
+#define MATCH_FCVT_L_D 0xc2200053
+#define MASK_FCVT_L_D 0xfff0007f
+#define MATCH_FCVT_LU_D 0xc2300053
+#define MASK_FCVT_LU_D 0xfff0007f
+#define MATCH_FMV_X_D 0xe2000053
+#define MASK_FMV_X_D 0xfff0707f
+#define MATCH_FCLASS_D 0xe2001053
+#define MASK_FCLASS_D 0xfff0707f
+#define MATCH_FCVT_W_Q 0xc6000053
+#define MASK_FCVT_W_Q 0xfff0007f
+#define MATCH_FCVT_WU_Q 0xc6100053
+#define MASK_FCVT_WU_Q 0xfff0007f
+#define MATCH_FCVT_L_Q 0xc6200053
+#define MASK_FCVT_L_Q 0xfff0007f
+#define MATCH_FCVT_LU_Q 0xc6300053
+#define MASK_FCVT_LU_Q 0xfff0007f
+#define MATCH_FMV_X_Q 0xe6000053
+#define MASK_FMV_X_Q 0xfff0707f
+#define MATCH_FCLASS_Q 0xe6001053
+#define MASK_FCLASS_Q 0xfff0707f
+#define MATCH_FCVT_S_W 0xd0000053
+#define MASK_FCVT_S_W 0xfff0007f
+#define MATCH_FCVT_S_WU 0xd0100053
+#define MASK_FCVT_S_WU 0xfff0007f
+#define MATCH_FCVT_S_L 0xd0200053
+#define MASK_FCVT_S_L 0xfff0007f
+#define MATCH_FCVT_S_LU 0xd0300053
+#define MASK_FCVT_S_LU 0xfff0007f
+#define MATCH_FMV_S_X 0xf0000053
+#define MASK_FMV_S_X 0xfff0707f
+#define MATCH_FCVT_D_W 0xd2000053
+#define MASK_FCVT_D_W 0xfff0007f
+#define MATCH_FCVT_D_WU 0xd2100053
+#define MASK_FCVT_D_WU 0xfff0007f
+#define MATCH_FCVT_D_L 0xd2200053
+#define MASK_FCVT_D_L 0xfff0007f
+#define MATCH_FCVT_D_LU 0xd2300053
+#define MASK_FCVT_D_LU 0xfff0007f
+#define MATCH_FMV_D_X 0xf2000053
+#define MASK_FMV_D_X 0xfff0707f
+#define MATCH_FCVT_Q_W 0xd6000053
+#define MASK_FCVT_Q_W 0xfff0007f
+#define MATCH_FCVT_Q_WU 0xd6100053
+#define MASK_FCVT_Q_WU 0xfff0007f
+#define MATCH_FCVT_Q_L 0xd6200053
+#define MASK_FCVT_Q_L 0xfff0007f
+#define MATCH_FCVT_Q_LU 0xd6300053
+#define MASK_FCVT_Q_LU 0xfff0007f
+#define MATCH_FMV_Q_X 0xf6000053
+#define MASK_FMV_Q_X 0xfff0707f
+#define MATCH_FLW 0x2007
+#define MASK_FLW 0x707f
+#define MATCH_FLD 0x3007
+#define MASK_FLD 0x707f
+#define MATCH_FLQ 0x4007
+#define MASK_FLQ 0x707f
+#define MATCH_FSW 0x2027
+#define MASK_FSW 0x707f
+#define MATCH_FSD 0x3027
+#define MASK_FSD 0x707f
+#define MATCH_FSQ 0x4027
+#define MASK_FSQ 0x707f
+#define MATCH_FMADD_S 0x43
+#define MASK_FMADD_S 0x600007f
+#define MATCH_FMSUB_S 0x47
+#define MASK_FMSUB_S 0x600007f
+#define MATCH_FNMSUB_S 0x4b
+#define MASK_FNMSUB_S 0x600007f
+#define MATCH_FNMADD_S 0x4f
+#define MASK_FNMADD_S 0x600007f
+#define MATCH_FMADD_D 0x2000043
+#define MASK_FMADD_D 0x600007f
+#define MATCH_FMSUB_D 0x2000047
+#define MASK_FMSUB_D 0x600007f
+#define MATCH_FNMSUB_D 0x200004b
+#define MASK_FNMSUB_D 0x600007f
+#define MATCH_FNMADD_D 0x200004f
+#define MASK_FNMADD_D 0x600007f
+#define MATCH_FMADD_Q 0x6000043
+#define MASK_FMADD_Q 0x600007f
+#define MATCH_FMSUB_Q 0x6000047
+#define MASK_FMSUB_Q 0x600007f
+#define MATCH_FNMSUB_Q 0x600004b
+#define MASK_FNMSUB_Q 0x600007f
+#define MATCH_FNMADD_Q 0x600004f
+#define MASK_FNMADD_Q 0x600007f
+#define MATCH_C_NOP 0x1
+#define MASK_C_NOP 0xffff
+#define MATCH_C_ADDI16SP 0x6101
+#define MASK_C_ADDI16SP 0xef83
+#define MATCH_C_JR 0x8002
+#define MASK_C_JR 0xf07f
+#define MATCH_C_JALR 0x9002
+#define MASK_C_JALR 0xf07f
+#define MATCH_C_EBREAK 0x9002
+#define MASK_C_EBREAK 0xffff
+#define MATCH_C_LD 0x6000
+#define MASK_C_LD 0xe003
+#define MATCH_C_SD 0xe000
+#define MASK_C_SD 0xe003
+#define MATCH_C_ADDIW 0x2001
+#define MASK_C_ADDIW 0xe003
+#define MATCH_C_LDSP 0x6002
+#define MASK_C_LDSP 0xe003
+#define MATCH_C_SDSP 0xe002
+#define MASK_C_SDSP 0xe003
+#define MATCH_C_ADDI4SPN 0x0
+#define MASK_C_ADDI4SPN 0xe003
+#define MATCH_C_FLD 0x2000
+#define MASK_C_FLD 0xe003
+#define MATCH_C_LW 0x4000
+#define MASK_C_LW 0xe003
+#define MATCH_C_FLW 0x6000
+#define MASK_C_FLW 0xe003
+#define MATCH_C_FSD 0xa000
+#define MASK_C_FSD 0xe003
+#define MATCH_C_SW 0xc000
+#define MASK_C_SW 0xe003
+#define MATCH_C_FSW 0xe000
+#define MASK_C_FSW 0xe003
+#define MATCH_C_ADDI 0x1
+#define MASK_C_ADDI 0xe003
+#define MATCH_C_JAL 0x2001
+#define MASK_C_JAL 0xe003
+#define MATCH_C_LI 0x4001
+#define MASK_C_LI 0xe003
+#define MATCH_C_LUI 0x6001
+#define MASK_C_LUI 0xe003
+#define MATCH_C_SRLI 0x8001
+#define MASK_C_SRLI 0xec03
+#define MATCH_C_SRAI 0x8401
+#define MASK_C_SRAI 0xec03
+#define MATCH_C_ANDI 0x8801
+#define MASK_C_ANDI 0xec03
+#define MATCH_C_SUB 0x8c01
+#define MASK_C_SUB 0xfc63
+#define MATCH_C_XOR 0x8c21
+#define MASK_C_XOR 0xfc63
+#define MATCH_C_OR 0x8c41
+#define MASK_C_OR 0xfc63
+#define MATCH_C_AND 0x8c61
+#define MASK_C_AND 0xfc63
+#define MATCH_C_SUBW 0x9c01
+#define MASK_C_SUBW 0xfc63
+#define MATCH_C_ADDW 0x9c21
+#define MASK_C_ADDW 0xfc63
+#define MATCH_C_J 0xa001
+#define MASK_C_J 0xe003
+#define MATCH_C_BEQZ 0xc001
+#define MASK_C_BEQZ 0xe003
+#define MATCH_C_BNEZ 0xe001
+#define MASK_C_BNEZ 0xe003
+#define MATCH_C_SLLI 0x2
+#define MASK_C_SLLI 0xe003
+#define MATCH_C_FLDSP 0x2002
+#define MASK_C_FLDSP 0xe003
+#define MATCH_C_LWSP 0x4002
+#define MASK_C_LWSP 0xe003
+#define MATCH_C_FLWSP 0x6002
+#define MASK_C_FLWSP 0xe003
+#define MATCH_C_MV 0x8002
+#define MASK_C_MV 0xf003
+#define MATCH_C_ADD 0x9002
+#define MASK_C_ADD 0xf003
+#define MATCH_C_FSDSP 0xa002
+#define MASK_C_FSDSP 0xe003
+#define MATCH_C_SWSP 0xc002
+#define MASK_C_SWSP 0xe003
+#define MATCH_C_FSWSP 0xe002
+#define MASK_C_FSWSP 0xe003
+#define MATCH_CUSTOM0 0xb
+#define MASK_CUSTOM0 0x707f
+#define MATCH_CUSTOM0_RS1 0x200b
+#define MASK_CUSTOM0_RS1 0x707f
+#define MATCH_CUSTOM0_RS1_RS2 0x300b
+#define MASK_CUSTOM0_RS1_RS2 0x707f
+#define MATCH_CUSTOM0_RD 0x400b
+#define MASK_CUSTOM0_RD 0x707f
+#define MATCH_CUSTOM0_RD_RS1 0x600b
+#define MASK_CUSTOM0_RD_RS1 0x707f
+#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
+#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM1 0x2b
+#define MASK_CUSTOM1 0x707f
+#define MATCH_CUSTOM1_RS1 0x202b
+#define MASK_CUSTOM1_RS1 0x707f
+#define MATCH_CUSTOM1_RS1_RS2 0x302b
+#define MASK_CUSTOM1_RS1_RS2 0x707f
+#define MATCH_CUSTOM1_RD 0x402b
+#define MASK_CUSTOM1_RD 0x707f
+#define MATCH_CUSTOM1_RD_RS1 0x602b
+#define MASK_CUSTOM1_RD_RS1 0x707f
+#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
+#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM2 0x5b
+#define MASK_CUSTOM2 0x707f
+#define MATCH_CUSTOM2_RS1 0x205b
+#define MASK_CUSTOM2_RS1 0x707f
+#define MATCH_CUSTOM2_RS1_RS2 0x305b
+#define MASK_CUSTOM2_RS1_RS2 0x707f
+#define MATCH_CUSTOM2_RD 0x405b
+#define MASK_CUSTOM2_RD 0x707f
+#define MATCH_CUSTOM2_RD_RS1 0x605b
+#define MASK_CUSTOM2_RD_RS1 0x707f
+#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
+#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM3 0x7b
+#define MASK_CUSTOM3 0x707f
+#define MATCH_CUSTOM3_RS1 0x207b
+#define MASK_CUSTOM3_RS1 0x707f
+#define MATCH_CUSTOM3_RS1_RS2 0x307b
+#define MASK_CUSTOM3_RS1_RS2 0x707f
+#define MATCH_CUSTOM3_RD 0x407b
+#define MASK_CUSTOM3_RD 0x707f
+#define MATCH_CUSTOM3_RD_RS1 0x607b
+#define MASK_CUSTOM3_RD_RS1 0x707f
+#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
+#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_SSTATUS 0x100
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_SBADADDR 0x143
+#define CSR_SIP 0x144
+#define CSR_SPTBR 0x180
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MBADADDR 0x343
+#define CSR_MIP 0x344
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_SUPERVISOR_ECALL 0x9
+#define CAUSE_HYPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#endif
+#ifdef DECLARE_INSN
+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
+DECLARE_INSN(or, MATCH_OR, MASK_OR)
+DECLARE_INSN(and, MATCH_AND, MASK_AND)
+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
+DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
+DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
+DECLARE_INSN(uret, MATCH_URET, MASK_URET)
+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(hret, MATCH_HRET, MASK_HRET)
+DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
+DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
+DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)
+DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
+DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)
+DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)
+DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)
+DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)
+DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)
+DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)
+DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)
+DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)
+DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)
+DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)
+DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)
+DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)
+DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)
+DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)
+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
+DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)
+DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)
+DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)
+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
+DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
+DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)
+DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)
+DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)
+DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)
+DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
+DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)
+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
+DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
+DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
+DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
+DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
+DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
+DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
+DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
+DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)
+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
+DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
+DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
+DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
+DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
+DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
+DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
+DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
+DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
+DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)
+DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
+DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
+DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
+DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
+DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
+DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
+DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
+DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
+DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
+DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
+DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
+DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
+DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
+DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)
+DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
+DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
+DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
+DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
+DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)
+DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
+DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)
+DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)
+DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)
+DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
+DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
+DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
+DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
+DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
+DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
+DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)
+DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
+DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)
+DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
+DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
+DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)
+DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
+DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)
+DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
+DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
+DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
+DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
+DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
+DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
+DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
+DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
+DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
+DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
+DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
+DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
+DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
+DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
+DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
+DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
+DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
+DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
+DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
+DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
+DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
+DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
+DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
+DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
+#endif
+#ifdef DECLARE_CSR
+DECLARE_CSR(fflags, CSR_FFLAGS)
+DECLARE_CSR(frm, CSR_FRM)
+DECLARE_CSR(fcsr, CSR_FCSR)
+DECLARE_CSR(cycle, CSR_CYCLE)
+DECLARE_CSR(time, CSR_TIME)
+DECLARE_CSR(instret, CSR_INSTRET)
+DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)
+DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)
+DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)
+DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)
+DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)
+DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)
+DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)
+DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)
+DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)
+DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)
+DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)
+DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)
+DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)
+DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)
+DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)
+DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)
+DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)
+DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)
+DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)
+DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)
+DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)
+DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)
+DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)
+DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)
+DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)
+DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)
+DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)
+DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)
+DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
+DECLARE_CSR(sstatus, CSR_SSTATUS)
+DECLARE_CSR(sie, CSR_SIE)
+DECLARE_CSR(stvec, CSR_STVEC)
+DECLARE_CSR(scounteren, CSR_SCOUNTEREN)
+DECLARE_CSR(sscratch, CSR_SSCRATCH)
+DECLARE_CSR(sepc, CSR_SEPC)
+DECLARE_CSR(scause, CSR_SCAUSE)
+DECLARE_CSR(sbadaddr, CSR_SBADADDR)
+DECLARE_CSR(sip, CSR_SIP)
+DECLARE_CSR(sptbr, CSR_SPTBR)
+DECLARE_CSR(mstatus, CSR_MSTATUS)
+DECLARE_CSR(misa, CSR_MISA)
+DECLARE_CSR(medeleg, CSR_MEDELEG)
+DECLARE_CSR(mideleg, CSR_MIDELEG)
+DECLARE_CSR(mie, CSR_MIE)
+DECLARE_CSR(mtvec, CSR_MTVEC)
+DECLARE_CSR(mcounteren, CSR_MCOUNTEREN)
+DECLARE_CSR(mscratch, CSR_MSCRATCH)
+DECLARE_CSR(mepc, CSR_MEPC)
+DECLARE_CSR(mcause, CSR_MCAUSE)
+DECLARE_CSR(mbadaddr, CSR_MBADADDR)
+DECLARE_CSR(mip, CSR_MIP)
+DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
+DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
+DECLARE_CSR(pmpcfg2, CSR_PMPCFG2)
+DECLARE_CSR(pmpcfg3, CSR_PMPCFG3)
+DECLARE_CSR(pmpaddr0, CSR_PMPADDR0)
+DECLARE_CSR(pmpaddr1, CSR_PMPADDR1)
+DECLARE_CSR(pmpaddr2, CSR_PMPADDR2)
+DECLARE_CSR(pmpaddr3, CSR_PMPADDR3)
+DECLARE_CSR(pmpaddr4, CSR_PMPADDR4)
+DECLARE_CSR(pmpaddr5, CSR_PMPADDR5)
+DECLARE_CSR(pmpaddr6, CSR_PMPADDR6)
+DECLARE_CSR(pmpaddr7, CSR_PMPADDR7)
+DECLARE_CSR(pmpaddr8, CSR_PMPADDR8)
+DECLARE_CSR(pmpaddr9, CSR_PMPADDR9)
+DECLARE_CSR(pmpaddr10, CSR_PMPADDR10)
+DECLARE_CSR(pmpaddr11, CSR_PMPADDR11)
+DECLARE_CSR(pmpaddr12, CSR_PMPADDR12)
+DECLARE_CSR(pmpaddr13, CSR_PMPADDR13)
+DECLARE_CSR(pmpaddr14, CSR_PMPADDR14)
+DECLARE_CSR(pmpaddr15, CSR_PMPADDR15)
+DECLARE_CSR(tselect, CSR_TSELECT)
+DECLARE_CSR(tdata1, CSR_TDATA1)
+DECLARE_CSR(tdata2, CSR_TDATA2)
+DECLARE_CSR(tdata3, CSR_TDATA3)
+DECLARE_CSR(dcsr, CSR_DCSR)
+DECLARE_CSR(dpc, CSR_DPC)
+DECLARE_CSR(dscratch, CSR_DSCRATCH)
+DECLARE_CSR(mcycle, CSR_MCYCLE)
+DECLARE_CSR(minstret, CSR_MINSTRET)
+DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)
+DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)
+DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)
+DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)
+DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)
+DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)
+DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)
+DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)
+DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)
+DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)
+DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)
+DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)
+DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)
+DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)
+DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)
+DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)
+DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)
+DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)
+DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)
+DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)
+DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)
+DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)
+DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)
+DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)
+DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)
+DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
+DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
+DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
+DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
+DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
+DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
+DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
+DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)
+DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)
+DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)
+DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)
+DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)
+DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)
+DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)
+DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)
+DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)
+DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)
+DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)
+DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)
+DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)
+DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)
+DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)
+DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)
+DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)
+DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)
+DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)
+DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)
+DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)
+DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)
+DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)
+DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)
+DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)
+DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)
+DECLARE_CSR(mvendorid, CSR_MVENDORID)
+DECLARE_CSR(marchid, CSR_MARCHID)
+DECLARE_CSR(mimpid, CSR_MIMPID)
+DECLARE_CSR(mhartid, CSR_MHARTID)
+DECLARE_CSR(cycleh, CSR_CYCLEH)
+DECLARE_CSR(timeh, CSR_TIMEH)
+DECLARE_CSR(instreth, CSR_INSTRETH)
+DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)
+DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)
+DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)
+DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)
+DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)
+DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)
+DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)
+DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)
+DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)
+DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)
+DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)
+DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)
+DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)
+DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)
+DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)
+DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)
+DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)
+DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)
+DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)
+DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)
+DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)
+DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)
+DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)
+DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)
+DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)
+DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)
+DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)
+DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)
+DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)
+DECLARE_CSR(mcycleh, CSR_MCYCLEH)
+DECLARE_CSR(minstreth, CSR_MINSTRETH)
+DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)
+DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)
+DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)
+DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)
+DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)
+DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)
+DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)
+DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)
+DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)
+DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)
+DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)
+DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)
+DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)
+DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)
+DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)
+DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)
+DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)
+DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)
+DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)
+DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)
+DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)
+DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)
+DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)
+DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)
+DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)
+DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)
+DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)
+DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)
+DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
+#endif
+#ifdef DECLARE_CAUSE
+DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
+DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
+DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
+DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
+DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
+DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
+DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
+DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
+DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
+DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
+DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
+DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
+DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
+DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
+DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_assert.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_assert.h
new file mode 100644
index 00000000..ebd70632
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_assert.h
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+#ifndef HAL_ASSERT_HEADER
+#define HAL_ASSERT_HEADER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * ASSERT() implementation.
+ ******************************************************************************/
+/* Disable assertions if we do not recognize the compiler. */
+#if defined ( __GNUC__ )
+#if defined(NDEBUG)
+#define ASSERT(CHECK)
+#else
+#define ASSERT(CHECK)\
+ do { \
+ if (!(CHECK)) \
+ { \
+ __asm volatile ("ebreak"); \
+ }\
+ } while(0);
+#endif /* NDEBUG check */
+#endif /* compiler check */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_ASSERT_HEADER */
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_axiswitch.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_axiswitch.c
new file mode 100644
index 00000000..c324cdbd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_axiswitch.c
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_axiswitch.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS AXI switch configuration
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*Returns the value of AXI_HW_CFG_REG register*/
+uint32_t MSS_AXISW_get_hwcfg(void)
+{
+ return (AXISW->HWCFG);
+}
+
+/*Returns the value of AXI_VERSION_ID_REG register*/
+uint32_t MSS_AXISW_get_vid(void)
+{
+ return (AXISW->VID);
+}
+
+/*Performs write operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+
+
+ Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+
+ Burstiness peak rate and transaction rate can be configured using other APIs.
+
+ data: QoS value to be programmed
+ return value: As received form AXI_ERR_BIT in CMD register.
+
+ * */
+uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t data)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = data & AXISW_DATA_QOSVAL_MASK; /*only valid values of bits[3:0]*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_QOS_VAL |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ * Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+ *
+ * returns the data returned by AXI SWITCH read operation for QoS command
+ *
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ */
+uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t* rd_data)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) | (MSS_AXISW_QOS_VAL) | AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *rd_data = AXISW->DATA & AXISW_DATA_QOSVAL_MASK;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the peak rate and transaction rate value for the given master port
+ read/write address channel
+
+ NOTE: Peak rate and transaction rate are programmed simultaneously in one command.
+ So we must make sure that both desired valid values must be provided.
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t peak_rate,
+ mss_axisw_rate_t xct_rate)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+ AXISW->DATA = ((peak_rate) << AXISW_DATA_PEAKRT) | ((xct_rate) << AXISW_DATA_XCTRT) ;
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the peak rate and transaction rate value for the given master port
+read/write address channel
+peak_rate: returns the value of peak rate
+xct_rate: returns the value of transaction rate
+return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t* peak_rate,
+ mss_axisw_rate_t* xct_rate)
+{
+ uint32_t temp = 0u;
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ temp = AXISW->DATA;
+
+ *peak_rate = (temp & AXISW_DATA_PEAKRT_MASK) >> AXISW_DATA_PEAKRT;
+ *xct_rate = (temp & AXISW_DATA_XCTRT_MASK) >> AXISW_DATA_XCTRT;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the burstiness value for the given master port read/write address channel
+
+burstiness_val: burstiness value to be programmed
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+regulator_en: QoS regulator Enable 1= enable, 0 = disable
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t burstiness_val,
+ uint32_t regulator_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ /*Write burstiness value and enable burstiness regulator.
+ * Burstiness_val=0 is not valid.
+ Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1*/
+
+ if(burstiness_val == 0)
+ {
+ return -1;
+ }
+ else
+ {
+ AXISW->DATA = ((burstiness_val - 1u) << AXISW_DATA_BURSTI) | (regulator_en & 0x01);
+ }
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the burstiness value for the given master port read/write address channel
+
+burstiness_val: Return parameter bit 23:16 shows the burstiness value.
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t* burstiness_val)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *burstiness_val = ((AXISW->DATA & AXISW_DATA_BURSTI_MASK) >> AXISW_DATA_BURSTI) + 1u;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t slave_ready_en)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = slave_ready_en & 0x01; /*only valid value of bit0*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_SLV_RDY |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ *
+ * slave_ready_en: returns the data returned by AXI SWITCH read operation for slave ready command
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ *
+ */
+uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t* slave_ready_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_SLV_RDY) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *slave_ready_en = AXISW->DATA & 0x01;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_axiswitch.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_axiswitch.h
new file mode 100644
index 00000000..437ea9bd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_axiswitch.h
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef __MSS_AXISW_H_
+#define __MSS_AXISW_H_ 1
+
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+
+ */
+
+typedef enum {
+ MSS_AXISW_FIC0_RD_CHAN = 0x000,
+ MSS_AXISW_FIC0_WR_CHAN,
+ MSS_AXISW_FIC1_RD_CHAN,
+ MSS_AXISW_FIC1_WR_CHAN,
+ MSS_AXISW_FIC2_RD_CHAN,
+ MSS_AXISW_FIC2_WR_CHAN,
+ MSS_AXISW_ATHENA_RD_CHAN,
+ MSS_AXISW_ATHENA_WR_CHAN,
+ MSS_AXISW_GEM0_RD_CHAN,
+ MSS_AXISW_GEM0_WR_CHAN,
+ MSS_AXISW_GEM1_RD_CHAN,
+ MSS_AXISW_GEM1_WR_CHAN,
+ MSS_AXISW_MMC_RD_CHAN,
+ MSS_AXISW_MMC_WR_CHAN,
+ MSS_AXISW_USB_RD_CHAN,
+ MSS_AXISW_USB_WR_CHAN,
+ MSS_AXISW_SCB_RD_CHAN,
+ MSS_AXISW_SCB_WR_CHAN,
+ MSS_AXISW_CPLEX_D0_RD_CHAN,
+ MSS_AXISW_CPLEX_D0_WR_CHAN,
+ MSS_AXISW_CPLEX_D1_RD_CHAN,
+ MSS_AXISW_CPLEX_D1_WR_CHAN,
+ MSS_AXISW_CPLEX_F0_RD_CHAN,
+ MSS_AXISW_CPLEX_F0_WR_CHAN,
+ MSS_AXISW_CPLEX_F1_RD_CHAN,
+ MSS_AXISW_CPLEX_F1_WR_CHAN,
+ MSS_AXISW_CPLEX_NC_RD_CHAN,
+ MSS_AXISW_CPLEX_NC_WR_CHAN,
+ MSS_AXISW_TRACE_RD_CHAN,
+ MSS_AXISW_TRACE_WR_CHAN,
+} mss_axisw_mport_t;
+
+
+typedef enum {
+ MSS_AXISW_BURSTINESS_EN = 0x00,
+ MSS_AXISW_PEAKRT_XCTRT,
+ MSS_AXISW_QOS_VAL,
+ MSS_AXISW_SLV_RDY,
+} mss_axisw_cmd_t;
+
+typedef enum {
+ MSS_AXISW_MASTER_RD_CHAN = 0x00,
+ MSS_AXISW_MASTER_WR_CHAN = 0x01,
+} mss_axisw_mchan_t;
+
+/*
+The Peak rate and transaction rates are encoded as follows.
+1000_0000_0000 1/2
+0100_0000_0000 1/4
+0010_0000_0000 1/8
+0001_0000_0000 1/16
+0000_1000_0000 1/32
+0000_0100_0000 1/64
+0000_0010_0000 1/128
+0000_0001_0000 1/256
+0000_0000_1000 1/512
+0000_0000_0100 1/1024
+0000_0000_0010 1/2048
+0000_0000_0001 1/4096
+
+Programming the transaction rate as 0000_0000_0000 disables token generation and
+traffic is not regulated based on the tokens.
+
+Programming the peak rate as 0000_0000_0000 disables the peak rate control logic and
+traffic is not regulated by the peak rate logic.
+*/
+typedef enum {
+ MSS_AXISW_TXNRATE_BY4096 = 0x001,
+ MSS_AXISW_TXNRATE_BY2098 = 0x002,
+ MSS_AXISW_TXNRATE_BY1024 = 0x004,
+ MSS_AXISW_TXNRATE_BY512 = 0x008,
+ MSS_AXISW_TXNRATE_BY256 = 0x010,
+ MSS_AXISW_TXNRATE_BY128 = 0x020,
+ MSS_AXISW_TXNRATE_BY64 = 0x040,
+ MSS_AXISW_TXNRATE_BY32 = 0x080,
+ MSS_AXISW_TXNRATE_BY16 = 0x100,
+ MSS_AXISW_TXNRATE_BY8 = 0x200,
+ MSS_AXISW_TXNRATE_BY4 = 0x400,
+ MSS_AXISW_TXNRATE_BY2 = 0x800,
+ MSS_AXISW_TXNRATE_DISABLE = 0x0,
+} mss_axisw_rate_t;
+
+#define AXISW_CMD_EN 31U
+#define AXISW_CMD_EN_MASK (uint32_t)(0x01U << AXISW_CMD_EN)
+
+#define AXISW_CMD_RW 30U
+#define AXISW_CMD_RW_MASK (uint32_t)(0x01U << AXISW_CMD_RW)
+
+#define AXISW_CMD_SWRST 29U
+#define AXISW_CMD_SWRST_MASK (uint32_t)(0x01U << AXISW_CMD_SWRST)
+
+#define AXISW_CMD_ERR 28U
+#define AXISW_CMD_ERR_MASK (uint32_t)(0x01U << AXISW_CMD_ERR)
+
+//#define AXISW_CMD_MPORT 8U
+//#define AXISW_CMD_MPORT_MASK (0x0F << AXISW_CMD_MPORT)
+
+#define AXISW_CMD_RWCHAN 7U
+#define AXISW_CMD_RWCHAN_MASK (uint32_t)(0x1F << AXISW_CMD_RWCHAN)
+
+#define AXISW_CMD_CMD 0U
+#define AXISW_CMD_CMD_MASK (0x01U << AXISW_CMD_CMD)
+
+#define AXISW_DATA_PEAKRT 20U
+#define AXISW_DATA_PEAKRT_MASK (0xFFFU << AXISW_DATA_PEAKRT)
+
+#define AXISW_DATA_XCTRT 4U
+#define AXISW_DATA_XCTRT_MASK (0xFFFU << AXISW_DATA_XCTRT)
+
+#define AXISW_DATA_BURSTI 16U
+#define AXISW_DATA_BURSTI_MASK (0xFFU << AXISW_DATA_BURSTI)
+
+#define AXISW_DATA_QOSVAL 0U
+#define AXISW_DATA_QOSVAL_MASK (0xFU << AXISW_DATA_QOSVAL)
+
+typedef struct
+{
+ __IO uint32_t VID;
+ __IO uint32_t HWCFG;
+ __IO uint32_t CMD;
+ __IO uint32_t DATA;
+} AXISW_TypeDef;
+
+
+#define AXISW ((AXISW_TypeDef*)0x20004000UL)
+
+
+uint32_t MSS_AXISW_get_hwcfg(void);
+uint32_t MSS_AXISW_get_vid(void);
+uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t data);
+uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t* rd_data);
+uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t peak_rate,
+ mss_axisw_rate_t xct_rate);
+uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t* peak_rate,
+ mss_axisw_rate_t* xct_rate);
+int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t burstiness_val,
+ uint32_t regulator_en);
+uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t* burstiness_val);
+uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t slave_ready_en);
+uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t* slave_ready_en);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSS_AXISW_H_ */
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_clint.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_clint.c
new file mode 100644
index 00000000..cd1558ac
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_clint.c
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_clint.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief CLINT access data structures and functions.
+ *
+ */
+#include
+#include "mpfs_hal/mss_hal.h"
+
+static uint64_t g_systick_increment[5] = {0ULL,0ULL,0ULL,0ULL,0ULL};
+
+/**
+ * call once at startup
+ * @return
+ */
+void reset_mtime(void)
+{
+#if ROLLOVER_TEST
+ CLINT->MTIME = 0xFFFFFFFFFFFFF000ULL;
+#else
+ CLINT->MTIME = 0ULL;
+#endif
+}
+
+/**
+ * readmtime
+ * @return mtime
+ */
+uint64_t readmtime(void)
+{
+ return (CLINT->MTIME);
+}
+
+/**
+ * Configure system tick
+ * @return SUCCESS or FAIL
+ */
+uint32_t SysTick_Config(void)
+{
+ const uint32_t tick_rate[5] = {HART0_TICK_RATE_MS, HART1_TICK_RATE_MS ,HART2_TICK_RATE_MS ,HART3_TICK_RATE_MS ,HART4_TICK_RATE_MS};
+ volatile uint32_t ret_val = ERROR;
+
+ uint64_t mhart_id = read_csr(mhartid);
+
+ /*
+ * We are assuming the tick rate is in milli-seconds
+ *
+ * convert RTC frequency into milliseconds and multiple by the tick rate
+ *
+ */
+
+ g_systick_increment[mhart_id] = ((LIBERO_SETTING_MSS_RTC_TOGGLE_CLK/1000U) * tick_rate[mhart_id]);
+
+ if (g_systick_increment[mhart_id] > 0ULL)
+ {
+
+ CLINT->MTIMECMP[mhart_id] = CLINT->MTIME + g_systick_increment[mhart_id];
+
+ set_csr(mie, MIP_MTIP); /* mie Register - Machine Timer Interrupt Enable */
+
+ __enable_irq();
+
+ ret_val = SUCCESS;
+ }
+
+ return (ret_val);
+}
+
+/**
+ * Disable system tick interrupt
+ */
+void disable_systick(void)
+{
+ clear_csr(mie, MIP_MTIP); /* mie Register - Machine Timer Interrupt Enable */
+ return;
+}
+
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for machine timer interrupts.
+ */
+void handle_m_timer_interrupt(void)
+{
+
+ volatile uint64_t hart_id = read_csr(mhartid);
+ volatile uint32_t error_loop;
+ clear_csr(mie, MIP_MTIP);
+
+ switch(hart_id)
+ {
+ case 0U:
+ SysTick_Handler_h0_IRQHandler();
+ break;
+ case 1U:
+ SysTick_Handler_h1_IRQHandler();
+ break;
+ case 2U:
+ SysTick_Handler_h2_IRQHandler();
+ break;
+ case 3U:
+ SysTick_Handler_h3_IRQHandler();
+ break;
+ case 4U:
+ SysTick_Handler_h4_IRQHandler();
+ break;
+ default:
+ while (hart_id != 0U)
+ {
+ error_loop++;
+ }
+ break;
+ }
+
+ CLINT->MTIMECMP[read_csr(mhartid)] = CLINT->MTIME + g_systick_increment[hart_id];
+
+ set_csr(mie, MIP_MTIP);
+
+}
+
+
+/**
+ *
+ */
+void handle_m_soft_interrupt(void)
+{
+ volatile uint64_t hart_id = read_csr(mhartid);
+ volatile uint32_t error_loop;
+
+ switch(hart_id)
+ {
+ case 0U:
+ Software_h0_IRQHandler();
+ break;
+ case 1U:
+ Software_h1_IRQHandler();
+ break;
+ case 2U:
+ Software_h2_IRQHandler();
+ break;
+ case 3U:
+ Software_h3_IRQHandler();
+ break;
+ case 4U:
+ Software_h4_IRQHandler();
+ break;
+ default:
+ while (hart_id != 0U)
+ {
+ error_loop++;
+ }
+ break;
+ }
+
+ /*Clear software interrupt*/
+ clear_soft_interrupt();
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_clint.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_clint.h
new file mode 100644
index 00000000..86b4a1cd
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_clint.h
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_clint.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief CLINT access data structures and functions.
+ *
+ */
+#ifndef MSS_CLINT_H
+#define MSS_CLINT_H
+
+#include
+#include "encoding.h"
+#include "atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTC_PRESCALER 100U
+#define SUCCESS 0U
+#define ERROR 1U
+
+
+/*==============================================================================
+ * CLINT: Core Local Interrupter
+ */
+typedef struct CLINT_Type_t
+{
+ volatile uint32_t MSIP[5];
+ volatile uint32_t reserved1[(0x4000U - 0x14U)/4U];
+ volatile uint64_t MTIMECMP[5]; /* mtime compare value for each hart. When mtime equals this value, interrupt is generated for particular hart */
+ volatile uint32_t reserved2[((0xbff8U - 0x4028U)/4U)];
+ volatile uint64_t MTIME; /* contains the current mtime value */
+} CLINT_Type;
+
+#define CLINT ((CLINT_Type *)CLINT_BASE)
+
+
+/*==============================================================================
+ * The function raise_soft_interrupt() raises a synchronous software interrupt by
+ * writing into the MSIP register.
+ */
+static inline void raise_soft_interrupt(unsigned long hart_id)
+{
+ /*You need to make sure that the global interrupt is enabled*/
+ /*Note: set_csr(mie, MIP_MSIP) needs to be set on hart you are setting sw interrupt */
+ CLINT->MSIP[hart_id] = 0x01U; /*raise soft interrupt for hart(x) where x== hart ID*/
+ mb();
+}
+
+/*==============================================================================
+ * The function clear_soft_interrupt() clears a synchronous software interrupt by
+ * clearing the MSIP register.
+ */
+static inline void clear_soft_interrupt(void)
+{
+ volatile uint32_t reg;
+ uint64_t hart_id = read_csr(mhartid);
+ CLINT->MSIP[hart_id] = 0x00U; /*clear soft interrupt for hart0*/
+ reg = CLINT->MSIP[hart_id]; /* we read back to make sure it has been written before moving on */
+ /* todo: verify line above guaranteed and best way to achieve result */
+ (void)reg; /* use reg to avoid compiler warning */
+}
+
+/*
+ * return mtime
+ */
+uint64_t readmtime(void);
+
+/**
+ * call once at startup
+ * @return
+ */
+void reset_mtime(void);
+
+/**
+ * Configure system tick
+ * @return SUCCESS or FAIL
+ */
+uint32_t SysTick_Config(void);
+
+/**
+ * Disable system tick interrupt
+ */
+void disable_systick(void);
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for machine timer interrupts.
+ */
+void handle_m_timer_interrupt(void);
+
+/**
+ *
+ */
+void handle_m_soft_interrupt(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_CLINT_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_h2f.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_h2f.c
new file mode 100644
index 00000000..2a1c10b5
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_h2f.c
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_h2f.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief H2F access data structures and functions.
+ *
+ */
+#include "mss_plic.h"
+#include "mss_h2f.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+#define H2F_MAPPING_INVALID 255U
+
+/*==============================================================================
+ * H2F_int_mapping, source to H2F output lines
+ * The internal interrupt are multiplexed to fabric I/O lines.
+ * That is, each line will contain several interrupts.
+ */
+
+const uint8_t H2F_int_mapping[BUS_ERROR_UNIT_HART_4]= { \
+
+ H2F_MAPPING_INVALID /*INVALID_IRQn = 0*/, \
+ H2F_MAPPING_INVALID /*L2_METADATA_CORR_IRQn = 1*/, \
+ H2F_MAPPING_INVALID /*L2_METADAT_UNCORR_IRQn = 2*/, \
+ H2F_MAPPING_INVALID /*L2_DATA_CORR_IRQn = 3*/, \
+ H2F_MAPPING_INVALID /*L2_DATA_UNCORR_IRQn = 4*/, \
+ H2F_MAPPING_INVALID /*DMA_CH0_DONE_IRQn = 5*/, \
+ H2F_MAPPING_INVALID /*DMA_CH0_ERR_IRQn = 6*/, \
+ H2F_MAPPING_INVALID /*DMA_CH1_DONE_IRQn = 7*/, \
+ H2F_MAPPING_INVALID /*DMA_CH1_ERR_IRQn = 8*/, \
+ H2F_MAPPING_INVALID /*DMA_CH2_DONE_IRQn = 9*/, \
+ H2F_MAPPING_INVALID /*DMA_CH2_ERR_IRQn = 10*/, \
+ H2F_MAPPING_INVALID /*DMA_CH3_DONE_IRQn = 11*/, \
+ H2F_MAPPING_INVALID /*DMA_CH3_ERR_IRQn = 12*/, \
+
+ 0x00U /*GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0 = 0 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1 = 1 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2 = 2 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3 = 3 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4 = 4 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5 = 5 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6 = 6 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7 = 7 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8 = 8 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9 = 9 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10 = 10 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11 = 11 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12 = 12 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO0_BIT14_or_GPIO2_BIT13_PLIC_13 = 13 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14 = 14 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15 = 15 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16 = 16 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17 = 17 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18 = 18 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19 = 19 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT6_or_GPIO2_BIT20_PLIC_20 = 20 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT7_or_GPIO2_BIT21_PLIC_21 = 21 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT8_or_GPIO2_BIT22_PLIC_22 = 22 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT9_or_GPIO2_BIT23_PLIC_23 = 23 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT10_or_GPIO2_BIT24_PLIC_24 = 24 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT11_or_GPIO2_BIT25_PLIC_25 = 25 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT12_or_GPIO2_BIT26_PLIC_26 = 26 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT13_or_GPIO2_BIT27_PLIC_27 = 27 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO1_BIT14_or_GPIO2_BIT28_PLIC_28 = 28 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT15_or_GPIO2_BIT29_PLIC_29 = 29 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT16_or_GPIO2_BIT30_PLIC_30 = 30 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT17_or_GPIO2_BIT31_PLIC_31 = 31 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO1_BIT18_PLIC_32 = 32 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT19_PLIC_33 = 33 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT20_PLIC_34 = 34 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT21_PLIC_35 = 35 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT22_PLIC_36 = 36 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_BIT23_PLIC_37 = 37 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x00U /*GPIO0_NON_DIRECT_PLI =38 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO1_NON_DIRECT_PLIC =39 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x00U /*GPIO2_NON_DIRECT_PLIC =40 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ 0x01U /*SPI0_PLIC =41 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*SPI1_PLIC =42 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*CAN0_PLIC =43 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*CAN1_PLIC =44 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_MAIN_PLIC =45 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_ALERT_PLIC =46 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C0_SUS_PLIC =47 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_MAIN_PLIC =48 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_ALERT_PLIC =49 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x02U /*I2C1_SUS_PLIC =50 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_INT_PLIC =51 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE1_PLIC =52 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE2_PLIC =53 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_QUEUE3_PLIC =54 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_eMAC_PLIC =55 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x03U /*MAC0_MMSL_PLIC =56 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_int_PLIC =57 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE1_PLIC =58 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE2_PLIC =59 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_QUEUE3_PLIC =60 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_EMAC_PLIC =61 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x04U /*MAC1_MMSL_PLIC =62 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x09U /*DDRC_TRAIN_PLIC =63 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x07U /*SCB_INTERRUPT_PLIC =64 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*ECC_ERROR_PLIC =65 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*ECC_CORRECT_PLIC =66 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*RTC_WAKEUP_PLIC =67 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*RTC_MATCH_PLIC =68 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0CU /*TIMER1_PLIC =69 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0CU /*TIMER2_PLIC =70 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*ENVM_PLIC =71 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*QSPI_PLIC =72 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0EU /*USB_DMA_PLIC =73 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0EU /*USB_MC_PLIC =74 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0FU /*MMC_main_PLIC =75 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0FU /*MMC_wakeup_PLIC =76 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART0_PLIC_77 =77 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART1_PLIC =78 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART2_PLIC =79 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART3_PLIC =80 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x01U /*MMUART4_PLIC =81 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0AU /*G5C_DEVRST_PLIC =82 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x08U /*g5c_MESSAGE_PLIC =83 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_VC_INTERRUPT_PLIC =84 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_SMB_INTERRUPT_PLIC =85 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x06U /*E51_0_MAINTENACE_PLIC =86 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG0_MRVP_PLIC =87 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG1_MRVP_PLIC =88 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG2_MRVP_PLIC =89 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG3_MRVP_PLIC =90 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG4_MRVP_PLIC =91 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG0_TOUT_PLIC =92 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG1_TOUT_PLIC =93 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG2_TOUT_PLIC =94 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG3_TOUT_PLIC =95 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x05U /*WDOG4_TOUT_PLIC =96 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0DU /*G5C_MSS_SPI_PLIC =97 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*VOLT_TEMP_ALARM_PLIC =98 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_COMPLETE_PLIC =99 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_ALARM_PLIC =100 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*ATHENA_BUS_ERROR_PLIC =101 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_AXIC_US_PLIC =102 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ 0x0BU /*USOC_AXIC_DS_PLIC =103 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_0_PLIC = 105 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_1_PLIC = 106 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_2_PLIC = 107 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_3_PLIC = 108 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_4_PLIC = 109 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_5_PLIC = 110 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_6_PLIC = 111 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_7_PLIC = 112 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_8_PLIC = 113 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_9_PLIC = 114 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_10_PLIC = 115 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_11_PLIC = 116 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_12_PLIC = 117 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_13_PLIC = 118 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_14_PLIC = 119 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_15_PLIC = 120 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_16_PLIC = 121 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_17_PLIC = 122 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_18_PLIC = 123 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_19_PLIC = 124 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_20_PLIC = 125 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_21_PLIC = 126 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_22_PLIC = 127 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_23_PLIC = 128 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_24_PLIC = 129 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_25_PLIC = 130 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_26_PLIC = 131 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_27_PLIC = 132 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_28_PLIC = 133 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_29_PLIC = 134 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_30_PLIC = 135 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_31_PLIC = 136 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_32_PLIC = 137 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_33_PLIC = 138 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_34_PLIC = 139 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_35_PLIC = 140 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_36_PLIC = 141 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_37_PLIC = 142 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_38_PLIC = 143 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_39_PLIC = 144 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_40_PLIC = 145 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_41_PLIC = 146 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_42_PLIC = 147 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_43_PLIC = 148 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_44_PLIC = 149 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_45_PLIC = 150 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_46_PLIC = 151 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_47_PLIC = 152 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_48_PLIC = 153 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_49_PLIC = 154 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_50_PLIC = 155 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_51_PLIC = 156 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_52_PLIC = 157 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_53_PLIC = 158 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_54_PLIC = 159 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_55_PLIC = 160 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_56_PLIC = 161 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_57_PLIC = 162 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_58_PLIC = 163 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_59_PLIC = 164 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_60_PLIC = 165 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_61_PLIC = 166 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*FABRIC_F2H_62_PLIC = 167 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+ H2F_MAPPING_INVALID /*FABRIC_F2H_63_PLIC = 168 + OFFSET_TO_MSS_GLOBAL_INTS*/, \
+
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_0 = 182*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_1 = 183*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_2 = 184*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_3 = 185*/, \
+ H2F_MAPPING_INVALID /*BUS_ERROR_UNIT_HART_4 = 186 */
+
+};
+
+
+/**
+ * get source to fabric signal mapping
+ * @param source_int
+ * @return
+ */
+static uint32_t get_corresponding_h2f_output(uint32_t source_int)
+{
+ uint32_t h2f_line = H2F_int_mapping[source_int];
+
+ if(h2f_line < H2F_MAPPING_INVALID) /* if no error */
+ {
+ return(0x01U << h2f_line);
+ }
+
+ return(h2f_line);
+
+}
+
+/**
+ * set H2F controller to reset to defaults- disabled
+ */
+void reset_h2f(void)
+{
+ uint8_t index = 0U;
+ H2F_CONTROLLER->ENABLE = 0U;
+ while(index < 4U)
+ {
+ H2F_CONTROLLER->PLENABLE[index] = 0U;
+ index++;
+ }
+}
+
+/**
+ * enables output which will mirror PLIC input. PLIC mapping given above for reference
+ * @param source_int
+ */
+void enable_h2f_int_output(uint32_t source_int)
+{
+
+ uint32_t output_signal = get_corresponding_h2f_output(source_int);
+
+ if(output_signal != H2F_MAPPING_INVALID)
+ {
+ source_int -= OFFSET_TO_MSS_GLOBAL_INTS;
+
+ /* enable the input */
+ H2F_CONTROLLER->PLENABLE[source_int/32U] |= (0x01U << (source_int % 32U));
+
+ /* enable the output */
+ H2F_CONTROLLER->ENABLE |= ((output_signal<<16U) | 0x01U);
+ }
+}
+
+
+/**
+ * enables output which will mirror PLIC input. PLIC mapping given above for reference
+ * @param source_int
+ */
+void disable_h2f_int_output(uint32_t source_int)
+{
+ uint32_t output_signal = get_corresponding_h2f_output(source_int);
+
+ if(output_signal != H2F_MAPPING_INVALID)
+ {
+ /* enable the input */
+ H2F_CONTROLLER->PLENABLE[source_int/32U] &= ~(source_int % 32U);
+ /* enable the output */
+ H2F_CONTROLLER->ENABLE &= ~(((output_signal<<16U)));
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_h2f.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_h2f.h
new file mode 100644
index 00000000..280e465b
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_h2f.h
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_h2f.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief H2F access data structures and functions.
+ *
+ * Definitions and functions associated with host to fabric interrupt controller.
+ *
+ */
+
+#ifndef MSS_H2F_H
+#define MSS_H2F_H
+
+#include "mpfs_hal_config/mss_sw_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+H2F line Group Ored (no of interrupts ored to one output line)
+0 GPIO 41
+1 MMUART,SPI,CAN 9
+2 I2C 6
+3 MAC0 6
+4 MAC1 6
+5 WATCHDOGS 10
+6 Maintenance 3
+7 SCB 1
+8 G5C-Message 1
+9 DDRC 1
+10 G5C-DEVRST 2
+11 RTC/USOC 4
+12 TIMER 2
+13 ENVM, QSPI 2
+14 USB 2
+15 MMC/SDIO 2
+*/
+
+/*==============================================================================
+ * Host to Fabric interrupt controller
+ *
+ * For an interrupt to activate the PENABLE and appropriate HENABLE and PENABLE bits must be set.
+ *
+ * Note. Since Interrupts 127:94 are not used in the system the enable registers are non-write-able and always read as zeros.
+ *
+ */
+
+typedef struct
+{
+ volatile uint32_t ENABLE; /* bit o: Enables all the H2FINT outputs, bit 31:16 Enables individual H2F outputs */
+ volatile uint32_t H2FSTATUS; /* 15:0 Read back of the 16-bit H2F Interrupts before the H2F and global enable */
+ uint32_t filler[2U]; /* fill the gap in the memory map */
+ volatile uint32_t PLSTATUS[4U]; /* Indicates that the PLINT interrupt is active before the PLINT enable
+ i.e. direct read of the PLINT inputs [31:0] from PLSTATUS[0]
+ direct read of the PLINT inputs [63:32] from PLSTATUS[1]
+ etc */
+ volatile uint32_t PLENABLE[4U]; /* Enables PLINT interrupts PLENABLE[0] 31:0, PLENABLE[1] 63:32, 95:64, 127:96 */
+} H2F_CONTROLLER_Type;
+
+#ifndef H2F_BASE_ADDRESS
+#if (LIBERO_SETTING_APBBUS_CR & (1U<<23U))
+#define H2F_BASE_ADDRESS 0x28126000
+#else
+#define H2F_BASE_ADDRESS 0x20126000
+#endif
+#endif
+
+#define H2F_CONTROLLER ((H2F_CONTROLLER_Type *)H2F_BASE_ADDRESS)
+
+void reset_h2f(void);
+void enable_h2f_int_output(uint32_t source_int);
+void disable_h2f_int_output(uint32_t source_int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_H2F_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_hart_ints.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_hart_ints.h
new file mode 100644
index 00000000..c559d193
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_hart_ints.h
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_hart_ints.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS local interrupt definitions
+ *
+ * Definitions and functions associated with local interrupts for each hart.
+ *
+ */
+#ifndef MSS_HART_INTS_H
+#define MSS_HART_INTS_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct BEU_Type_
+{
+ volatile uint64_t CAUSE;
+ volatile uint64_t VALUE;
+ volatile uint64_t ENABLE;
+ volatile uint64_t PLIC_INT;
+ volatile uint64_t ACCRUED;
+ volatile uint64_t LOCAL_INT;
+ volatile uint64_t reserved2[((0x1000U/8U) - 0x6U)];
+} BEU_Type;
+
+typedef struct BEU_Types_
+{
+ volatile BEU_Type regs[5];
+} BEU_Types;
+
+#define MSS_BUS_ERROR_UNIT_H0 0x01700000UL
+#define MSS_BUS_ERROR_UNIT_H1 0x01701000UL
+#define MSS_BUS_ERROR_UNIT_H2 0x01702000UL
+#define MSS_BUS_ERROR_UNIT_H3 0x01703000UL
+#define MSS_BUS_ERROR_UNIT_H4 0x01704000UL
+
+#define BEU ((BEU_Types *)MSS_BUS_ERROR_UNIT_H0)
+
+/*
+ * Interrupt numbers U0
+ */
+
+#define MAINTENANCE_E51_INT 0
+#define USOC_SMB_INTERRUPT_E51_INT 1
+#define USOC_VC_INTERRUPT_E51_INT 2
+#define G5C_MESSAGE_E51_INT 3
+#define G5C_DEVRST_E51_INT 4
+#define WDOG4_TOUT_E51_INT 5
+#define WDOG3_TOUT_E51_INT 6
+#define WDOG2_TOUT_E51_INT 7
+#define WDOG1_TOUT_E51_INT 8
+#define WDOG0_TOUT_E51_INT 9
+#define WDOG0_MVRP_E51_INT 10
+#define MMUART0_E51_INT 11
+#define ENVM_E51_INT 12
+#define ECC_CORRECT_E51_INT 13
+#define ECC_ERROR_E51_INT 14
+#define scb_INTERRUPT_E51_INT 15
+#define FABRIC_F2H_32_E51_INT 16
+#define FABRIC_F2H_33_E51_INT 17
+#define FABRIC_F2H_34_E51_INT 18
+#define FABRIC_F2H_35_E51_INT 19
+#define FABRIC_F2H_36_E51_INT 20
+#define FABRIC_F2H_37_E51_INT 21
+#define FABRIC_F2H_38_E51_INT 22
+#define FABRIC_F2H_39_E51_INT 23
+#define FABRIC_F2H_40_E51_INT 24
+#define FABRIC_F2H_41_E51_INT 25
+
+#define FABRIC_F2H_42_E51_INT 26
+#define FABRIC_F2H_43_E51_INT 27
+#define FABRIC_F2H_44_E51_INT 28
+#define FABRIC_F2H_45_E51_INT 29
+#define FABRIC_F2H_46_E51_INT 30
+#define FABRIC_F2H_47_E51_INT 31
+#define FABRIC_F2H_48_E51_INT 32
+#define FABRIC_F2H_49_E51_INT 33
+#define FABRIC_F2H_50_E51_INT 34
+#define FABRIC_F2H_51_E51_INT 35
+
+#define FABRIC_F2H_52_E51_INT 36
+#define FABRIC_F2H_53_E51_INT 37
+#define FABRIC_F2H_54_E51_INT 38
+#define FABRIC_F2H_55_E51_INT 39
+#define FABRIC_F2H_56_E51_INT 40
+#define FABRIC_F2H_57_E51_INT 41
+#define FABRIC_F2H_58_E51_INT 42
+#define FABRIC_F2H_59_E51_INT 43
+#define FABRIC_F2H_60_E51_INT 44
+#define FABRIC_F2H_61_E51_INT 45
+
+#define FABRIC_F2H_62_E51_INT 46
+#define FABRIC_F2H_63_E51_INT 47
+
+#define LOCAL_INT_MAX 47U /* Highest numbered */
+#define LOCAL_INT_UNUSED 127U /* Signifies unused interrupt */
+/*
+ * Interrupts associated with
+ * MAINTENANCE_E51_INT
+ *
+ * A group of interrupt events are grouped into a single maintenance interrupt to the E51 CPU,
+ * on receiving this interrupt the E51 should read the maintenance system register to find out
+ * the interrupt source. The maintenance interrupts are defined below
+ */
+#define MAINTENANCE_E51_pll_INT 0
+#define MAINTENANCE_E51_mpu_INT 1
+#define MAINTENANCE_E51_lp_state_enter_INT 2
+#define MAINTENANCE_E51_lp_state_exit_INT 3
+#define MAINTENANCE_E51_ff_start_INT 4
+#define MAINTENANCE_E51_ff_end_INT 5
+#define MAINTENANCE_E51_fpga_on_INT 6
+#define MAINTENANCE_E51_fpga_off_INT 7
+#define MAINTENANCE_E51_scb_error_INT 8
+#define MAINTENANCE_E51_scb_fault_INT 9
+#define MAINTENANCE_E51_mesh_error_INT 10
+#define MAINTENANCE_E51_io_bank_b2_on_INT 12
+#define MAINTENANCE_E51_io_bank_b4_on_INT 13
+#define MAINTENANCE_E51_io_bank_b5_on_INT 14
+#define MAINTENANCE_E51_io_bank_b6_on_INT 15
+#define MAINTENANCE_E51_io_bank_b2_off_INT 16
+#define MAINTENANCE_E51_io_bank_b4_off_INT 17
+#define MAINTENANCE_E51_io_bank_b5_off_INT 18
+#define MAINTENANCE_E51_io_bank_b6_off_INT 19
+
+
+/*
+ * E51-0 is Maintenance Interrupt CPU needs to read status register to determine exact cause:
+ * These defines added here for clarity need to replay with status register defines
+ * for determining interrupt cause
+ */
+#ifndef FOR_CLARITY
+# define FOR_CLARITY 0
+#endif
+
+#if FOR_CLARITY
+# define mpu_fail_plic 0
+# define lp_state_enter_plic 1
+# define lp_state_exit_plic 2
+# define ff_start_plic 3
+# define ff_end_plic 4
+# define fpga_on_plic 5
+# define fpga_off_plic 6
+# define scb_error_plic 7
+# define scb_fault_plic 8
+# define mesh_fail_plic 9
+#endif
+
+/*
+ * Interrupt numbers U54's
+ */
+
+/* U0 (first U54) and U1 connected to mac0 */
+#define MAC0_INT_U54_INT 8 /* determine source mac using hart ID */
+#define MAC0_QUEUE1_U54_INT 7
+#define MAC0_QUEUE2_U54_INT 6
+#define MAC0_QUEUE3_U54_INT 5
+#define MAC0_EMAC_U54_INT 4
+#define MAC0_MMSL_U54_INT 3
+
+/* U2 and U3 connected to mac1 */
+#define MAC1_INT_U54_INT 8 /* determine source mac using hart ID */
+#define MAC1_QUEUE1_U54_INT 7
+#define MAC1_QUEUE2_U54_INT 6
+#define MAC1_QUEUE3_U54_INT 5
+#define MAC1_EMAC_U54_INT 4
+#define MAC1_MMSL_U54_INT 3
+
+/* MMUART1 connected to U54 0 */
+/* MMUART2 connected to U54 1 */
+/* MMUART3 connected to U54 2 */
+/* MMUART4 connected to U54 3 */
+#define MMUARTx_U54_INT 11 /* MMUART1 connected to U54 0 */
+#define WDOGx_MVRP_U54_INT 10 /* determine source mac using hart ID */
+#define WDOGx_TOUT_U54_INT 9 /* determine source mac using hart ID */
+
+#define H2_FABRIC_F2H_0_U54_INT 16
+#define H2_FABRIC_F2H_1_U54_INT 17
+#define H2_FABRIC_F2H_2_U54_INT 18
+#define H2_FABRIC_F2H_3_U54_INT 19
+#define H2_FABRIC_F2H_4_U54_INT 20
+#define H2_FABRIC_F2H_5_U54_INT 21
+#define H2_FABRIC_F2H_6_U54_INT 22
+#define H2_FABRIC_F2H_7_U54_INT 23
+#define H2_FABRIC_F2H_8_U54_INT 24
+#define H2_FABRIC_F2H_9_U54_INT 25
+
+#define H2_FABRIC_F2H_10_U54_INT 26
+#define H2_FABRIC_F2H_11_U54_INT 27
+#define H2_FABRIC_F2H_12_U54_INT 28
+#define H2_FABRIC_F2H_13_U54_INT 29
+#define H2_FABRIC_F2H_14_U54_INT 30
+#define H2_FABRIC_F2H_15_U54_INT 31
+#define H2_FABRIC_F2H_16_U54_INT 32
+#define H2_FABRIC_F2H_17_U54_INT 33
+#define H2_FABRIC_F2H_18_U54_INT 34
+#define H2_FABRIC_F2H_19_U54_INT 35
+
+#define H2_FABRIC_F2H_20_U54_INT 36
+#define H2_FABRIC_F2H_21_U54_INT 37
+#define H2_FABRIC_F2H_22_U54_INT 38
+#define H2_FABRIC_F2H_23_U54_INT 39
+#define H2_FABRIC_F2H_24_U54_INT 40
+#define H2_FABRIC_F2H_25_U54_INT 41
+#define H2_FABRIC_F2H_26_U54_INT 42
+#define H2_FABRIC_F2H_27_U54_INT 43
+#define H2_FABRIC_F2H_28_U54_INT 44
+#define H2_FABRIC_F2H_29_U54_INT 45
+
+#define H2_FABRIC_F2H_30_U54_INT 46
+#define H2_FABRIC_F2H_31_U54_INT 47
+
+
+void handle_m_ext_interrupt(void);
+void Software_h0_IRQHandler(void);
+void Software_h1_IRQHandler(void);
+void Software_h2_IRQHandler(void);
+void Software_h3_IRQHandler(void);
+void Software_h4_IRQHandler(void);
+void SysTick_Handler_h0_IRQHandler(void);
+void SysTick_Handler_h1_IRQHandler(void);
+void SysTick_Handler_h2_IRQHandler(void);
+void SysTick_Handler_h3_IRQHandler(void);
+void SysTick_Handler_h4_IRQHandler(void);
+
+/*
+ *
+ * Local interrupt defines
+ *
+ */
+void maintenance_e51_local_IRQHandler_0(void);
+void usoc_smb_interrupt_e51_local_IRQHandler_1(void);
+void usoc_vc_interrupt_e51_local_IRQHandler_2(void);
+void g5c_message_e51_local_IRQHandler_3(void);
+void g5c_devrst_e51_local_IRQHandler_4(void);
+void wdog4_tout_e51_local_IRQHandler_5(void);
+void wdog3_tout_e51_local_IRQHandler_6(void);
+void wdog2_tout_e51_local_IRQHandler_7(void);
+void wdog1_tout_e51_local_IRQHandler_8(void);
+void wdog0_tout_e51_local_IRQHandler_9(void);
+void wdog0_mvrp_e51_local_IRQHandler_10(void);
+void mmuart0_e51_local_IRQHandler_11(void);
+void envm_e51_local_IRQHandler_12(void);
+void ecc_correct_e51_local_IRQHandler_13(void);
+void ecc_error_e51_local_IRQHandler_14(void);
+void scb_interrupt_e51_local_IRQHandler_15(void);
+void fabric_f2h_32_e51_local_IRQHandler_16(void);
+void fabric_f2h_33_e51_local_IRQHandler_17(void);
+void fabric_f2h_34_e51_local_IRQHandler_18(void);
+void fabric_f2h_35_e51_local_IRQHandler_19(void);
+void fabric_f2h_36_e51_local_IRQHandler_20(void);
+void fabric_f2h_37_e51_local_IRQHandler_21(void);
+void fabric_f2h_38_e51_local_IRQHandler_22(void);
+void fabric_f2h_39_e51_local_IRQHandler_23(void);
+void fabric_f2h_40_e51_local_IRQHandler_24(void);
+void fabric_f2h_41_e51_local_IRQHandler_25(void);
+void fabric_f2h_42_e51_local_IRQHandler_26(void);
+void fabric_f2h_43_e51_local_IRQHandler_27(void);
+void fabric_f2h_44_e51_local_IRQHandler_28(void);
+void fabric_f2h_45_e51_local_IRQHandler_29(void);
+void fabric_f2h_46_e51_local_IRQHandler_30(void);
+void fabric_f2h_47_e51_local_IRQHandler_31(void);
+void fabric_f2h_48_e51_local_IRQHandler_32(void);
+void fabric_f2h_49_e51_local_IRQHandler_33(void);
+void fabric_f2h_50_e51_local_IRQHandler_34(void);
+void fabric_f2h_51_e51_local_IRQHandler_35(void);
+void fabric_f2h_52_e51_local_IRQHandler_36(void);
+void fabric_f2h_53_e51_local_IRQHandler_37(void);
+void fabric_f2h_54_e51_local_IRQHandler_38(void);
+void fabric_f2h_55_e51_local_IRQHandler_39(void);
+void fabric_f2h_56_e51_local_IRQHandler_40(void);
+void fabric_f2h_57_e51_local_IRQHandler_41(void);
+void fabric_f2h_58_e51_local_IRQHandler_42(void);
+void fabric_f2h_59_e51_local_IRQHandler_43(void);
+void fabric_f2h_60_e51_local_IRQHandler_44(void);
+void fabric_f2h_61_e51_local_IRQHandler_45(void);
+void fabric_f2h_62_e51_local_IRQHandler_46(void);
+void fabric_f2h_63_e51_local_IRQHandler_47(void);
+
+/*
+ * U54
+ */
+void spare_u54_local_IRQHandler_0(void);
+void spare_u54_local_IRQHandler_1(void);
+void spare_u54_local_IRQHandler_2(void);
+
+void mac_mmsl_u54_1_local_IRQHandler_3(void);
+void mac_emac_u54_1_local_IRQHandler_4(void);
+void mac_queue3_u54_1_local_IRQHandler_5(void);
+void mac_queue2_u54_1_local_IRQHandler_6(void);
+void mac_queue1_u54_1_local_IRQHandler_7(void);
+void mac_int_u54_1_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_2_local_IRQHandler_3(void);
+void mac_emac_u54_2_local_IRQHandler_4(void);
+void mac_queue3_u54_2_local_IRQHandler_5(void);
+void mac_queue2_u54_2_local_IRQHandler_6(void);
+void mac_queue1_u54_2_local_IRQHandler_7(void);
+void mac_int_u54_2_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_3_local_IRQHandler_3(void);
+void mac_emac_u54_3_local_IRQHandler_4(void);
+void mac_queue3_u54_3_local_IRQHandler_5(void);
+void mac_queue2_u54_3_local_IRQHandler_6(void);
+void mac_queue1_u54_3_local_IRQHandler_7(void);
+void mac_int_u54_3_local_IRQHandler_8(void);
+
+void mac_mmsl_u54_4_local_IRQHandler_3(void);
+void mac_emac_u54_4_local_IRQHandler_4(void);
+void mac_queue3_u54_4_local_IRQHandler_5(void);
+void mac_queue2_u54_4_local_IRQHandler_6(void);
+void mac_queue1_u54_4_local_IRQHandler_7(void);
+void mac_int_u54_4_local_IRQHandler_8(void);
+
+void wdog_tout_u54_h1_local_IRQHandler_9(void);
+void wdog_tout_u54_h2_local_IRQHandler_9(void);
+void wdog_tout_u54_h3_local_IRQHandler_9(void);
+void wdog_tout_u54_h4_local_IRQHandler_9(void);
+void mvrp_u54_local_IRQHandler_10(void);
+void mmuart_u54_h1_local_IRQHandler_11(void);
+void mmuart_u54_h2_local_IRQHandler_11(void);
+void mmuart_u54_h3_local_IRQHandler_11(void);
+void mmuart_u54_h4_local_IRQHandler_11(void);
+void spare_u54_local_IRQHandler_12(void);
+void spare_u54_local_IRQHandler_13(void);
+void spare_u54_local_IRQHandler_14(void);
+void spare_u54_local_IRQHandler_15(void);
+void fabric_f2h_0_u54_local_IRQHandler_16(void);
+void fabric_f2h_1_u54_local_IRQHandler_17(void);
+void fabric_f2h_2_u54_local_IRQHandler_18(void);
+void fabric_f2h_3_u54_local_IRQHandler_19(void);
+void fabric_f2h_4_u54_local_IRQHandler_20(void);
+void fabric_f2h_5_u54_local_IRQHandler_21(void);
+void fabric_f2h_6_u54_local_IRQHandler_22(void);
+void fabric_f2h_7_u54_local_IRQHandler_23(void);
+void fabric_f2h_8_u54_local_IRQHandler_24(void);
+void fabric_f2h_9_u54_local_IRQHandler_25(void);
+void fabric_f2h_10_u54_local_IRQHandler_26(void);
+void fabric_f2h_11_u54_local_IRQHandler_27(void);
+void fabric_f2h_12_u54_local_IRQHandler_28(void);
+void fabric_f2h_13_u54_local_IRQHandler_29(void);
+void fabric_f2h_14_u54_local_IRQHandler_30(void);
+void fabric_f2h_15_u54_local_IRQHandler_31(void);
+void fabric_f2h_16_u54_local_IRQHandler_32(void);
+void fabric_f2h_17_u54_local_IRQHandler_33(void);
+void fabric_f2h_18_u54_local_IRQHandler_34(void);
+void fabric_f2h_19_u54_local_IRQHandler_35(void);
+void fabric_f2h_20_u54_local_IRQHandler_36(void);
+void fabric_f2h_21_u54_local_IRQHandler_37(void);
+void fabric_f2h_22_u54_local_IRQHandler_38(void);
+void fabric_f2h_23_u54_local_IRQHandler_39(void);
+void fabric_f2h_24_u54_local_IRQHandler_40(void);
+void fabric_f2h_25_u54_local_IRQHandler_41(void);
+void fabric_f2h_26_u54_local_IRQHandler_42(void);
+void fabric_f2h_27_u54_local_IRQHandler_43(void);
+void fabric_f2h_28_u54_local_IRQHandler_44(void);
+void fabric_f2h_29_u54_local_IRQHandler_45(void);
+void fabric_f2h_30_u54_local_IRQHandler_46(void);
+void fabric_f2h_31_u54_local_IRQHandler_47(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_HART_INTS_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c
new file mode 100644
index 00000000..6194ae57
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_irq_handler_stubs.c
@@ -0,0 +1,1663 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_irq_handler_stubs.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MPFS MSS Interrupt Function stubs.
+ *
+ * The functions below will only be linked with the application code if the user
+ * does not provide an implementation for these functions. These functions are
+ * defined with weak linking so that they can be overridden by a function with
+ * same prototype in the user's application code.
+ *
+ */
+#include
+#include "mpfs_hal/mss_hal.h"
+
+
+__attribute__((weak)) void handle_m_ext_interrupt(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h0_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h1_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h2_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h3_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void Software_h4_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h0_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h1_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h2_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h3_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) void SysTick_Handler_h4_IRQHandler(void)
+{
+
+}
+
+__attribute__((weak)) uint8_t Invalid_IRQHandler(void)
+{
+ return(0U);
+}
+#ifdef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t External_1_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_2_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_3_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t USART0_plic_4_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_5_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_6_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_7_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_8_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_9_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_10_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_11_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_12_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_13_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_14_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_15_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_16_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_17_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_18_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_19_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_20_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_21_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_22_IRQHandler(void)
+{
+ return(0U);
+}
+#endif
+
+__attribute__((weak)) uint8_t dma_ch0_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch0_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch1_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch1_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch2_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch2_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch3_DONE_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t dma_ch3_ERR_IRQHandler(void)
+{
+ return(0U);
+}
+#ifdef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t External_31_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t External_32_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_33_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_34_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_35_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_36_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_37_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_38_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_39_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_40_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_41_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_42_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_43_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_44_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_45_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_46_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_47_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_48_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_49_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_50_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_51_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_52_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t MAC0_plic_53_IRQHandler(void)
+{
+ return(0U);
+}
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t l2_metadata_corr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_metadata_uncorr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_data_corr_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t l2_data_uncorr_IRQHandler(void)
+{
+ return(0U);
+}
+#endif /* ifndef SIFIVE_HIFIVE_UNLEASHED */
+
+
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+__attribute__((weak)) uint8_t gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler(void)
+ {
+ return(0U);
+ }
+
+__attribute__((weak)) uint8_t gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio1_bit18_plic_32_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit19_plic_33_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit20_plic_34_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit21_plic_35_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit22_plic_36_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_bit23_plic_37_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t gpio0_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio1_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t gpio2_non_direct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t spi0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t spi1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t external_can0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t can1_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_i2c0_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t External_i2c0_alert_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c0_sus_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_alert_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t i2c1_sus_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_int_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_queue3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_emac_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac0_mmsl_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_int_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_queue3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_emac_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mac1_mmsl_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ddrc_train_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t scb_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ecc_error_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t ecc_correct_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t rtc_wakeup_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t rtc_match_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t timer1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t timer2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t envm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t qspi_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usb_dma_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usb_mc_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmc_main_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmc_wakeup_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart0_plic_77_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t mmuart4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t g5c_devrst_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t g5c_message_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usoc_vc_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t usoc_smb_interrupt_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t e51_0_Maintence_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t wdog0_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog1_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog2_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog3_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog4_mvrp_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog0_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog1_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog2_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog3_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t wdog4_tout_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t g5c_mss_spi_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t volt_temp_alarm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_complete_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_alarm_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t athena_bus_error_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t usoc_axic_us_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t usoc_axic_ds_plic_IRQHandler(void)
+{
+ return(0U);
+}
+__attribute__((weak)) uint8_t reserved_104_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+
+__attribute__((weak)) uint8_t fabric_f2h_0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_5_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_6_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_7_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_8_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_9_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_10_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_11_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_12_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_13_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_14_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_15_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_16_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_17_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_18_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_19_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_20_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_21_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_22_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_23_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_24_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_25_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_26_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_27_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_28_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_29_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_30_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_31_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_32_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_33_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_34_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_35_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_36_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_37_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_38_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_39_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_40_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_41_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_42_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_43_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_44_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_45_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_46_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_47_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_48_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_49_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_50_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_51_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_52_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_53_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_54_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_55_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_56_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_57_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_58_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_59_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_60_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_61_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t fabric_f2h_62_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t fabric_f2h_63_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_0_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_1_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_2_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_3_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+__attribute__((weak)) uint8_t bus_error_unit_hart_4_plic_IRQHandler(void)
+{
+ return(0U);
+}
+
+
+/* Local interrupt stubs */
+__attribute__((weak)) void maintenance_e51_local_IRQHandler_0(void)
+{
+}
+__attribute__((weak)) void usoc_smb_interrupt_e51_local_IRQHandler_1(void)
+{
+}
+__attribute__((weak)) void usoc_vc_interrupt_e51_local_IRQHandler_2(void)
+{
+}
+__attribute__((weak)) void g5c_message_e51_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void g5c_devrst_e51_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void wdog4_tout_e51_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void wdog3_tout_e51_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void wdog2_tout_e51_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void wdog1_tout_e51_local_IRQHandler_8(void)
+{
+}
+__attribute__((weak)) void wdog0_tout_e51_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog0_mvrp_e51_local_IRQHandler_10(void)
+{
+}
+
+__attribute__((weak)) void mmuart0_e51_local_IRQHandler_11(void)
+{
+}
+
+__attribute__((weak)) void envm_e51_local_IRQHandler_12(void)
+{
+}
+
+__attribute__((weak)) void ecc_correct_e51_local_IRQHandler_13(void)
+{
+}
+
+__attribute__((weak)) void ecc_error_e51_local_IRQHandler_14(void)
+{
+}
+
+__attribute__((weak)) void scb_interrupt_e51_local_IRQHandler_15(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_32_e51_local_IRQHandler_16(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_33_e51_local_IRQHandler_17(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_34_e51_local_IRQHandler_18(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_35_e51_local_IRQHandler_19(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_36_e51_local_IRQHandler_20(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_37_e51_local_IRQHandler_21(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_38_e51_local_IRQHandler_22(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_39_e51_local_IRQHandler_23(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_40_e51_local_IRQHandler_24(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_41_e51_local_IRQHandler_25(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_42_e51_local_IRQHandler_26(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_43_e51_local_IRQHandler_27(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_44_e51_local_IRQHandler_28(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_45_e51_local_IRQHandler_29(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_46_e51_local_IRQHandler_30(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_47_e51_local_IRQHandler_31(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_48_e51_local_IRQHandler_32(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_49_e51_local_IRQHandler_33(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_50_e51_local_IRQHandler_34(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_51_e51_local_IRQHandler_35(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_52_e51_local_IRQHandler_36(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_53_e51_local_IRQHandler_37(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_54_e51_local_IRQHandler_38(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_55_e51_local_IRQHandler_39(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_56_e51_local_IRQHandler_40(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_57_e51_local_IRQHandler_41(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_58_e51_local_IRQHandler_42(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_59_e51_local_IRQHandler_43(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_60_e51_local_IRQHandler_44(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_61_e51_local_IRQHandler_45(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_62_e51_local_IRQHandler_46(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_63_e51_local_IRQHandler_47(void)
+{
+}
+
+
+/*
+ * U54
+ */
+__attribute__((weak)) void spare_u54_local_IRQHandler_0(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_1(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_2(void)
+{
+}
+
+/* Ethernet MACs - GEM0 is on U54s 1 and 2, GEM1 is on U54s 3 and 4 */
+
+/* U54 1 */
+__attribute__((weak)) void mac_mmsl_u54_1_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_1_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_1_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_1_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_1_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_1_local_IRQHandler_8(void)
+{
+}
+
+/* U54 2 */
+__attribute__((weak)) void mac_mmsl_u54_2_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_2_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_2_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_2_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_2_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_2_local_IRQHandler_8(void)
+{
+}
+
+/* U54 3 */
+__attribute__((weak)) void mac_mmsl_u54_3_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_3_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_3_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_3_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_3_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_3_local_IRQHandler_8(void)
+{
+}
+
+/* U54 4 */
+__attribute__((weak)) void mac_mmsl_u54_4_local_IRQHandler_3(void)
+{
+}
+__attribute__((weak)) void mac_emac_u54_4_local_IRQHandler_4(void)
+{
+}
+__attribute__((weak)) void mac_queue3_u54_4_local_IRQHandler_5(void)
+{
+}
+__attribute__((weak)) void mac_queue2_u54_4_local_IRQHandler_6(void)
+{
+}
+__attribute__((weak)) void mac_queue1_u54_4_local_IRQHandler_7(void)
+{
+}
+__attribute__((weak)) void mac_int_u54_4_local_IRQHandler_8(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h1_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h2_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h3_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void wdog_tout_u54_h4_local_IRQHandler_9(void)
+{
+}
+__attribute__((weak)) void mvrp_u54_local_IRQHandler_10(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h1_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h2_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h3_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void mmuart_u54_h4_local_IRQHandler_11(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_12(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_13(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_14(void)
+{
+}
+__attribute__((weak)) void spare_u54_local_IRQHandler_15(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_0_u54_local_IRQHandler_16(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_1_u54_local_IRQHandler_17(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_2_u54_local_IRQHandler_18(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_3_u54_local_IRQHandler_19(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_4_u54_local_IRQHandler_20(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_5_u54_local_IRQHandler_21(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_6_u54_local_IRQHandler_22(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_7_u54_local_IRQHandler_23(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_8_u54_local_IRQHandler_24(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_9_u54_local_IRQHandler_25(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_10_u54_local_IRQHandler_26(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_11_u54_local_IRQHandler_27(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_12_u54_local_IRQHandler_28(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_13_u54_local_IRQHandler_29(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_14_u54_local_IRQHandler_30(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_15_u54_local_IRQHandler_31(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_16_u54_local_IRQHandler_32(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_17_u54_local_IRQHandler_33(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_18_u54_local_IRQHandler_34(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_19_u54_local_IRQHandler_35(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_20_u54_local_IRQHandler_36(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_21_u54_local_IRQHandler_37(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_22_u54_local_IRQHandler_38(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_23_u54_local_IRQHandler_39(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_24_u54_local_IRQHandler_40(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_25_u54_local_IRQHandler_41(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_26_u54_local_IRQHandler_42(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_27_u54_local_IRQHandler_43(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_28_u54_local_IRQHandler_44(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_29_u54_local_IRQHandler_45(void)
+{
+}
+
+__attribute__((weak)) void fabric_f2h_30_u54_local_IRQHandler_46(void)
+{
+}
+__attribute__((weak)) void fabric_f2h_31_u54_local_IRQHandler_47(void)
+{
+}
+#endif /* ifndef SIFIVE_HIFIVE_UNLEASHED */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_l2_cache.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_l2_cache.c
new file mode 100644
index 00000000..d51efed0
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_l2_cache.c
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_l2_cache.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief The code in this file is executed before any code/data sections are
+ * copied. This code must not rely sdata/data section content. Hence, global
+ * variables should not be used unless they are constants.
+ *
+ */
+/*==============================================================================
+ *
+ */
+
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+#include "mss_l2_cache.h"
+
+/*==============================================================================
+ * Local defines
+ */
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+static const uint64_t g_init_marker = INIT_MARKER;
+#endif
+
+/*==============================================================================
+ * Local functions.
+ */
+static void check_config_l2_scratchpad(void);
+
+
+/*==============================================================================
+ * This code should only be executed from E51 to be functional.
+ * Configure the L2 cache memory:
+ * - Set the number of cache ways used as cache based on the MSS Configurator
+ * settings.
+ * - Configure some of the enabled ways as scratchpad based on linker
+ * configuration and space allocated by configurator.
+ */
+__attribute__((weak)) void config_l2_cache(void)
+{
+ ASSERT(LIBERO_SETTING_WAY_ENABLE < 16U);
+
+ /*
+ * Set the number of ways that will be shared between cache and scratchpad.
+ */
+ CACHE_CTRL->WAY_ENABLE = LIBERO_SETTING_WAY_ENABLE;
+
+ /*
+ * shutdown L2 as directed
+ */
+ SYSREG->L2_SHUTDOWN_CR = LIBERO_SETTING_L2_SHUTDOWN_CR;
+
+ /* The scratchpad has already been set-up, first check enough space before copying */
+ check_config_l2_scratchpad();
+
+ /* If you are not using scratchpad, no need to include the following code */
+
+ ASSERT(LIBERO_SETTING_WAY_ENABLE >= LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS);
+
+
+
+ /*
+ * Compute the mask used to specify ways that will be used by the
+ * scratchpad.
+ */
+
+ uint32_t scratchpad_ways_mask = 0U;
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+ uint32_t inc;
+ uint32_t seed_ways_mask = 0x1U << LIBERO_SETTING_WAY_ENABLE;
+ for(inc = 0; inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++inc)
+ {
+ scratchpad_ways_mask |= (seed_ways_mask >> inc) ;
+ }
+#else
+ (void)scratchpad_ways_mask;
+#endif
+
+ /*
+ * Make sure ways are masked if being used as scratchpad
+ */
+ ASSERT((LIBERO_SETTING_WAY_MASK_DMA & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_E51_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_E51_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_1_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_2_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_3_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_4_DCACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_1_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_2_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_3_ICACHE & scratchpad_ways_mask) == 0UL);
+ ASSERT((LIBERO_SETTING_WAY_MASK_U54_4_ICACHE & scratchpad_ways_mask) == 0UL);
+
+ /*
+ * Setup all masters, apart from one we are using to setup scratch
+ */
+ CACHE_CTRL->WAY_MASK_DMA = LIBERO_SETTING_WAY_MASK_DMA;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_0;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_1;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_2;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_3;
+ CACHE_CTRL->WAY_MASK_E51_ICACHE = LIBERO_SETTING_WAY_MASK_E51_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_1_DCACHE = LIBERO_SETTING_WAY_MASK_U54_1_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_1_ICACHE = LIBERO_SETTING_WAY_MASK_U54_1_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_2_DCACHE = LIBERO_SETTING_WAY_MASK_U54_2_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_2_ICACHE = LIBERO_SETTING_WAY_MASK_U54_2_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_3_DCACHE = LIBERO_SETTING_WAY_MASK_U54_3_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_3_ICACHE = LIBERO_SETTING_WAY_MASK_U54_3_ICACHE;
+ CACHE_CTRL->WAY_MASK_U54_4_DCACHE = LIBERO_SETTING_WAY_MASK_U54_4_DCACHE;
+ CACHE_CTRL->WAY_MASK_U54_4_ICACHE = LIBERO_SETTING_WAY_MASK_U54_4_ICACHE;
+
+#if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0)
+ /*
+ * Assign ways to Zero Device
+ */
+ uint64_t * p_scratchpad = (uint64_t *)ZERO_DEVICE_BOTTOM;
+ uint32_t ways_inc;
+ uint64_t current_way = 0x1U << (((LIBERO_SETTING_WAY_ENABLE + 1U) - LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS) );
+ for(ways_inc = 0; ways_inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++ways_inc)
+ {
+ /*
+ * Populate the scratchpad memory one way at a time.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way;
+ mb();
+ /*
+ * Write to the first 64-bit location of each cache block.
+ */
+ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc)
+ {
+ *p_scratchpad = g_init_marker + inc;
+ p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH;
+ }
+ current_way = current_way << 1U;
+ mb();
+ }
+#endif /* (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0) */
+ /*
+ * Prevent E51 from evicting from scratchpad ways.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = LIBERO_SETTING_WAY_MASK_E51_DCACHE;
+ mb();
+
+}
+
+
+/*==============================================================================
+ * Configure the L2 scratchpad based on linker symbols:
+ * __l2_scratchpad_vma_start
+ * __l2_scratchpad_vma_end
+ *
+ * These linker symbols specify the start address and length of the scratchpad.
+ * The scratchpad must be located within the Zero Device memory range.
+ */
+static void check_config_l2_scratchpad(void)
+{
+ extern char __l2_scratchpad_vma_start;
+ extern char __l2_scratchpad_vma_end;
+
+ uint8_t n_scratchpad_ways;
+ const uint64_t end = (const uint64_t)&__l2_scratchpad_vma_end;
+ const uint64_t start = (const uint64_t)&__l2_scratchpad_vma_start;
+ uint64_t modulo;
+
+ ASSERT(start >= (uint64_t)ZERO_DEVICE_BOTTOM);
+ ASSERT(end < (uint64_t)ZERO_DEVICE_TOP);
+ ASSERT(end >= start);
+
+ /*
+ * Figure out how many cache ways will be required from linker script
+ * symbols.
+ */
+ n_scratchpad_ways = (uint8_t)((end - start) / WAY_BYTE_LENGTH);
+ modulo = (end - start) % WAY_BYTE_LENGTH;
+ if(modulo > 0)
+ {
+ ++n_scratchpad_ways;
+ }
+
+ ASSERT(LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS >= n_scratchpad_ways);
+}
+
+#if 0 // todo - remove, no longer used
+
+
+/*==============================================================================
+ * Reserve a number of cache ways to be used as scratchpad memory.
+ *
+ * @param nways
+ * Number of ways to be used as scratchpad. One way is 128Kbytes.
+ *
+ * @param scratchpad_start
+ * Start address within the Zero Device memory range in which the scratchpad
+ * will be located.
+ */
+static void reserve_scratchpad_ways(uint8_t nways, uint64_t * scratchpad_start)
+{
+ uint8_t way_enable;
+ uint64_t available_ways = 1;
+ uint64_t scratchpad_ways = 0;
+ uint64_t non_scratchpad_ways;
+ uint32_t inc;
+
+ ASSERT(scratchpad_start >= (uint64_t *)ZERO_DEVICE_BOTTOM);
+ ASSERT(scratchpad_start < (uint64_t *)ZERO_DEVICE_TOP);
+
+ /*
+ * Ensure at least one way remains available as cache.
+ */
+ way_enable = CACHE_CTRL->WAY_ENABLE;
+ ASSERT(nways <= way_enable);
+ if(nways <= way_enable)
+ {
+ /*
+ * Compute the mask used to specify ways that will be used by the
+ * scratchpad.
+ */
+
+ for(inc = 0; inc < way_enable; ++inc)
+ {
+ available_ways = (available_ways << 1) | (uint64_t)0x01;
+ if(inc < nways)
+ {
+ scratchpad_ways = (scratchpad_ways << 1) | (uint64_t)0x01;
+ }
+ }
+
+ /*
+ * Prevent other masters from evicting cache lines from scratchpad ways.
+ * Only allow E51 to evict from scratchpad ways.
+ */
+ non_scratchpad_ways = available_ways & ~scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_DMA = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_E51_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_1_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_1_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_2_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_2_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_3_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_3_ICACHE = non_scratchpad_ways;
+
+ CACHE_CTRL->WAY_MASK_U54_4_DCACHE = non_scratchpad_ways;
+ CACHE_CTRL->WAY_MASK_U54_4_ICACHE = non_scratchpad_ways;
+
+ /*
+ * Assign ways to Zero Device
+ */
+ uint64_t * p_scratchpad = scratchpad_start;
+ int ways_inc;
+ uint64_t current_way = 1;
+ for(ways_inc = 0; ways_inc < nways; ++ways_inc)
+ {
+ /*
+ * Populate the scratchpad memory one way at a time.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way;
+ /*
+ * Write to the first 64-bit location of each cache block.
+ */
+ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc)
+ {
+ *p_scratchpad = g_init_marker + inc;
+ p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH;
+ }
+ current_way = current_way << 1U;
+ mb();
+ }
+
+ /*
+ * Prevent E51 from evicting from scratchpad ways.
+ */
+ CACHE_CTRL->WAY_MASK_E51_DCACHE = non_scratchpad_ways;
+ }
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_l2_cache.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_l2_cache.h
new file mode 100644
index 00000000..16d618d6
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_l2_cache.h
@@ -0,0 +1,532 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ * @file mss_l2_cache.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief MACROs defines and prototypes associated with L2 Cache
+ *
+ */
+#ifndef MSS_L2_CACHE_H
+#define MSS_L2_CACHE_H
+
+#include
+#include "encoding.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following defines will be present in configurator generated xml Q1 2021
+ * In the interim, you can manually edit if required.
+ */
+#if !defined (LIBERO_SETTING_WAY_ENABLE)
+/*Way indexes less than or equal to this register value may be used by the
+cache. E.g. set to 0x7, will allocate 8 cache ways, 0-7 to cache, and leave
+8-15 as LIM. Note 1: Way 0 is always allocated as cache. Note 2: each way is
+128KB. */
+#define LIBERO_SETTING_WAY_ENABLE 0x00000007UL
+ /* WAY_ENABLE [0:8] RW value= 0x7 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_DMA)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_DMA 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_0)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_1)
+/*Way mask register master DMA. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_2)
+/*Way mask registerAXI slave port 2. Set field to zero to disable way from this
+master. The available cache ways are 0 to number set in WAY_ENABLE register. If
+using scratch pad memory, the ways you want reserved for scrathpad are not
+available for selection, you must set to 0. e.g. If three ways reserved for
+scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
+masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_3)
+/*Way mask register AXI slave port 3. Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_DCACHE)
+/*Way mask register E51 data cache (hart0). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_E51_ICACHE)
+/*Way mask registerE52 instruction cache (hart0). Set field to zero to disable
+way from this master. The available cache ways are 0 to number set in
+WAY_ENABLE register. If using scratch pad memory, the ways you want reserved
+for scrathpad are not available for selection, you must set to 0. e.g. If three
+ways reserved for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set
+to zero for all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_E51_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_DCACHE)
+/*Way mask register data cache (hart1). Set field to zero to disable way from
+this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_ICACHE)
+/*Way mask register instruction cache (hart1). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_1_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_DCACHE)
+/*Way mask register data cache (hart2). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_ICACHE)
+/*Way mask register instruction cache (hart2). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_2_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_DCACHE)
+/*Way mask register data cache (hart3). Set field to 1 to disable way from this
+master.Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_ICACHE)
+/*Way mask register instruction cache(hart3). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_3_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_DCACHE)
+/*Way mask register data cache (hart4). Set field to 1 to disable way from this
+master. Set field to zero to disable way from this master. The available cache
+ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
+the ways you want reserved for scrathpad are not available for selection, you
+must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
+WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
+evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_DCACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_ICACHE)
+/*Way mask register instruction cache (hart4). Set field to zero to disable way
+from this master. The available cache ways are 0 to number set in WAY_ENABLE
+register. If using scratch pad memory, the ways you want reserved for scrathpad
+are not available for selection, you must set to 0. e.g. If three ways reserved
+for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
+all masters, so they can not evict the way. */
+#define LIBERO_SETTING_WAY_MASK_U54_4_ICACHE 0x0000FFFFUL
+ /* WAY_MASK_0 [0:1] RW value= 0x1 */
+ /* WAY_MASK_1 [1:1] RW value= 0x1 */
+ /* WAY_MASK_2 [2:1] RW value= 0x1 */
+ /* WAY_MASK_3 [3:1] RW value= 0x1 */
+ /* WAY_MASK_4 [4:1] RW value= 0x1 */
+ /* WAY_MASK_5 [5:1] RW value= 0x1 */
+ /* WAY_MASK_6 [6:1] RW value= 0x1 */
+ /* WAY_MASK_7 [7:1] RW value= 0x1 */
+ /* WAY_MASK_8 [8:1] RW value= 0x1 */
+ /* WAY_MASK_9 [9:1] RW value= 0x1 */
+ /* WAY_MASK_10 [10:1] RW value= 0x1 */
+ /* WAY_MASK_11 [11:1] RW value= 0x1 */
+ /* WAY_MASK_12 [12:1] RW value= 0x1 */
+ /* WAY_MASK_13 [13:1] RW value= 0x1 */
+ /* WAY_MASK_14 [14:1] RW value= 0x1 */
+ /* WAY_MASK_15 [15:1] RW value= 0x1 */
+#endif
+#if !defined (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS)
+/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
+2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
+for scratchpad start at way 0, and work up. */
+#define LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS 0x00000000UL
+ /* NUM_OF_WAYS [0:8] RW value= 0x0 */
+#endif
+
+
+#if !defined (LIBERO_SETTING_L2_SHUTDOWN_CR)
+/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
+2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
+for scratchpad start at way 0, and work up. */
+#define LIBERO_SETTING_L2_SHUTDOWN_CR 0x00000000UL
+ /* NUM_OF_WAYS [0:8] RW value= 0x0 */
+#endif
+
+
+
+/*==============================================================================
+ * Define describing cache characteristics.
+ */
+#define MAX_WAY_ENABLE 15
+#define NB_SETS 512
+#define NB_BANKS 4
+#define CACHE_BLOCK_BYTE_LENGTH 64
+#define UINT64_BYTE_LENGTH 8
+#define WAY_BYTE_LENGTH (CACHE_BLOCK_BYTE_LENGTH * NB_SETS * NB_BANKS)
+
+#define ZERO_DEVICE_BOTTOM 0x0A000000ULL
+#define ZERO_DEVICE_TOP 0x0C000000ULL
+
+#define CACHE_CTRL_BASE 0x02010000ULL
+
+#define INIT_MARKER 0xC0FFEEBEC0010000ULL
+
+#define SHUTDOWN_CACHE_CC24_00_07_MASK 0x01
+#define SHUTDOWN_CACHE_CC24_08_15_MASK 0x02
+#define SHUTDOWN_CACHE_CC24_16_23_MASK 0x04
+#define SHUTDOWN_CACHE_CC24_24_31_MASK 0x08
+
+
+/*==============================================================================
+ * Cache controller registers definitions
+ */
+#define RO volatile const
+#define RW volatile
+#define WO volatile
+
+typedef struct {
+ RO uint8_t BANKS;
+ RO uint8_t WAYS;
+ RO uint8_t SETS;
+ RO uint8_t BYTES;
+} CACHE_CONFIG_typedef;
+
+typedef struct {
+ CACHE_CONFIG_typedef CONFIG;
+ RO uint32_t RESERVED;
+ RW uint8_t WAY_ENABLE;
+ RO uint8_t RESERVED0[55];
+
+ RW uint32_t ECC_INJECT_ERROR;
+ RO uint32_t RESERVED1[47];
+
+ RO uint64_t ECC_DIR_FIX_ADDR;
+ RO uint32_t ECC_DIR_FIX_COUNT;
+ RO uint32_t RESERVED2[13];
+
+ RO uint64_t ECC_DATA_FIX_ADDR;
+ RO uint32_t ECC_DATA_FIX_COUNT;
+ RO uint32_t RESERVED3[5];
+
+ RO uint64_t ECC_DATA_FAIL_ADDR;
+ RO uint32_t ECC_DATA_FAIL_COUNT;
+ RO uint32_t RESERVED4[37];
+
+ WO uint64_t FLUSH64;
+ RO uint64_t RESERVED5[7];
+
+ WO uint32_t FLUSH32;
+ RO uint32_t RESERVED6[367];
+
+ RW uint64_t WAY_MASK_DMA;
+
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_0;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_1;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_2;
+ RW uint64_t WAY_MASK_AXI4_SLAVE_PORT_3;
+
+ RW uint64_t WAY_MASK_E51_DCACHE;
+ RW uint64_t WAY_MASK_E51_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_1_DCACHE;
+ RW uint64_t WAY_MASK_U54_1_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_2_DCACHE;
+ RW uint64_t WAY_MASK_U54_2_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_3_DCACHE;
+ RW uint64_t WAY_MASK_U54_3_ICACHE;
+
+ RW uint64_t WAY_MASK_U54_4_DCACHE;
+ RW uint64_t WAY_MASK_U54_4_ICACHE;
+} CACHE_CTRL_typedef;
+
+#define CACHE_CTRL ((volatile CACHE_CTRL_typedef *) CACHE_CTRL_BASE)
+
+void config_l2_cache(void);
+uint8_t check_num_scratch_ways(uint64_t *start, uint64_t *end);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_L2_CACHE_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mpu.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mpu.c
new file mode 100644
index 00000000..1e5b55e7
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mpu.c
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_mpu.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS MPU driver for configuring access regions for the
+ * external masters.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+static uint64_t pmp_get_napot_base_and_range(uint64_t reg, uint64_t *range);
+
+uint8_t num_pmp_lut[10U] = {16U,16U,8U,4U,8U,8U,4U,4U,8U,2U};
+
+/**
+ * \brief MPU configuration from Libero for FIC0
+ *
+ */
+const uint64_t mpu_fic0_values[] = {
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP7,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP8,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP9,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP10,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP11,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP12,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP13,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP14,
+ LIBERO_SETTING_FIC0_MPU_CFG_PMP15
+};
+
+/**
+ * \brief MPU configuration from Libero for FIC1
+ *
+ */
+const uint64_t mpu_fic1_values[] = {
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP7,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP8,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP9,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP10,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP11,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP12,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP13,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP14,
+ LIBERO_SETTING_FIC1_MPU_CFG_PMP15
+};
+
+/**
+ * \brief MPU configuration from Libero for FIC2
+ *
+ */
+const uint64_t mpu_fic2_values[] = {
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP0,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP1,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP2,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP3,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP4,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP5,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP6,
+ LIBERO_SETTING_FIC2_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for ATHENA
+ *
+ */
+const uint64_t mpu_crypto_values[] = {
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP0,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP1,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP2,
+ LIBERO_SETTING_CRYPTO_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for GEM0
+ *
+ */
+const uint64_t mpu_gem0_values[] = {
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP0,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP1,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP2,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP3,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP4,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP5,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP6,
+ LIBERO_SETTING_GEM0_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for GEM1
+ *
+ */
+const uint64_t mpu_gem1_values[] = {
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP0,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP1,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP2,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP3,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP4,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP5,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP6,
+ LIBERO_SETTING_GEM1_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for MMC
+ *
+ */
+const uint64_t mpu_mmc_values[] = {
+ LIBERO_SETTING_MMC_MPU_CFG_PMP0,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP1,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP2,
+ LIBERO_SETTING_MMC_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for SCB
+ *
+ */
+const uint64_t mpu_scb_values[] = {
+ LIBERO_SETTING_SCB_MPU_CFG_PMP0,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP1,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP2,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP3,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP4,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP5,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP6,
+ LIBERO_SETTING_SCB_MPU_CFG_PMP7,
+};
+
+/**
+ * \brief MPU configuration from Libero for USB
+ *
+ */
+const uint64_t mpu_usb_values[] = {
+ LIBERO_SETTING_USB_MPU_CFG_PMP0,
+ LIBERO_SETTING_USB_MPU_CFG_PMP1,
+ LIBERO_SETTING_USB_MPU_CFG_PMP2,
+ LIBERO_SETTING_USB_MPU_CFG_PMP3,
+};
+
+/**
+ * \brief MPU configuration from Libero for TRACE
+ *
+ */
+const uint64_t mpu_trace_values[] = {
+ LIBERO_SETTING_TRACE_MPU_CFG_PMP0,
+ LIBERO_SETTING_TRACE_MPU_CFG_PMP1,
+};
+
+
+/***************************************************************************//**
+ * MSS_MPU_auto_configure()
+ * Set MPU's up with configuration from Libero
+ *
+ *
+ * @return
+ */
+uint8_t mpu_configure(void)
+{
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC0)->PMPCFG)),
+ &(mpu_fic0_values),
+ sizeof(mpu_fic0_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC1)->PMPCFG)),
+ &(mpu_fic1_values),
+ sizeof(mpu_fic1_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_FIC2)->PMPCFG)),
+ &(mpu_fic2_values),
+ sizeof(mpu_fic2_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_CRYPTO)->PMPCFG)),
+ &(mpu_crypto_values),
+ sizeof(mpu_crypto_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_GEM0)->PMPCFG)),
+ &(mpu_gem0_values),
+ sizeof(mpu_gem0_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_GEM1)->PMPCFG)),
+ &(mpu_gem1_values),
+ sizeof(mpu_gem1_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_USB)->PMPCFG)),
+ &(mpu_usb_values),
+ sizeof(mpu_usb_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_MMC)->PMPCFG)),
+ &(mpu_mmc_values),
+ sizeof(mpu_mmc_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_SCB)->PMPCFG)),
+ &(mpu_scb_values),
+ sizeof(mpu_scb_values));
+
+ config_64_copy((void *)(&(MSS_MPU(MSS_MPU_TRACE)->PMPCFG)),
+ &(mpu_trace_values),
+ sizeof(mpu_trace_values));
+
+ return(0);
+}
+
+
+
+
+
+/***************************************************************************//**
+*/
+uint8_t MSS_MPU_configure(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t base,
+ uint64_t size,
+ uint8_t permission,
+ mss_mpu_addrm_t matching_mode,
+ uint8_t lock_en)
+{
+ uint64_t temp = size, cnt=0ULL;
+ uint64_t range;
+
+ /*size must be minimum 4k
+ Size must be power of 2
+ different masters have different number of regions*/
+ if((size >= 4096ULL) && (0U == (size & (size - 1U))) && (pmp_region < num_pmp_lut[master_port]))
+ {
+ while((0 == (temp & 0x01U)))
+ {
+ cnt++;
+ temp >>= 1U;
+ }
+
+ range = (1ULL << (cnt-1U))-1U;
+
+ MSS_MPU(master_port)->PMPCFG[pmp_region].raw = (base | range) >> 2U;
+
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode = (uint8_t)(permission |
+ (uint8_t)(matching_mode << 3U) |
+ (lock_en << 0x7U));
+
+ return ((uint8_t)0);
+ }
+ else
+ {
+ return ((uint8_t)1);
+ }
+}
+
+uint8_t MSS_MPU_get_config(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t* base,
+ uint64_t* size,
+ uint8_t* permission,
+ mss_mpu_addrm_t* matching_mode,
+ uint8_t* lock_en)
+{
+ uint64_t reg;
+
+ /*All AXI external masters dont have same number of PMP regions*/
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ reg = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.pmp;
+ *base = pmp_get_napot_base_and_range(reg, size);
+
+ reg = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode;
+ *lock_en = ( reg >> 0x7U) & 0x1U;
+ *matching_mode = (mss_mpu_addrm_t)( (reg >> 3ULL) & 0x3U);
+ *permission = reg & 0x7U;
+
+ return ((uint8_t)0);
+ }
+ else
+ {
+ return ((uint8_t)1);
+ }
+}
+
+static uint64_t pmp_get_napot_base_and_range(uint64_t reg, uint64_t *range)
+{
+ /* construct a mask of all bits bar the top bit */
+ uint64_t mask = 0U;
+ uint64_t base = reg;
+ uint64_t numbits = (sizeof(uint64_t) * 8U) + 2U;
+ mask = (mask - 1U) >> 1U;
+
+ while (mask)
+ {
+ if ((reg & mask) == mask)
+ {
+ /* this is the mask to use */
+ base = reg & ~mask;
+ break;
+ }
+ mask >>= 1U;
+ numbits--;
+ }
+
+ *range = (1LU << numbits);
+ return (base << 2U);
+}
+
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mpu.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mpu.h
new file mode 100644
index 00000000..6b4e1abb
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mpu.h
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_mpu.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS MPU driver APIs for configuring access regions for
+ * the external masters.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_MPU_H
+#define MSS_MPU_H
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+
+/***************************************************************************//**
+
+ */
+#define MPU_MODE_READ_ACCESS (1U << 0U)
+#define MPU_MODE_WRITE_ACCESS (1U << 1U)
+#define MPU_MODE_EXEC_ACCESS (1U << 2U)
+
+typedef enum {
+ MSS_MPU_FIC0 = 0x00,
+ MSS_MPU_FIC1,
+ MSS_MPU_FIC2,
+ MSS_MPU_CRYPTO,
+ MSS_MPU_GEM0,
+ MSS_MPU_GEM1,
+ MSS_MPU_USB,
+ MSS_MPU_MMC,
+ MSS_MPU_SCB,
+ MSS_MPU_TRACE,
+ MSS_MPU_SEG0,
+ MSS_MPU_SEG1,
+} mss_mpu_mport_t;
+
+typedef enum {
+ MSS_MPU_AM_OFF = 0x00U,
+ MSS_MPU_AM_NAPOT = 0x03U,
+} mss_mpu_addrm_t;
+
+typedef enum {
+ MSS_MPU_PMP_REGION0 = 0x00,
+ MSS_MPU_PMP_REGION1,
+ MSS_MPU_PMP_REGION2,
+ MSS_MPU_PMP_REGION3,
+ MSS_MPU_PMP_REGION4,
+ MSS_MPU_PMP_REGION5,
+ MSS_MPU_PMP_REGION6,
+ MSS_MPU_PMP_REGION7,
+ MSS_MPU_PMP_REGION8,
+ MSS_MPU_PMP_REGION9,
+ MSS_MPU_PMP_REGION10,
+ MSS_MPU_PMP_REGION11,
+ MSS_MPU_PMP_REGION12,
+ MSS_MPU_PMP_REGION13,
+ MSS_MPU_PMP_REGION14,
+ MSS_MPU_PMP_REGION15,
+} mss_mpu_pmp_region_t;
+
+extern uint8_t num_pmp_lut[10];
+
+#ifndef __I
+#define __I const volatile
+#endif
+#ifndef __IO
+#define __IO volatile
+#endif
+#ifndef __O
+#define __O volatile
+#endif
+
+
+typedef struct {
+ union {
+ struct
+ {
+ __IO uint64_t pmp : 38;
+ __IO uint64_t rsrvd : 18;
+ __IO uint64_t mode : 8;
+ } MPUCFG_TypeDef;
+ uint64_t raw;
+ };
+} MPU_CFG;
+
+typedef struct
+{
+ __IO uint64_t addr : 38;
+ __IO uint64_t rw : 1;
+ __IO uint64_t id : 4;
+ __IO uint64_t failed : 1;
+ __IO uint64_t padding : (64-44);
+} MPU_FailStatus_TypeDef;
+
+typedef struct
+{
+ MPU_CFG PMPCFG[16U];
+ __IO MPU_FailStatus_TypeDef STATUS;
+} MPU_TypeDef;
+
+
+
+#define MSS_MPU(master) ( (MPU_TypeDef*) (0x20005000UL + ((master) << 8U)))
+
+
+uint8_t mpu_configure(void);
+
+
+uint8_t MSS_MPU_configure(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t base,
+ uint64_t size,
+ uint8_t permission,
+ mss_mpu_addrm_t matching_mode,
+ uint8_t lock_en);
+
+uint8_t MSS_MPU_get_config(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint64_t* base,
+ uint64_t* size,
+ uint8_t* permission,
+ mss_mpu_addrm_t* matching_mode,
+ uint8_t* lock_en);
+
+static inline uint8_t MSS_MPU_lock_region(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= (0x1U << 7U);
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+/*permission value could be bitwise or of:
+ * MPU_MODE_READ_ACCESS
+ * MPU_MODE_WRITE_ACCESS
+ * MPU_MODE_EXEC_ACCESS
+ *
+ * */
+static inline uint8_t MSS_MPU_set_permission(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint8_t permission)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode |= permission;
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+static inline uint8_t MSS_MPU_get_permission(mss_mpu_mport_t master_port,
+ mss_mpu_pmp_region_t pmp_region,
+ uint8_t* permission)
+{
+ if(pmp_region < num_pmp_lut[master_port])
+ {
+ *permission = MSS_MPU(master_port)->PMPCFG[pmp_region].MPUCFG_TypeDef.mode & 0x7U;
+ return (0U);
+ }
+ else
+ {
+ return (1U);
+ }
+}
+
+/*read the Fail status register when there is a MPU access failure.
+ See the return type MPU_FailStatus_TypeDef for the details of the STATUS bitfield.
+ The status failed bit(offset 42) needs to be reset using the corresponding bit
+ in SYSREG->mpu_violation_sr
+ */
+static inline MPU_FailStatus_TypeDef MSS_MPU_get_failstatus(mss_mpu_mport_t master_port)
+{
+ return (MSS_MPU(master_port)->STATUS);
+}
+
+#endif /* ! SIFIVE_HIFIVE_UNLEASHED */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_MPU_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mtrap.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mtrap.c
new file mode 100644
index 00000000..2226d7bf
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mtrap.c
@@ -0,0 +1,783 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ *
+ * @file mss_mtrap.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief trap functions
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+void handle_local_interrupt(uint8_t interrupt_no);
+void handle_m_soft_interrupt(void);
+void handle_m_timer_interrupt(void);
+void illegal_insn_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void misaligned_store_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void misaligned_load_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void pmp_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc);
+void trap_from_machine_mode(uintptr_t * regs, uintptr_t dummy, uintptr_t mepc);
+void bad_trap(uintptr_t* regs, uintptr_t dummy, uintptr_t mepc);
+
+
+void bad_trap(uintptr_t* regs, uintptr_t dummy, uintptr_t mepc)
+{
+ (void)regs;
+ (void)dummy;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void misaligned_store_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void misaligned_load_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void illegal_insn_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+void pmp_trap(uintptr_t * regs, uintptr_t mcause, uintptr_t mepc)
+{
+ (void)regs;
+ (void)mcause;
+ (void)mepc;
+ while(1)
+ {
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * RISC-V interrupt handler for external interrupts.
+ */
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+uint8_t (*ext_irq_handler_table[PLIC_NUM_SOURCES])(void) =
+{
+ Invalid_IRQHandler,
+ l2_metadata_corr_IRQHandler,
+ l2_metadata_uncorr_IRQHandler,
+ l2_data_corr_IRQHandler,
+ l2_data_uncorr_IRQHandler,
+ dma_ch0_DONE_IRQHandler,
+ dma_ch0_ERR_IRQHandler,
+ dma_ch1_DONE_IRQHandler,
+ dma_ch1_ERR_IRQHandler,
+ dma_ch2_DONE_IRQHandler,
+ dma_ch2_ERR_IRQHandler,
+ dma_ch3_DONE_IRQHandler,
+ dma_ch3_ERR_IRQHandler,
+ gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler,
+ gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler,
+ gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler,
+ gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler,
+ gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler,
+ gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler,
+ gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler,
+ gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler,
+ gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler,
+ gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler,
+ gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler,
+ gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler,
+ gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler,
+
+ gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler,
+ gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler,
+ gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler,
+ gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler,
+ gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler,
+ gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler,
+ gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler,
+ gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler,
+ gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler,
+ gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler,
+ gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler,
+ gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler,
+ gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler,
+ gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler,
+ gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler,
+
+ gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler,
+ gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler,
+ gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler,
+ gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler,
+
+ gpio1_bit18_plic_32_IRQHandler,
+ gpio1_bit19_plic_33_IRQHandler,
+ gpio1_bit20_plic_34_IRQHandler,
+ gpio1_bit21_plic_35_IRQHandler,
+ gpio1_bit22_plic_36_IRQHandler,
+ gpio1_bit23_plic_37_IRQHandler,
+
+ gpio0_non_direct_plic_IRQHandler,
+ gpio1_non_direct_plic_IRQHandler,
+ gpio2_non_direct_plic_IRQHandler,
+
+ spi0_plic_IRQHandler,
+ spi1_plic_IRQHandler,
+ external_can0_plic_IRQHandler,
+ can1_IRQHandler,
+ External_i2c0_main_plic_IRQHandler,
+ External_i2c0_alert_plic_IRQHandler,
+ i2c0_sus_plic_IRQHandler,
+ i2c1_main_plic_IRQHandler,
+ i2c1_alert_plic_IRQHandler,
+ i2c1_sus_plic_IRQHandler,
+ mac0_int_plic_IRQHandler,
+ mac0_queue1_plic_IRQHandler,
+ mac0_queue2_plic_IRQHandler,
+ mac0_queue3_plic_IRQHandler,
+ mac0_emac_plic_IRQHandler,
+ mac0_mmsl_plic_IRQHandler,
+ mac1_int_plic_IRQHandler,
+ mac1_queue1_plic_IRQHandler,
+ mac1_queue2_plic_IRQHandler,
+ mac1_queue3_plic_IRQHandler,
+ mac1_emac_plic_IRQHandler,
+ mac1_mmsl_plic_IRQHandler,
+ ddrc_train_plic_IRQHandler,
+ scb_interrupt_plic_IRQHandler,
+ ecc_error_plic_IRQHandler,
+ ecc_correct_plic_IRQHandler,
+ rtc_wakeup_plic_IRQHandler,
+ rtc_match_plic_IRQHandler,
+ timer1_plic_IRQHandler,
+ timer2_plic_IRQHandler,
+ envm_plic_IRQHandler,
+ qspi_plic_IRQHandler,
+ usb_dma_plic_IRQHandler,
+ usb_mc_plic_IRQHandler,
+ mmc_main_plic_IRQHandler,
+ mmc_wakeup_plic_IRQHandler,
+ mmuart0_plic_77_IRQHandler,
+ mmuart1_plic_IRQHandler,
+ mmuart2_plic_IRQHandler,
+ mmuart3_plic_IRQHandler,
+ mmuart4_plic_IRQHandler,
+
+ g5c_devrst_plic_IRQHandler,
+ g5c_message_plic_IRQHandler,
+ usoc_vc_interrupt_plic_IRQHandler,
+ usoc_smb_interrupt_plic_IRQHandler,
+ e51_0_Maintence_plic_IRQHandler,
+
+ wdog0_mvrp_plic_IRQHandler,
+ wdog1_mvrp_plic_IRQHandler, /*100 contains multiple interrupts- */
+ wdog2_mvrp_plic_IRQHandler,
+ wdog3_mvrp_plic_IRQHandler,
+ wdog4_mvrp_plic_IRQHandler,
+ wdog0_tout_plic_IRQHandler,
+ wdog1_tout_plic_IRQHandler,
+ wdog2_tout_plic_IRQHandler,
+ wdog3_tout_plic_IRQHandler,
+ wdog4_tout_plic_IRQHandler,
+
+ g5c_mss_spi_plic_IRQHandler,
+ volt_temp_alarm_plic_IRQHandler,
+ athena_complete_plic_IRQHandler,
+ athena_alarm_plic_IRQHandler,
+ athena_bus_error_plic_IRQHandler,
+ usoc_axic_us_plic_IRQHandler,
+ usoc_axic_ds_plic_IRQHandler,
+
+ reserved_104_plic_IRQHandler,
+
+ fabric_f2h_0_plic_IRQHandler,
+ fabric_f2h_1_plic_IRQHandler,
+ fabric_f2h_2_plic_IRQHandler,
+ fabric_f2h_3_plic_IRQHandler,
+ fabric_f2h_4_plic_IRQHandler,
+ fabric_f2h_5_plic_IRQHandler,
+ fabric_f2h_6_plic_IRQHandler,
+ fabric_f2h_7_plic_IRQHandler,
+ fabric_f2h_8_plic_IRQHandler,
+ fabric_f2h_9_plic_IRQHandler,
+
+ fabric_f2h_10_plic_IRQHandler,
+ fabric_f2h_11_plic_IRQHandler,
+ fabric_f2h_12_plic_IRQHandler,
+ fabric_f2h_13_plic_IRQHandler,
+ fabric_f2h_14_plic_IRQHandler,
+ fabric_f2h_15_plic_IRQHandler,
+ fabric_f2h_16_plic_IRQHandler,
+ fabric_f2h_17_plic_IRQHandler,
+ fabric_f2h_18_plic_IRQHandler,
+ fabric_f2h_19_plic_IRQHandler,
+
+ fabric_f2h_20_plic_IRQHandler,
+ fabric_f2h_21_plic_IRQHandler,
+ fabric_f2h_22_plic_IRQHandler,
+ fabric_f2h_23_plic_IRQHandler,
+ fabric_f2h_24_plic_IRQHandler,
+ fabric_f2h_25_plic_IRQHandler,
+ fabric_f2h_26_plic_IRQHandler,
+ fabric_f2h_27_plic_IRQHandler,
+ fabric_f2h_28_plic_IRQHandler,
+ fabric_f2h_29_plic_IRQHandler,
+
+ fabric_f2h_30_plic_IRQHandler,
+ fabric_f2h_31_plic_IRQHandler,
+
+ fabric_f2h_32_plic_IRQHandler,
+ fabric_f2h_33_plic_IRQHandler,
+ fabric_f2h_34_plic_IRQHandler,
+ fabric_f2h_35_plic_IRQHandler,
+ fabric_f2h_36_plic_IRQHandler,
+ fabric_f2h_37_plic_IRQHandler,
+ fabric_f2h_38_plic_IRQHandler,
+ fabric_f2h_39_plic_IRQHandler,
+ fabric_f2h_40_plic_IRQHandler,
+ fabric_f2h_41_plic_IRQHandler,
+
+ fabric_f2h_42_plic_IRQHandler,
+ fabric_f2h_43_plic_IRQHandler,
+ fabric_f2h_44_plic_IRQHandler,
+ fabric_f2h_45_plic_IRQHandler,
+ fabric_f2h_46_plic_IRQHandler,
+ fabric_f2h_47_plic_IRQHandler,
+ fabric_f2h_48_plic_IRQHandler,
+ fabric_f2h_49_plic_IRQHandler,
+ fabric_f2h_50_plic_IRQHandler,
+ fabric_f2h_51_plic_IRQHandler,
+
+ fabric_f2h_52_plic_IRQHandler,
+ fabric_f2h_53_plic_IRQHandler,
+ fabric_f2h_54_plic_IRQHandler,
+ fabric_f2h_55_plic_IRQHandler,
+ fabric_f2h_56_plic_IRQHandler,
+ fabric_f2h_57_plic_IRQHandler,
+ fabric_f2h_58_plic_IRQHandler,
+ fabric_f2h_59_plic_IRQHandler,
+ fabric_f2h_60_plic_IRQHandler,
+ fabric_f2h_61_plic_IRQHandler,
+
+ fabric_f2h_62_plic_IRQHandler,
+ fabric_f2h_63_plic_IRQHandler,
+
+ bus_error_unit_hart_0_plic_IRQHandler,
+ bus_error_unit_hart_1_plic_IRQHandler,
+ bus_error_unit_hart_2_plic_IRQHandler,
+ bus_error_unit_hart_3_plic_IRQHandler,
+ bus_error_unit_hart_4_plic_IRQHandler
+};
+
+#define E51_LOCAL_NUM_SOURCES 48U
+
+
+void (*local_irq_handler_e51_table[E51_LOCAL_NUM_SOURCES])(void) =
+{
+ maintenance_e51_local_IRQHandler_0, /* reference multiple interrupts */
+ usoc_smb_interrupt_e51_local_IRQHandler_1,
+ usoc_vc_interrupt_e51_local_IRQHandler_2,
+ g5c_message_e51_local_IRQHandler_3,
+ g5c_devrst_e51_local_IRQHandler_4,
+ wdog4_tout_e51_local_IRQHandler_5,
+ wdog3_tout_e51_local_IRQHandler_6,
+ wdog2_tout_e51_local_IRQHandler_7,
+ wdog1_tout_e51_local_IRQHandler_8,
+ wdog0_tout_e51_local_IRQHandler_9,
+ wdog0_mvrp_e51_local_IRQHandler_10,
+ mmuart0_e51_local_IRQHandler_11,
+ envm_e51_local_IRQHandler_12,
+ ecc_correct_e51_local_IRQHandler_13,
+ ecc_error_e51_local_IRQHandler_14,
+ scb_interrupt_e51_local_IRQHandler_15,
+ fabric_f2h_32_e51_local_IRQHandler_16,
+ fabric_f2h_33_e51_local_IRQHandler_17,
+ fabric_f2h_34_e51_local_IRQHandler_18,
+ fabric_f2h_35_e51_local_IRQHandler_19,
+ fabric_f2h_36_e51_local_IRQHandler_20,
+ fabric_f2h_37_e51_local_IRQHandler_21,
+ fabric_f2h_38_e51_local_IRQHandler_22,
+ fabric_f2h_39_e51_local_IRQHandler_23,
+ fabric_f2h_40_e51_local_IRQHandler_24,
+ fabric_f2h_41_e51_local_IRQHandler_25,
+
+ fabric_f2h_42_e51_local_IRQHandler_26,
+ fabric_f2h_43_e51_local_IRQHandler_27,
+ fabric_f2h_44_e51_local_IRQHandler_28,
+ fabric_f2h_45_e51_local_IRQHandler_29,
+ fabric_f2h_46_e51_local_IRQHandler_30,
+ fabric_f2h_47_e51_local_IRQHandler_31,
+ fabric_f2h_48_e51_local_IRQHandler_32,
+ fabric_f2h_49_e51_local_IRQHandler_33,
+ fabric_f2h_50_e51_local_IRQHandler_34,
+ fabric_f2h_51_e51_local_IRQHandler_35,
+
+ fabric_f2h_52_e51_local_IRQHandler_36,
+ fabric_f2h_53_e51_local_IRQHandler_37,
+ fabric_f2h_54_e51_local_IRQHandler_38,
+ fabric_f2h_55_e51_local_IRQHandler_39,
+ fabric_f2h_56_e51_local_IRQHandler_40,
+ fabric_f2h_57_e51_local_IRQHandler_41,
+ fabric_f2h_58_e51_local_IRQHandler_42,
+ fabric_f2h_59_e51_local_IRQHandler_43,
+ fabric_f2h_60_e51_local_IRQHandler_44,
+ fabric_f2h_61_e51_local_IRQHandler_45,
+
+ fabric_f2h_62_e51_local_IRQHandler_46,
+ fabric_f2h_63_e51_local_IRQHandler_47
+};
+
+
+typedef void (*local_int_p_t)(void);
+
+/* U54 1 */
+local_int_p_t local_irq_handler_u54_1_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_1_local_IRQHandler_3,
+ mac_emac_u54_1_local_IRQHandler_4,
+ mac_queue3_u54_1_local_IRQHandler_5,
+ mac_queue2_u54_1_local_IRQHandler_6,
+ mac_queue1_u54_1_local_IRQHandler_7,
+ mac_int_u54_1_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h1_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h1_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 2 */
+local_int_p_t local_irq_handler_u54_2_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_2_local_IRQHandler_3,
+ mac_emac_u54_2_local_IRQHandler_4,
+ mac_queue3_u54_2_local_IRQHandler_5,
+ mac_queue2_u54_2_local_IRQHandler_6,
+ mac_queue1_u54_2_local_IRQHandler_7,
+ mac_int_u54_2_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h2_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h2_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 3 */
+local_int_p_t local_irq_handler_u54_3_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_3_local_IRQHandler_3,
+ mac_emac_u54_3_local_IRQHandler_4,
+ mac_queue3_u54_3_local_IRQHandler_5,
+ mac_queue2_u54_3_local_IRQHandler_6,
+ mac_queue1_u54_3_local_IRQHandler_7,
+ mac_int_u54_3_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h3_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h3_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+/* U54 4 */
+local_int_p_t local_irq_handler_u54_4_table[E51_LOCAL_NUM_SOURCES] =
+{
+ /*reference multiple interrupts*/
+ spare_u54_local_IRQHandler_0,
+ spare_u54_local_IRQHandler_1,
+ spare_u54_local_IRQHandler_2,
+
+ /*parse hart ID to discover which mac is the source*/
+ mac_mmsl_u54_4_local_IRQHandler_3,
+ mac_emac_u54_4_local_IRQHandler_4,
+ mac_queue3_u54_4_local_IRQHandler_5,
+ mac_queue2_u54_4_local_IRQHandler_6,
+ mac_queue1_u54_4_local_IRQHandler_7,
+ mac_int_u54_4_local_IRQHandler_8,
+
+ /*parse hart ID to discover which wdog is the source*/
+ wdog_tout_u54_h4_local_IRQHandler_9,
+ mvrp_u54_local_IRQHandler_10,
+ mmuart_u54_h4_local_IRQHandler_11,
+
+ spare_u54_local_IRQHandler_12,
+ spare_u54_local_IRQHandler_13,
+ spare_u54_local_IRQHandler_14,
+ spare_u54_local_IRQHandler_15,
+
+ fabric_f2h_0_u54_local_IRQHandler_16,
+ fabric_f2h_1_u54_local_IRQHandler_17,
+ fabric_f2h_2_u54_local_IRQHandler_18,
+ fabric_f2h_3_u54_local_IRQHandler_19,
+ fabric_f2h_4_u54_local_IRQHandler_20,
+ fabric_f2h_5_u54_local_IRQHandler_21,
+ fabric_f2h_6_u54_local_IRQHandler_22,
+ fabric_f2h_7_u54_local_IRQHandler_23,
+ fabric_f2h_8_u54_local_IRQHandler_24,
+ fabric_f2h_9_u54_local_IRQHandler_25,
+
+ fabric_f2h_10_u54_local_IRQHandler_26,
+ fabric_f2h_11_u54_local_IRQHandler_27,
+ fabric_f2h_12_u54_local_IRQHandler_28,
+ fabric_f2h_13_u54_local_IRQHandler_29,
+ fabric_f2h_14_u54_local_IRQHandler_30,
+ fabric_f2h_15_u54_local_IRQHandler_31,
+ fabric_f2h_16_u54_local_IRQHandler_32,
+ fabric_f2h_17_u54_local_IRQHandler_33,
+ fabric_f2h_18_u54_local_IRQHandler_34,
+ fabric_f2h_19_u54_local_IRQHandler_35,
+
+ fabric_f2h_20_u54_local_IRQHandler_36,
+ fabric_f2h_21_u54_local_IRQHandler_37,
+ fabric_f2h_22_u54_local_IRQHandler_38,
+ fabric_f2h_23_u54_local_IRQHandler_39,
+ fabric_f2h_24_u54_local_IRQHandler_40,
+ fabric_f2h_25_u54_local_IRQHandler_41,
+ fabric_f2h_26_u54_local_IRQHandler_42,
+ fabric_f2h_27_u54_local_IRQHandler_43,
+ fabric_f2h_28_u54_local_IRQHandler_44,
+ fabric_f2h_29_u54_local_IRQHandler_45,
+
+ fabric_f2h_30_u54_local_IRQHandler_46,
+ fabric_f2h_31_u54_local_IRQHandler_47
+};
+
+local_int_p_t *local_int_mux[5] =
+{
+ local_irq_handler_e51_table,
+ local_irq_handler_u54_1_table,
+ local_irq_handler_u54_2_table,
+ local_irq_handler_u54_3_table,
+ local_irq_handler_u54_4_table
+};
+
+#else
+uint8_t (*ext_irq_handler_table[PLIC_NUM_SOURCES])(void) =
+{
+ Invalid_IRQHandler,
+ External_1_IRQHandler,
+ External_2_IRQHandler,
+ External_3_IRQHandler,
+ USART0_plic_4_IRQHandler,
+ External_5_IRQHandler,
+ External_6_IRQHandler,
+ External_7_IRQHandler,
+ External_8_IRQHandler,
+ External_9_IRQHandler,
+ External_10_IRQHandler,
+ External_11_IRQHandler,
+ External_12_IRQHandler,
+ External_13_IRQHandler,
+ External_14_IRQHandler,
+ External_15_IRQHandler,
+ External_16_IRQHandler,
+ External_17_IRQHandler,
+ External_18_IRQHandler,
+ External_19_IRQHandler,
+ External_20_IRQHandler,
+ External_21_IRQHandler,
+ External_22_IRQHandler,
+ dma_ch0_DONE_IRQHandler,
+ dma_ch0_ERR_IRQHandler,
+ dma_ch1_DONE_IRQHandler,
+ dma_ch1_ERR_IRQHandler,
+ dma_ch2_DONE_IRQHandler,
+ dma_ch2_ERR_IRQHandler,
+ dma_ch3_DONE_IRQHandler,
+ dma_ch3_ERR_IRQHandler,
+ External_31_IRQHandler,
+ External_32_IRQHandler,
+ External_33_IRQHandler,
+ External_34_IRQHandler,
+ External_35_IRQHandler,
+ External_36_IRQHandler,
+ External_37_IRQHandler,
+ External_38_IRQHandler,
+ External_39_IRQHandler,
+ External_40_IRQHandler,
+ External_41_IRQHandler,
+ External_42_IRQHandler,
+ External_43_IRQHandler,
+ External_44_IRQHandler,
+ External_45_IRQHandler,
+ External_46_IRQHandler,
+ External_47_IRQHandler,
+ External_48_IRQHandler,
+ External_49_IRQHandler,
+ External_50_IRQHandler,
+ External_51_IRQHandler,
+ External_52_IRQHandler,
+ MAC0_plic_53_IRQHandler
+
+};
+#endif
+/*------------------------------------------------------------------------------
+ *
+ */
+void handle_m_ext_interrupt(void)
+{
+
+ volatile uint32_t int_num = PLIC_ClaimIRQ();
+
+ if (INVALID_IRQn == int_num)
+ {
+ return;
+ }
+
+ uint8_t disable = EXT_IRQ_KEEP_ENABLED;
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ disable = ext_irq_handler_table[int_num /* + OFFSET_TO_MSS_GLOBAL_INTS Think this was required in early bitfile */]();
+#else
+ disable = ext_irq_handler_table[int_num]();
+#endif
+
+ PLIC_CompleteIRQ(int_num);
+
+ if(EXT_IRQ_DISABLE == disable)
+ {
+ PLIC_DisableIRQ((PLIC_IRQn_Type)int_num);
+ }
+
+}
+
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void handle_local_interrupt(uint8_t interrupt_no)
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED /* no local interrupts on unleashed */
+ uint64_t mhart_id = read_csr(mhartid);
+ uint8_t local_interrupt_no = (uint8_t)(interrupt_no - 16U);
+ local_int_p_t *local_int_table = local_int_mux[mhart_id];
+
+ (*local_int_table[local_interrupt_no])();
+
+#endif
+}
+
+/*------------------------------------------------------------------------------
+ *
+ */
+void trap_from_machine_mode(uintptr_t * regs, uintptr_t dummy, uintptr_t mepc)
+{
+ volatile uintptr_t mcause = read_csr(mcause);
+
+ if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) > 15U)&& ((mcause & MCAUSE_CAUSE) < 64U))
+ {
+ handle_local_interrupt((uint8_t)(mcause & MCAUSE_CAUSE));
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT))
+ {
+ handle_m_ext_interrupt();
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_SOFT))
+ {
+ handle_m_soft_interrupt();
+ }
+ else if (((mcause & MCAUSE_INT) == MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER))
+ {
+ handle_m_timer_interrupt();
+ }
+ else
+ {
+ uint32_t i = 0U;
+ while(1)
+ {
+ /* wait for watchdog */
+ i++; /* added some code as SC debugger hangs if in loop doing nothing */
+ if(i == 0x1000U)
+ {
+ i = mcause; /* so mcause is not optimised out */
+ }
+ }
+ switch(mcause)
+ {
+
+ case CAUSE_LOAD_PAGE_FAULT:
+ break;
+ case CAUSE_STORE_PAGE_FAULT:
+ break;
+ case CAUSE_FETCH_ACCESS:
+ break;
+ case CAUSE_LOAD_ACCESS:
+ break;
+ case CAUSE_STORE_ACCESS:
+ break;
+ default:
+ bad_trap(regs, dummy, mepc);
+ break;
+ }
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mtrap.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mtrap.h
new file mode 100644
index 00000000..3d68eb12
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_mtrap.h
@@ -0,0 +1,92 @@
+/*
+ Copyright (c) 2013, The Regents of the University of California (Regents).
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+/***********************************************************************************
+ * Record of Microchip changes
+ */
+#ifndef RISCV_MTRAP_H
+#define RISCV_MTRAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ASSEMBLER__
+#define read_const_csr(reg) ({ unsigned long __tmp; \
+ asm ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+#endif
+
+#define IPI_SOFT 0x01
+#define IPI_FENCE_I 0x02
+#define IPI_SFENCE_VMA 0x04
+
+#define MACHINE_STACK_SIZE (RISCV_PGSIZE) /* this is 4k for HLS and 4k for the stack*/
+#define MENTRY_HLS_OFFSET (INTEGER_CONTEXT_SIZE + SOFT_FLOAT_CONTEXT_SIZE)
+#define MENTRY_FRAME_SIZE (MENTRY_HLS_OFFSET + HLS_SIZE)
+#define MENTRY_IPI_OFFSET (MENTRY_HLS_OFFSET)
+#define MENTRY_IPI_PENDING_OFFSET (MENTRY_HLS_OFFSET + REGBYTES)
+
+#ifdef __riscv_flen
+# define SOFT_FLOAT_CONTEXT_SIZE (0)
+#else
+# define SOFT_FLOAT_CONTEXT_SIZE (8 * 32)
+#endif
+
+#define HLS_SIZE (64)
+#define INTEGER_CONTEXT_SIZE (32 * REGBYTES)
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ volatile uint32_t * ipi;
+ volatile int mipi_pending;
+ volatile int padding;
+ volatile uint64_t * timecmp;
+ volatile uint32_t * plic_m_thresh;
+ volatile uintptr_t * plic_m_ie;
+ volatile uint32_t * plic_s_thresh;
+ volatile uintptr_t * plic_s_ie;
+} hls_t;
+
+/* This code relies on the stack being allocated on a 4K boundary */
+/* also can not be bigger than 4k */
+#define MACHINE_STACK_TOP() ({ \
+ register uintptr_t sp asm ("sp"); \
+ (void *)((sp + RISCV_PGSIZE) & -RISCV_PGSIZE); })
+
+// hart-local storage
+#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
+#define OTHER_HLS(id) ((hls_t*)((void *)HLS() + RISCV_PGSIZE * ((id) - read_const_csr(mhartid))))
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*RISCV_MTRAP_H*/
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_peripherals.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_peripherals.c
new file mode 100644
index 00000000..307cd0ee
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_peripherals.c
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_peripherals.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS functions related to peripherals.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+const uint32_t LIBERO_SETTING_CONTEXT_EN[][2U] = {
+ {LIBERO_SETTING_CONTEXT_A_EN,
+ LIBERO_SETTING_CONTEXT_B_EN},
+ {LIBERO_SETTING_CONTEXT_A_EN_FIC,
+ LIBERO_SETTING_CONTEXT_B_EN_FIC},
+};
+
+/* offsets used in PERIPHERAL_SETUP array */
+#define PERIPHERAL_INDEX_OFFSET 0U /* used for sanity check */
+#define CONTEXT_EN_INDEX_OFFSET 1U
+#define CONTEXT_MASK_INDEX_OFFSET 2U
+#define CONTEXT_SUBCLK_INDEX_OFFSET 3U
+
+const uint32_t PERIPHERAL_SETUP[][4U] = {
+ {MSS_PERIPH_MMUART0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART0,SUBBLK_CLOCK_CR_MMUART0_MASK},
+ {MSS_PERIPH_MMUART1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART1,SUBBLK_CLOCK_CR_MMUART1_MASK},
+ {MSS_PERIPH_MMUART2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART2,SUBBLK_CLOCK_CR_MMUART2_MASK},
+ {MSS_PERIPH_MMUART3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART3,SUBBLK_CLOCK_CR_MMUART3_MASK},
+ {MSS_PERIPH_MMUART4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMUART4,SUBBLK_CLOCK_CR_MMUART4_MASK},
+ {MSS_PERIPH_WDOG0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG0,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG1,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG2,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG3,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG3,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_WDOG4,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_WDOG4,SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_SPI0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI0,SUBBLK_CLOCK_CR_SPI0_MASK},
+ {MSS_PERIPH_SPI1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_SPI1,SUBBLK_CLOCK_CR_SPI1_MASK},
+ {MSS_PERIPH_I2C0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C0,SUBBLK_CLOCK_CR_I2C0_MASK},
+ {MSS_PERIPH_I2C1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_I2C1,SUBBLK_CLOCK_CR_I2C1_MASK},
+ {MSS_PERIPH_CAN0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN0,SUBBLK_CLOCK_CR_CAN0_MASK},
+ {MSS_PERIPH_CAN1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CAN1,SUBBLK_CLOCK_CR_CAN1_MASK},
+ {MSS_PERIPH_MAC0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC0,SUBBLK_CLOCK_CR_MAC0_MASK},
+ {MSS_PERIPH_MAC1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MAC1,SUBBLK_CLOCK_CR_MAC1_MASK},
+ {MSS_PERIPH_TIMER,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_TIMER,SUBBLK_CLOCK_CR_TIMER_MASK},
+ {MSS_PERIPH_GPIO0,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO0,SUBBLK_CLOCK_CR_GPIO0_MASK},
+ {MSS_PERIPH_GPIO1,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO1,SUBBLK_CLOCK_CR_GPIO1_MASK},
+ {MSS_PERIPH_GPIO2,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_GPIO2,SUBBLK_CLOCK_CR_GPIO2_MASK},
+ {MSS_PERIPH_RTC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_RTC,SUBBLK_CLOCK_CR_RTC_MASK},
+ {MSS_PERIPH_H2FINT,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_H2FINT, SUBBLK_CLOCK_NA_MASK},
+ {MSS_PERIPH_CRYPTO,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CRYPTO,SUBBLK_CLOCK_CR_ATHENA_MASK},
+ {MSS_PERIPH_USB,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_USB,SUBBLK_CLOCK_CR_USB_MASK},
+ {MSS_PERIPH_QSPIXIP,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_QSPIXIP,SUBBLK_CLOCK_CR_QSPI_MASK},
+ {MSS_PERIPH_ATHENA,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_ATHENA,SUBBLK_CLOCK_CR_ATHENA_MASK},
+ {MSS_PERIPH_TRACE,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_MAILBOX_SC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_EMMC,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_MMC,SUBBLK_CLOCK_CR_MMC_MASK},
+ {MSS_PERIPH_CFM,CONTEXT_EN_INDEX, CONTEXT_EN_MASK_CFM,SUBBLK_CLOCK_CR_CFM_MASK},
+ {MSS_PERIPH_FIC0,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC0,SUBBLK_CLOCK_CR_FIC0_MASK},
+ {MSS_PERIPH_FIC1,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC1,SUBBLK_CLOCK_CR_FIC1_MASK},
+ {MSS_PERIPH_FIC2,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC2,SUBBLK_CLOCK_CR_FIC2_MASK},
+ {MSS_PERIPH_FIC3,CONTEXT_EN_INDEX_FIC, CONTEXT_EN_MASK_FIC3,SUBBLK_CLOCK_CR_FIC3_MASK}
+};
+
+/**
+ * If contexts set-up, verify allowed access to peripheral
+ * @param option - Two option, , FIC enables set separately. CONTEXT_EN_INDEX_FIC or CONTEXT_EN_INDEX
+ * @param periph_context_mask See CONTEXT_EN_MASK_ defines for options
+ * @param hart The hart ID of origin of request.
+ * @return
+ */
+static inline uint8_t verify_context_enable(uint8_t option, uint32_t periph_context_mask , uint32_t hart)
+{
+ uint8_t result = 1U;
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ if (hart != (uint8_t) 0U)
+ {
+ if (LIBERO_SETTING_CONTEXT_A_HART_EN & hart )
+ {
+ if (LIBERO_SETTING_CONTEXT_EN[option][0U] & periph_context_mask)
+ {
+ result = 0U;
+ }
+ }
+
+ if (LIBERO_SETTING_CONTEXT_B_HART_EN & hart )
+ {
+ if (LIBERO_SETTING_CONTEXT_EN[option][1U] & periph_context_mask)
+ {
+ result = 0U;
+ }
+ }
+ }
+ else
+ {
+ hart = 0U;
+ }
+#else
+ (void)hart;
+ (void)periph_context_mask;
+ (void)option;
+ result = 0U;
+#endif
+ return result;
+}
+
+/**
+ * Turn on/off mss peripheral as required
+ * @param peripheral_mask
+ * @param req_state
+ */
+static inline void peripheral_on_off(uint32_t peripheral_mask , PERIPH_RESET_STATE req_state)
+{
+ if (req_state == PERIPHERAL_OFF)
+ {
+ /* Turn off clock */
+ SYSREG->SUBBLK_CLOCK_CR &= (uint32_t)~(peripheral_mask);
+ /* Hold in reset */
+ SYSREG->SOFT_RESET_CR |= (uint32_t)(peripheral_mask);
+ }
+ else
+ {
+ /* Turn on clock */
+ SYSREG->SUBBLK_CLOCK_CR |= (peripheral_mask);
+ /* Remove soft reset */
+ SYSREG->SOFT_RESET_CR &= (uint32_t)~(peripheral_mask);
+ }
+}
+
+
+/***************************************************************************//**
+ * See mss_peripherals.h for details of how to use this function.
+ */
+__attribute__((weak)) uint8_t mss_config_clk_rst(mss_peripherals peripheral, uint8_t hart, PERIPH_RESET_STATE req_state)
+{
+ uint8_t result = 1U;
+
+ ASSERT(PERIPHERAL_SETUP[peripheral][PERIPHERAL_INDEX_OFFSET] == peripheral);
+
+ result = verify_context_enable(PERIPHERAL_SETUP[peripheral][CONTEXT_EN_INDEX_OFFSET], PERIPHERAL_SETUP[peripheral][CONTEXT_MASK_INDEX_OFFSET] , hart);
+
+ if (result == 0U)
+ {
+ peripheral_on_off(PERIPHERAL_SETUP[peripheral][CONTEXT_SUBCLK_INDEX_OFFSET] , req_state);
+ }
+ return result;
+}
+
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_peripherals.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_peripherals.h
new file mode 100644
index 00000000..0f6f217c
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_peripherals.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_peripherals.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS fumnctions related to MSS peripherals.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_PERIPHERALS_H
+#define MSS_PERIPHERALS_H
+
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_CONTEXT_A_EN)
+#define LIBERO_SETTING_CONTEXT_A_EN 0x00000000UL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_EN)
+#define LIBERO_SETTING_CONTEXT_B_EN 0x00000000UL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_A_EN_FIC)
+#define LIBERO_SETTING_CONTEXT_A_EN_FIC 0x0000000FUL
+#endif
+#if !defined (LIBERO_SETTING_CONTEXT_B_EN_FIC)
+#define LIBERO_SETTING_CONTEXT_B_EN_FIC 0x0000000FUL
+#endif
+
+/***************************************************************************//**
+
+ */
+typedef enum PERIPH_RESET_STATE_
+{
+
+ PERIPHERAL_ON = 0x00, /*!< 0 RST and clk ON */
+ PERIPHERAL_OFF = 0x01, /*!< 1 RST and clk OFF */
+} PERIPH_RESET_STATE;
+
+#define CONTEXT_EN_INDEX 0x00U
+#define CONTEXT_EN_INDEX_FIC 0x01U
+#define SUBBLK_CLOCK_NA_MASK 0x00U
+
+typedef enum mss_peripherals_ {
+ MSS_PERIPH_MMUART0 = 0U,
+ MSS_PERIPH_MMUART1 = 1U,
+ MSS_PERIPH_MMUART2 = 2U,
+ MSS_PERIPH_MMUART3 = 3U,
+ MSS_PERIPH_MMUART4 = 4U,
+ MSS_PERIPH_WDOG0 = 5U,
+ MSS_PERIPH_WDOG1 = 6U,
+ MSS_PERIPH_WDOG2 = 7U,
+ MSS_PERIPH_WDOG3 = 8U,
+ MSS_PERIPH_WDOG4 = 9U,
+ MSS_PERIPH_SPI0 = 10U,
+ MSS_PERIPH_SPI1 = 11U,
+ MSS_PERIPH_I2C0 = 12U,
+ MSS_PERIPH_I2C1 = 13U,
+ MSS_PERIPH_CAN0 = 14U,
+ MSS_PERIPH_CAN1 = 15U,
+ MSS_PERIPH_MAC0 = 16U,
+ MSS_PERIPH_MAC1 = 17U,
+ MSS_PERIPH_TIMER = 18U,
+ MSS_PERIPH_GPIO0 = 19U,
+ MSS_PERIPH_GPIO1 = 20U,
+ MSS_PERIPH_GPIO2 = 21U,
+ MSS_PERIPH_RTC = 22U,
+ MSS_PERIPH_H2FINT = 23U,
+ MSS_PERIPH_CRYPTO = 24U,
+ MSS_PERIPH_USB = 25U,
+ MSS_PERIPH_QSPIXIP = 26U,
+ MSS_PERIPH_ATHENA = 27U,
+ MSS_PERIPH_TRACE = 28U,
+ MSS_PERIPH_MAILBOX_SC = 29U,
+ MSS_PERIPH_EMMC = 30U,
+ MSS_PERIPH_CFM = 31U,
+ MSS_PERIPH_FIC0 = 32U,
+ MSS_PERIPH_FIC1 = 33U,
+ MSS_PERIPH_FIC2 = 34U,
+ MSS_PERIPH_FIC3 = 35U
+} mss_peripherals;
+
+
+/***************************************************************************//**
+ This function is used to turn on or off a peripheral. If contexts have been
+ configured, these will be checked to see if peripheral should be controlled
+ from a particular context.
+
+ @param peripheral
+ See enum mss_peripherals for list of peripherals
+
+ @param hart
+ Origin hart of this request
+
+ @req_state
+ Turn peripheral on or off:
+ - PERIPHERAL_ON
+ - PERIPHERAL_OFF
+ Example:
+ @code
+ uint8_t err_status;
+ err_status = mss_config_clk_rst(MSS_PERIPH_MMUART0, (uint8_t) origin_hart_ID, PERIPHERAL_ON);
+
+ if(0U != err_status)
+ {
+ print_uart0("\n\r Context not allowed to access UART0 from hart:%d\n\nr", origin_hart_ID);
+ }
+ @endcode
+ */
+uint8_t mss_config_clk_rst(mss_peripherals peripheral, uint8_t hart, PERIPH_RESET_STATE req_state);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_PERIPHERALS_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_plic.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_plic.c
new file mode 100644
index 00000000..15297e97
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_plic.c
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_plic.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PLIC and PRCI access data structures and functions.
+ *
+ * PLIC related data which cannot be placed in mss_plic.h
+ *
+ */
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const unsigned long plic_hart_lookup[5U] = {0U, 1U, 3U, 5U, 7U};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_plic.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_plic.h
new file mode 100644
index 00000000..16c16029
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_plic.h
@@ -0,0 +1,1026 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/*******************************************************************************
+ *
+ * @file mss_plic.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PLIC and PRCI access data structures and functions.
+ *
+ * Definitions and functions associated with PLIC interrupts.
+ *
+ */
+#ifndef MSS_PLIC_H
+#define MSS_PLIC_H
+
+#include
+#ifndef CONFIG_OPENSBI
+#include "encoding.h"
+#endif
+
+#include "mss_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *Return value from External IRQ handler. This will be used to disable the
+ *Return External interrupt.
+ */
+#define EXT_IRQ_KEEP_ENABLED 0U
+#define EXT_IRQ_DISABLE 1U
+
+/*------------------------------------------------------------------------------
+ *
+ */
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+uint8_t Invalid_IRQHandler(void);
+uint8_t l2_metadata_corr_IRQHandler(void);
+uint8_t l2_metadata_uncorr_IRQHandler(void);
+uint8_t l2_data_corr_IRQHandler(void);
+uint8_t l2_data_uncorr_IRQHandler(void);
+uint8_t dma_ch0_DONE_IRQHandler(void);
+uint8_t dma_ch0_ERR_IRQHandler(void);
+uint8_t dma_ch1_DONE_IRQHandler(void);
+uint8_t dma_ch1_ERR_IRQHandler(void);
+uint8_t dma_ch2_DONE_IRQHandler(void);
+uint8_t dma_ch2_ERR_IRQHandler(void);
+uint8_t dma_ch3_DONE_IRQHandler(void);
+uint8_t dma_ch3_ERR_IRQHandler(void);
+uint8_t gpio0_bit0_or_gpio2_bit13_plic_0_IRQHandler(void);
+uint8_t gpio0_bit1_or_gpio2_bit13_plic_1_IRQHandler(void);
+uint8_t gpio0_bit2_or_gpio2_bit13_plic_2_IRQHandler(void);
+uint8_t gpio0_bit3_or_gpio2_bit13_plic_3_IRQHandler(void);
+uint8_t gpio0_bit4_or_gpio2_bit13_plic_4_IRQHandler(void);
+uint8_t gpio0_bit5_or_gpio2_bit13_plic_5_IRQHandler(void);
+uint8_t gpio0_bit6_or_gpio2_bit13_plic_6_IRQHandler(void);
+uint8_t gpio0_bit7_or_gpio2_bit13_plic_7_IRQHandler(void);
+uint8_t gpio0_bit8_or_gpio2_bit13_plic_8_IRQHandler(void);
+uint8_t gpio0_bit9_or_gpio2_bit13_plic_9_IRQHandler(void);
+uint8_t gpio0_bit10_or_gpio2_bit13_plic_10_IRQHandler(void);
+uint8_t gpio0_bit11_or_gpio2_bit13_plic_11_IRQHandler(void);
+uint8_t gpio0_bit12_or_gpio2_bit13_plic_12_IRQHandler(void);
+
+uint8_t gpio0_bit13_or_gpio2_bit13_plic_13_IRQHandler(void);
+uint8_t gpio1_bit0_or_gpio2_bit14_plic_14_IRQHandler(void);
+uint8_t gpio1_bit1_or_gpio2_bit15_plic_15_IRQHandler(void);
+uint8_t gpio1_bit2_or_gpio2_bit16_plic_16_IRQHandler(void);
+uint8_t gpio1_bit3_or_gpio2_bit17_plic_17_IRQHandler(void);
+uint8_t gpio1_bit4_or_gpio2_bit18_plic_18_IRQHandler(void);
+uint8_t gpio1_bit5_or_gpio2_bit19_plic_19_IRQHandler(void);
+uint8_t gpio1_bit6_or_gpio2_bit20_plic_20_IRQHandler(void);
+uint8_t gpio1_bit7_or_gpio2_bit21_plic_21_IRQHandler(void);
+uint8_t gpio1_bit8_or_gpio2_bit22_plic_22_IRQHandler(void);
+uint8_t gpio1_bit9_or_gpio2_bit23_plic_23_IRQHandler(void);
+uint8_t gpio1_bit10_or_gpio2_bit24_plic_24_IRQHandler(void);
+uint8_t gpio1_bit11_or_gpio2_bit25_plic_25_IRQHandler(void);
+uint8_t gpio1_bit12_or_gpio2_bit26_plic_26_IRQHandler(void);
+uint8_t gpio1_bit13_or_gpio2_bit27_plic_27_IRQHandler(void);
+
+uint8_t gpio1_bit14_or_gpio2_bit28_plic_28_IRQHandler(void);
+uint8_t gpio1_bit15_or_gpio2_bit29_plic_29_IRQHandler(void);
+uint8_t gpio1_bit16_or_gpio2_bit30_plic_30_IRQHandler(void);
+uint8_t gpio1_bit17_or_gpio2_bit31_plic_31_IRQHandler(void);
+
+uint8_t gpio1_bit18_plic_32_IRQHandler(void);
+uint8_t gpio1_bit19_plic_33_IRQHandler(void);
+uint8_t gpio1_bit20_plic_34_IRQHandler(void);
+uint8_t gpio1_bit21_plic_35_IRQHandler(void);
+uint8_t gpio1_bit22_plic_36_IRQHandler(void);
+uint8_t gpio1_bit23_plic_37_IRQHandler(void);
+
+uint8_t gpio0_non_direct_plic_IRQHandler(void);
+uint8_t gpio1_non_direct_plic_IRQHandler(void);
+uint8_t gpio2_non_direct_plic_IRQHandler(void);
+
+uint8_t spi0_plic_IRQHandler(void);
+uint8_t spi1_plic_IRQHandler(void);
+uint8_t external_can0_plic_IRQHandler(void);
+uint8_t can1_IRQHandler(void);
+uint8_t External_i2c0_main_plic_IRQHandler(void);
+uint8_t External_i2c0_alert_plic_IRQHandler(void);
+uint8_t i2c0_sus_plic_IRQHandler(void);
+uint8_t i2c1_main_plic_IRQHandler(void);
+uint8_t i2c1_alert_plic_IRQHandler(void);
+uint8_t i2c1_sus_plic_IRQHandler(void);
+uint8_t mac0_int_plic_IRQHandler(void);
+uint8_t mac0_queue1_plic_IRQHandler(void);
+uint8_t mac0_queue2_plic_IRQHandler(void);
+uint8_t mac0_queue3_plic_IRQHandler(void);
+uint8_t mac0_emac_plic_IRQHandler(void);
+uint8_t mac0_mmsl_plic_IRQHandler(void);
+uint8_t mac1_int_plic_IRQHandler(void);
+uint8_t mac1_queue1_plic_IRQHandler(void);
+uint8_t mac1_queue2_plic_IRQHandler(void);
+uint8_t mac1_queue3_plic_IRQHandler(void);
+uint8_t mac1_emac_plic_IRQHandler(void);
+uint8_t mac1_mmsl_plic_IRQHandler(void);
+uint8_t ddrc_train_plic_IRQHandler(void);
+uint8_t scb_interrupt_plic_IRQHandler(void);
+uint8_t ecc_error_plic_IRQHandler(void);
+uint8_t ecc_correct_plic_IRQHandler(void);
+uint8_t rtc_wakeup_plic_IRQHandler(void);
+uint8_t rtc_match_plic_IRQHandler(void);
+uint8_t timer1_plic_IRQHandler(void);
+uint8_t timer2_plic_IRQHandler(void);
+uint8_t envm_plic_IRQHandler(void);
+uint8_t qspi_plic_IRQHandler(void);
+uint8_t usb_dma_plic_IRQHandler(void);
+uint8_t usb_mc_plic_IRQHandler(void);
+uint8_t mmc_main_plic_IRQHandler(void);
+uint8_t mmc_wakeup_plic_IRQHandler(void);
+uint8_t mmuart0_plic_77_IRQHandler(void);
+uint8_t mmuart1_plic_IRQHandler(void);
+uint8_t mmuart2_plic_IRQHandler(void);
+uint8_t mmuart3_plic_IRQHandler(void);
+uint8_t mmuart4_plic_IRQHandler(void);
+uint8_t g5c_devrst_plic_IRQHandler(void);
+uint8_t g5c_message_plic_IRQHandler(void);
+uint8_t usoc_vc_interrupt_plic_IRQHandler(void);
+uint8_t usoc_smb_interrupt_plic_IRQHandler(void);
+uint8_t e51_0_Maintence_plic_IRQHandler(void);
+
+uint8_t wdog0_mvrp_plic_IRQHandler(void);
+uint8_t wdog1_mvrp_plic_IRQHandler(void);
+uint8_t wdog2_mvrp_plic_IRQHandler(void);
+uint8_t wdog3_mvrp_plic_IRQHandler(void);
+uint8_t wdog4_mvrp_plic_IRQHandler(void);
+uint8_t wdog0_tout_plic_IRQHandler(void);
+uint8_t wdog1_tout_plic_IRQHandler(void);
+uint8_t wdog2_tout_plic_IRQHandler(void);
+uint8_t wdog3_tout_plic_IRQHandler(void);
+uint8_t wdog4_tout_plic_IRQHandler(void);
+uint8_t g5c_mss_spi_plic_IRQHandler(void);
+uint8_t volt_temp_alarm_plic_IRQHandler(void);
+
+uint8_t athena_complete_plic_IRQHandler(void);
+uint8_t athena_alarm_plic_IRQHandler(void);
+uint8_t athena_bus_error_plic_IRQHandler(void);
+uint8_t usoc_axic_us_plic_IRQHandler(void);
+uint8_t usoc_axic_ds_plic_IRQHandler(void);
+
+uint8_t reserved_104_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_0_plic_IRQHandler(void);
+uint8_t fabric_f2h_1_plic_IRQHandler(void);
+uint8_t fabric_f2h_2_plic_IRQHandler(void);
+uint8_t fabric_f2h_3_plic_IRQHandler(void);
+uint8_t fabric_f2h_4_plic_IRQHandler(void);
+uint8_t fabric_f2h_5_plic_IRQHandler(void);
+uint8_t fabric_f2h_6_plic_IRQHandler(void);
+uint8_t fabric_f2h_7_plic_IRQHandler(void);
+uint8_t fabric_f2h_8_plic_IRQHandler(void);
+uint8_t fabric_f2h_9_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_10_plic_IRQHandler(void);
+uint8_t fabric_f2h_11_plic_IRQHandler(void);
+uint8_t fabric_f2h_12_plic_IRQHandler(void);
+uint8_t fabric_f2h_13_plic_IRQHandler(void);
+uint8_t fabric_f2h_14_plic_IRQHandler(void);
+uint8_t fabric_f2h_15_plic_IRQHandler(void);
+uint8_t fabric_f2h_16_plic_IRQHandler(void);
+uint8_t fabric_f2h_17_plic_IRQHandler(void);
+uint8_t fabric_f2h_18_plic_IRQHandler(void);
+uint8_t fabric_f2h_19_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_20_plic_IRQHandler(void);
+uint8_t fabric_f2h_21_plic_IRQHandler(void);
+uint8_t fabric_f2h_22_plic_IRQHandler(void);
+uint8_t fabric_f2h_23_plic_IRQHandler(void);
+uint8_t fabric_f2h_24_plic_IRQHandler(void);
+uint8_t fabric_f2h_25_plic_IRQHandler(void);
+uint8_t fabric_f2h_26_plic_IRQHandler(void);
+uint8_t fabric_f2h_27_plic_IRQHandler(void);
+uint8_t fabric_f2h_28_plic_IRQHandler(void);
+uint8_t fabric_f2h_29_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_30_plic_IRQHandler(void);
+uint8_t fabric_f2h_31_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_32_plic_IRQHandler(void);
+uint8_t fabric_f2h_33_plic_IRQHandler(void);
+uint8_t fabric_f2h_34_plic_IRQHandler(void);
+uint8_t fabric_f2h_35_plic_IRQHandler(void);
+uint8_t fabric_f2h_36_plic_IRQHandler(void);
+uint8_t fabric_f2h_37_plic_IRQHandler(void);
+uint8_t fabric_f2h_38_plic_IRQHandler(void);
+uint8_t fabric_f2h_39_plic_IRQHandler(void);
+uint8_t fabric_f2h_40_plic_IRQHandler(void);
+uint8_t fabric_f2h_41_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_42_plic_IRQHandler(void);
+uint8_t fabric_f2h_43_plic_IRQHandler(void);
+uint8_t fabric_f2h_44_plic_IRQHandler(void);
+uint8_t fabric_f2h_45_plic_IRQHandler(void);
+uint8_t fabric_f2h_46_plic_IRQHandler(void);
+uint8_t fabric_f2h_47_plic_IRQHandler(void);
+uint8_t fabric_f2h_48_plic_IRQHandler(void);
+uint8_t fabric_f2h_49_plic_IRQHandler(void);
+uint8_t fabric_f2h_50_plic_IRQHandler(void);
+uint8_t fabric_f2h_51_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_52_plic_IRQHandler(void);
+uint8_t fabric_f2h_53_plic_IRQHandler(void);
+uint8_t fabric_f2h_54_plic_IRQHandler(void);
+uint8_t fabric_f2h_55_plic_IRQHandler(void);
+uint8_t fabric_f2h_56_plic_IRQHandler(void);
+uint8_t fabric_f2h_57_plic_IRQHandler(void);
+uint8_t fabric_f2h_58_plic_IRQHandler(void);
+uint8_t fabric_f2h_59_plic_IRQHandler(void);
+uint8_t fabric_f2h_60_plic_IRQHandler(void);
+uint8_t fabric_f2h_61_plic_IRQHandler(void);
+
+uint8_t fabric_f2h_62_plic_IRQHandler(void);
+uint8_t fabric_f2h_63_plic_IRQHandler(void);
+
+uint8_t bus_error_unit_hart_0_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_1_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_2_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_3_plic_IRQHandler(void);
+uint8_t bus_error_unit_hart_4_plic_IRQHandler(void);
+
+
+#else
+uint8_t Invalid_IRQHandler(void);
+uint8_t External_1_IRQHandler(void);
+uint8_t External_2_IRQHandler(void);
+uint8_t External_3_IRQHandler(void);
+uint8_t USART0_plic_4_IRQHandler(void);
+uint8_t External_5_IRQHandler(void);
+uint8_t External_6_IRQHandler(void);
+uint8_t External_7_IRQHandler(void);
+uint8_t External_8_IRQHandler(void);
+uint8_t External_9_IRQHandler(void);
+uint8_t External_10_IRQHandler(void);
+uint8_t External_11_IRQHandler(void);
+uint8_t External_12_IRQHandler(void);
+uint8_t External_13_IRQHandler(void);
+uint8_t External_14_IRQHandler(void);
+uint8_t External_15_IRQHandler(void);
+uint8_t External_16_IRQHandler(void);
+uint8_t External_17_IRQHandler(void);
+uint8_t External_18_IRQHandler(void);
+uint8_t External_19_IRQHandler(void);
+uint8_t External_20_IRQHandler(void);
+uint8_t External_21_IRQHandler(void);
+uint8_t External_22_IRQHandler(void);
+uint8_t dma_ch0_DONE_IRQHandler(void);
+uint8_t dma_ch0_ERR_IRQHandler(void);
+uint8_t dma_ch1_DONE_IRQHandler(void);
+uint8_t dma_ch1_ERR_IRQHandler(void);
+uint8_t dma_ch2_DONE_IRQHandler(void);
+uint8_t dma_ch2_ERR_IRQHandler(void);
+uint8_t dma_ch3_DONE_IRQHandler(void);
+uint8_t dma_ch3_ERR_IRQHandler(void);
+uint8_t External_31_IRQHandler(void);
+uint8_t External_32_IRQHandler(void);
+uint8_t External_33_IRQHandler(void);
+uint8_t External_34_IRQHandler(void);
+uint8_t External_35_IRQHandler(void);
+uint8_t External_36_IRQHandler(void);
+uint8_t External_37_IRQHandler(void);
+uint8_t External_38_IRQHandler(void);
+uint8_t External_39_IRQHandler(void);
+uint8_t External_40_IRQHandler(void);
+uint8_t External_41_IRQHandler(void);
+uint8_t External_42_IRQHandler(void);
+uint8_t External_43_IRQHandler(void);
+uint8_t External_44_IRQHandler(void);
+uint8_t External_45_IRQHandler(void);
+uint8_t External_46_IRQHandler(void);
+uint8_t External_47_IRQHandler(void);
+uint8_t External_48_IRQHandler(void);
+uint8_t External_49_IRQHandler(void);
+uint8_t External_50_IRQHandler(void);
+uint8_t External_51_IRQHandler(void);
+uint8_t External_52_IRQHandler(void);
+uint8_t MAC0_plic_53_IRQHandler(void);
+
+#endif
+
+/***************************************************************************//**
+ * PLIC source Interrupt numbers:
+ */
+/* See section on PLIC Interrupt Sources in User Guide */
+#define OFFSET_TO_MSS_GLOBAL_INTS 13U
+typedef enum
+{
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+ INVALID_IRQn = 0,
+ L2_METADATA_CORR_IRQn = 1,
+ L2_METADAT_UNCORR_IRQn = 2,
+ L2_DATA_CORR_IRQn = 3,
+ L2_DATA_UNCORR_IRQn = 4,
+ DMA_CH0_DONE_IRQn = 5,
+ DMA_CH0_ERR_IRQn = 6,
+ DMA_CH1_DONE_IRQn = 7,
+ DMA_CH1_ERR_IRQn = 8,
+ DMA_CH2_DONE_IRQn = 9,
+ DMA_CH2_ERR_IRQn = 10,
+ DMA_CH3_DONE_IRQn = 11,
+ DMA_CH3_ERR_IRQn = 12,
+ /* see GPIO Interrupt Multiplexing in the User Guide */
+ GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0 = 0 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1 = 1 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2 = 2 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3 = 3 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4 = 4 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5 = 5 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6 = 6 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7 = 7 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8 = 8 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9 = 9 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10 = 10 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11 = 11 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12 = 12 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO0_BIT13_or_GPIO2_BIT13_PLIC_13 = 13 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14 = 14 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15 = 15 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16 = 16 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17 = 17 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18 = 18 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19 = 19 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT6_or_GPIO2_BIT20_PLIC_20 = 20 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT7_or_GPIO2_BIT21_PLIC_21 = 21 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT8_or_GPIO2_BIT22_PLIC_22 = 22 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT9_or_GPIO2_BIT23_PLIC_23 = 23 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT10_or_GPIO2_BIT24_PLIC_24 = 24 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT11_or_GPIO2_BIT25_PLIC_25 = 25 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT12_or_GPIO2_BIT26_PLIC_26 = 26 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT13_or_GPIO2_BIT27_PLIC_27 = 27 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO1_BIT14_or_GPIO2_BIT28_PLIC_28 = 28 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT15_or_GPIO2_BIT29_PLIC_29 = 29 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT16_or_GPIO2_BIT30_PLIC_30 = 30 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT17_or_GPIO2_BIT31_PLIC_31 = 31 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO1_BIT18_PLIC_32 = 32 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT19_PLIC_33 = 33 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT20_PLIC_34 = 34 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT21_PLIC_35 = 35 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT22_PLIC_36 = 36 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_BIT23_PLIC_37 = 37 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ GPIO0_NON_DIRECT_PLIC = 38 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO1_NON_DIRECT_PLIC = 39 + OFFSET_TO_MSS_GLOBAL_INTS,
+ GPIO2_NON_DIRECT_PLIC = 40 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ SPI0_PLIC = 41 + OFFSET_TO_MSS_GLOBAL_INTS,
+ SPI1_PLIC = 42 + OFFSET_TO_MSS_GLOBAL_INTS,
+ CAN0_PLIC = 43 + OFFSET_TO_MSS_GLOBAL_INTS,
+ CAN1_PLIC = 44 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_MAIN_PLIC = 45 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_ALERT_PLIC = 46 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C0_SUS_PLIC = 47 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_MAIN_PLIC = 48 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_ALERT_PLIC = 49 + OFFSET_TO_MSS_GLOBAL_INTS,
+ I2C1_SUS_PLIC = 50 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_INT_PLIC = 51 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE1_PLIC = 52 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE2_PLIC = 53 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_QUEUE3_PLIC = 54 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_EMAC_PLIC = 55 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC0_MMSL_PLIC = 56 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_INT_PLIC = 57 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE1_PLIC = 58 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE2_PLIC = 59 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_QUEUE3_PLIC = 60 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_EMAC_PLIC = 61 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MAC1_MMSL_PLIC = 62 + OFFSET_TO_MSS_GLOBAL_INTS,
+ DDRC_TRAIN_PLIC = 63 + OFFSET_TO_MSS_GLOBAL_INTS,
+ SCB_INTERRUPT_PLIC = 64 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ECC_ERROR_PLIC = 65 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ECC_CORRECT_PLIC = 66 + OFFSET_TO_MSS_GLOBAL_INTS,
+ RTC_WAKEUP_PLIC = 67 + OFFSET_TO_MSS_GLOBAL_INTS,
+ RTC_MATCH_PLIC = 68 + OFFSET_TO_MSS_GLOBAL_INTS,
+ TIMER1_PLIC = 69 + OFFSET_TO_MSS_GLOBAL_INTS,
+ TIMER2_PLIC = 70 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ENVM_PLIC = 71 + OFFSET_TO_MSS_GLOBAL_INTS,
+ QSPI_PLIC = 72 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USB_DMA_PLIC = 73 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USB_MC_PLIC = 74 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMC_main_PLIC = 75 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMC_wakeup_PLIC = 76 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART0_PLIC_77 = 77 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART1_PLIC = 78 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART2_PLIC = 79 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART3_PLIC = 80 + OFFSET_TO_MSS_GLOBAL_INTS,
+ MMUART4_PLIC = 81 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ G5C_DEVRST_PLIC = 82 + OFFSET_TO_MSS_GLOBAL_INTS,
+ g5c_MESSAGE_PLIC = 83 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_VC_INTERRUPT_PLIC = 84 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_SMB_INTERRUPT_PLIC = 85 + OFFSET_TO_MSS_GLOBAL_INTS,
+ /* contains multiple interrupts- */
+ E51_0_MAINTENACE_PLIC = 86 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ WDOG0_MRVP_PLIC = 87 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG1_MRVP_PLIC = 88 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG2_MRVP_PLIC = 89 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG3_MRVP_PLIC = 90 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG4_MRVP_PLIC = 91 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG0_TOUT_PLIC = 92 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG1_TOUT_PLIC = 93 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG2_TOUT_PLIC = 94 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG3_TOUT_PLIC = 95 + OFFSET_TO_MSS_GLOBAL_INTS,
+ WDOG4_TOUT_PLIC = 96 + OFFSET_TO_MSS_GLOBAL_INTS,
+ G5C_MSS_SPI_PLIC = 97 + OFFSET_TO_MSS_GLOBAL_INTS,
+ VOLT_TEMP_ALARM_PLIC = 98 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_COMPLETE_PLIC = 99 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_ALARM_PLIC = 100 + OFFSET_TO_MSS_GLOBAL_INTS,
+ ATHENA_BUS_ERROR_PLIC = 101 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_AXIC_US_PLIC = 102 + OFFSET_TO_MSS_GLOBAL_INTS,
+ USOC_AXIC_DS_PLIC = 103 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_0_PLIC = 105 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_1_PLIC = 106 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_2_PLIC = 107 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_3_PLIC = 108 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_4_PLIC = 109 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_5_PLIC = 110 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_6_PLIC = 111 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_7_PLIC = 112 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_8_PLIC = 113 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_9_PLIC = 114 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_10_PLIC = 115 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_11_PLIC = 116 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_12_PLIC = 117 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_13_PLIC = 118 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_14_PLIC = 119 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_15_PLIC = 120 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_16_PLIC = 121 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_17_PLIC = 122 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_18_PLIC = 123 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_19_PLIC = 124 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_20_PLIC = 125 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_21_PLIC = 126 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_22_PLIC = 127 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_23_PLIC = 128 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_24_PLIC = 129 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_25_PLIC = 130 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_26_PLIC = 131 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_27_PLIC = 132 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_28_PLIC = 133 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_29_PLIC = 134 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_30_PLIC = 135 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_31_PLIC = 136 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_32_PLIC = 137 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_33_PLIC = 138 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_34_PLIC = 139 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_35_PLIC = 140 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_36_PLIC = 141 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_37_PLIC = 142 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_38_PLIC = 143 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_39_PLIC = 144 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_40_PLIC = 145 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_41_PLIC = 146 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_42_PLIC = 147 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_43_PLIC = 148 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_44_PLIC = 149 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_45_PLIC = 150 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_46_PLIC = 151 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_47_PLIC = 152 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_48_PLIC = 153 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_49_PLIC = 154 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_50_PLIC = 155 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_51_PLIC = 156 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_52_PLIC = 157 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_53_PLIC = 158 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_54_PLIC = 159 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_55_PLIC = 160 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_56_PLIC = 161 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_57_PLIC = 162 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_58_PLIC = 163 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_59_PLIC = 164 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_60_PLIC = 165 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_61_PLIC = 166 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ FABRIC_F2H_62_PLIC = 167 + OFFSET_TO_MSS_GLOBAL_INTS,
+ FABRIC_F2H_63_PLIC = 168 + OFFSET_TO_MSS_GLOBAL_INTS,
+
+ BUS_ERROR_UNIT_HART_0 = 182,
+ BUS_ERROR_UNIT_HART_1 = 183,
+ BUS_ERROR_UNIT_HART_2 = 184,
+ BUS_ERROR_UNIT_HART_3 = 185,
+ BUS_ERROR_UNIT_HART_4 = 186
+
+#else
+ INVALID_IRQn = 0,
+ L2Cache_0_PLIC_1 = 1,
+ L2Cache_1_PLIC_2 = 2,
+ L2Cache_2__PLIC_3 = 3,
+ USART0_PLIC_4 = 4,
+ USART1_PLIC_5 = 5,
+ QSPI_12_PLIC_6 = 6,
+
+ gpio_PLIC_7 = 7,
+ gpio_PLIC_8 = 8,
+ gpio_PLIC_9 = 9,
+ gpio_10 = 10,
+ gpio_11 = 11,
+ gpio_12 = 12,
+ gpio_PLIC_13 = 13,
+ gpio_PLIC_14 = 14,
+ gpio_PLIC_15 = 15,
+ gpio_PLIC_16 = 16,
+ gpio_PLIC_17 = 17,
+ gpio_PLIC_18 = 18,
+ gpio_PLIC_19 = 19,
+ gpio_PLIC_20 = 20,
+ gpio_PLIC_21 = 21,
+ gpio_PLIC_22 = 22,
+
+ dma_PLIC_23 = 23,
+ dma_PLIC_24 = 24,
+ dma_PLIC_25 = 25,
+ dma_PLIC_26 = 26,
+ dma_PLIC_27 = 27,
+ dma_PLIC_28 = 28,
+ dma_PLIC_29 = 29,
+ dma_PLIC_30 = 30,
+
+ ddr_subsytem_PLIC_31 = 31,
+
+ chiplink_msi_PLIC_32 = 32,
+ chiplink_msi_PLIC_33 = 33,
+ chiplink_msi_PLIC_34 = 34,
+ chiplink_msi_PLIC_35 = 35,
+ chiplink_msi_PLIC_36 = 36,
+ chiplink_msi_PLIC_37 = 37,
+ chiplink_msi_PLIC_38 = 38,
+ chiplink_msi_PLIC_39 = 39,
+ chiplink_msi_PLIC_40 = 40,
+ chiplink_msi_PLIC_41 = 41,
+
+ pwm0_PLIC_42 = 42,
+ pwm0_PLIC_43 = 43,
+ pwm0_PLIC_44 = 44,
+ pwm0_PLIC_45 = 45,
+
+ pwm1_PLIC_46 = 46,
+ pwm1_PLIC_47 = 47,
+ pwm1_PLIC_48 = 48,
+ pwm1_PLIC_49 = 49,
+
+ i2c_PLIC_50 = 50,
+ QSPI0_PLIC_51 = 51,
+ QSPI1_PLIC_52 = 52,
+ ethernet_PLIC_53 = 53
+
+#endif
+
+} PLIC_IRQn_Type;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define MAX_PLIC_INT BUS_ERROR_UNIT_HART_4
+#else
+#define MAX_PLIC_INT ethernet_PLIC_53
+#endif
+
+/***************************************************************************//**
+ * E51-0 is Maintenance Interrupt, CPU needs to read status register to
+ * determine exact cause:
+ * This structure added here for clarity, need to replay with status register
+ * defines for determining interrupt cause
+ */
+typedef enum
+{
+ mpu_fail_plic =0,
+ lp_state_enter_plic =1,
+ lp_state_exit_plic =2,
+ ff_start_plic =3,
+ ff_end_plic =4,
+ fpga_on_plic =5,
+ fpga_off_plic =6,
+ scb_error_plic =7,
+ scb_fault_plic =8,
+ mesh_fail_plic =9
+} PLIC_IRQ86_Type;
+
+typedef struct
+{
+ volatile uint32_t PRIORITY_THRESHOLD;
+ volatile uint32_t CLAIM_COMPLETE;
+ volatile uint32_t reserved[(0x1000/4)-2];
+} IRQ_Target_Type;
+
+typedef struct
+{
+ volatile uint32_t ENABLES[32U];
+} Target_Enables_Type;
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define PLIC_SET_UP_REGISTERS 6U
+#else
+#define PLIC_SET_UP_REGISTERS 2U
+#endif
+
+#ifndef SIFIVE_HIFIVE_UNLEASHED
+#define PLIC_NUM_SOURCES 187U
+#else
+#define PLIC_NUM_SOURCES 54U /* 53 actual, source 0 is not used */
+#endif
+
+#define PLIC_NUM_PRIORITIES 7U
+#define NUM_CLAIM_REGS 9U
+
+
+/* The FU540-C000 has 53 interrupt sources. */
+ typedef struct
+{
+ volatile uint32_t RESERVED0;
+ /*-------------------- Source Priority --------------------*/
+ volatile uint32_t SOURCE_PRIORITY[PLIC_NUM_SOURCES];
+ volatile uint32_t RESERVED1[(0x1000 / 4) - (PLIC_NUM_SOURCES + 1)];
+ /*-------------------- Pending array --------------------*/
+ volatile const uint32_t PENDING_ARRAY[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED2[(0x1000/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart0 Mode Enables--------------------*/
+ volatile uint32_t HART0_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED3[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart1 Mode Enables--------------------*/
+ volatile uint32_t HART1_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED4a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART1_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED4[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart2 Mode Enables--------------------*/
+ volatile uint32_t HART2_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED5a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART2_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED5[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart3 Mode Enables--------------------*/
+ volatile uint32_t HART3_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED6a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART3_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED6[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ /*-----------------Hart4 Mode Enables--------------------*/
+ volatile uint32_t HART4_MMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED7a[(0x80/4) - PLIC_SET_UP_REGISTERS];
+ volatile uint32_t HART4_SMODE_ENA[PLIC_SET_UP_REGISTERS];
+ volatile uint32_t RESERVED7[(0x80/4) - PLIC_SET_UP_REGISTERS];
+
+ volatile uint32_t RESERVED8[(0x0C200000 - 0x0C002480)/4];
+
+ /*--- Target Priority threshold and claim/complete---------*/
+ IRQ_Target_Type TARGET[NUM_CLAIM_REGS]; /* See PLIC Register Map or
+ TARGET_OFFSET defines below
+ for offset details */
+
+} PLIC_Type;
+
+#define TARGET_OFFSET_HART0_M 0U
+#define TARGET_OFFSET_HART1_M 1U
+#define TARGET_OFFSET_HART1_S 2U
+#define TARGET_OFFSET_HART2_M 3U
+#define TARGET_OFFSET_HART2_S 4U
+#define TARGET_OFFSET_HART3_M 5U
+#define TARGET_OFFSET_HART3_S 6U
+#define TARGET_OFFSET_HART4_M 7U
+#define TARGET_OFFSET_HART4_S 8U
+
+extern const unsigned long plic_hart_lookup[5U];
+
+/***************************************************************************//**
+ * PLIC: Platform Level Interrupt Controller
+ */
+#define PLIC_BASE_ADDR 0x0C000000UL
+
+#define PLIC ((PLIC_Type * const)PLIC_BASE_ADDR)
+
+/*-------------------------------------------------------------------------*//**
+ * The function PLIC_init() initializes the PLIC controller and enables the
+ * global external interrupt bit.
+ */
+
+/*-----------------Hart Mode Enables--------------------*/
+
+static inline void PLIC_init(void)
+{
+ uint32_t inc;
+ uint64_t hart_id = read_csr(mhartid);
+
+ /* Disable all interrupts for the current hart. */
+ switch(hart_id)
+ {
+ case 0:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART0_MMODE_ENA[inc] = 0U;
+ }
+
+ /* Set the threshold to zero.
+ * PLIC provides context based threshold register for the settings of a
+ * interrupt priority threshold of each context. The threshold register
+ * is a WARL field. The PLIC will mask all PLIC interrupts of a priority
+ * less than or equal to threshold. For example, a threshold value of zero
+ * permits all interrupts with non-zero priority.*/
+
+ PLIC->TARGET[TARGET_OFFSET_HART0_M].PRIORITY_THRESHOLD = 0U;
+ break;
+ case 1:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART1_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART1_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART1_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 2:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART2_MMODE_ENA[inc] = 0U;
+ PLIC->HART2_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART2_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART2_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 3:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART3_MMODE_ENA[inc] = 0U;
+ PLIC->HART3_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART3_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART3_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ case 4:
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART4_MMODE_ENA[inc] = 0U;
+ PLIC->HART4_SMODE_ENA[inc] = 0U;
+ }
+
+ PLIC->TARGET[TARGET_OFFSET_HART4_M].PRIORITY_THRESHOLD = 0U;
+ /* Disable supervisor level */
+ PLIC->TARGET[TARGET_OFFSET_HART4_S].PRIORITY_THRESHOLD = 7U;
+ break;
+ default:
+ break;
+ }
+
+ /* Enable machine external interrupts. */
+ set_csr(mie, MIP_MEIP);
+}
+
+
+
+/***************************************************************************//**
+ * The function PLIC_EnableIRQ() enables the external interrupt for the
+ * interrupt number indicated by the parameter IRQn.
+ */
+static inline void PLIC_EnableIRQ(PLIC_IRQn_Type IRQn)
+{
+ uint32_t current;
+ uint64_t hart_id = read_csr(mhartid);
+
+ switch(hart_id)
+ {
+ case 0:
+ current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 1:
+ current = PLIC->HART1_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART1_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 2:
+ current = PLIC->HART2_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART2_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 3:
+ current = PLIC->HART3_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART3_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 4:
+ current = PLIC->HART4_MMODE_ENA[IRQn / 32U];
+ current |= (uint32_t)1 << (IRQn % 32U);
+ PLIC->HART4_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ default:
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_DisableIRQ() disables the external interrupt for the
+ * interrupt number indicated by the parameter IRQn.
+
+ * NOTE:
+ * This function can be used to disable the external interrupt from outside
+ * external interrupt handler function.
+ * This function MUST NOT be used from within the External Interrupt
+ * handler.
+ * If you wish to disable the external interrupt while the interrupt handler
+ * for that external interrupt is executing then you must use the return
+ * value EXT_IRQ_DISABLE to return from the extern interrupt handler.
+ */
+static inline void PLIC_DisableIRQ(PLIC_IRQn_Type IRQn)
+{
+ uint32_t current;
+ uint64_t hart_id = read_csr(mhartid);
+
+ switch(hart_id)
+ {
+ case 0:
+ current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 1:
+ current = PLIC->HART1_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART1_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 2:
+ current = PLIC->HART2_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART2_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 3:
+ current = PLIC->HART3_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART3_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ case 4:
+ current = PLIC->HART4_MMODE_ENA[IRQn / 32U];
+ current &= ~((uint32_t)1 << (IRQn % 32U));
+ PLIC->HART4_MMODE_ENA[IRQn / 32U] = current;
+ break;
+ default:
+ break;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_SetPriority() sets the priority for the external interrupt
+ * for the interrupt number indicated by the parameter IRQn.
+ */
+static inline void PLIC_SetPriority(PLIC_IRQn_Type IRQn, uint32_t priority)
+{
+ if((IRQn > INVALID_IRQn) && (IRQn < PLIC_NUM_SOURCES))
+ {
+ PLIC->SOURCE_PRIORITY[IRQn-1] = priority;
+ }
+}
+
+/***************************************************************************//**
+ * The function PLIC_GetPriority() returns the priority for the external
+ * interrupt for the interrupt number indicated by the parameter IRQn.
+ */
+static inline uint32_t PLIC_GetPriority(PLIC_IRQn_Type IRQn)
+{
+ uint32_t ret_val = 0U;
+
+ if((IRQn > INVALID_IRQn) && (IRQn < PLIC_NUM_SOURCES))
+ {
+ ret_val = PLIC->SOURCE_PRIORITY[IRQn-1];
+ }
+
+ return(ret_val);
+}
+
+
+static inline uint32_t PLIC_pending(PLIC_IRQn_Type IRQn)
+{
+ return (PLIC->PENDING_ARRAY[IRQn/32U] & (0x01U<<(IRQn%32U)));
+}
+
+/***************************************************************************//**
+ * The function PLIC_ClaimIRQ() claims the interrupt from the PLIC controller.
+ */
+static inline uint32_t PLIC_ClaimIRQ(void)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ return (PLIC->TARGET[plic_hart_lookup[hart_id]].CLAIM_COMPLETE);
+}
+
+/***************************************************************************//**
+ * The function PLIC_CompleteIRQ() indicates to the PLIC controller the
+ * interrupt is processed and claim is complete.
+ */
+static inline void PLIC_CompleteIRQ(uint32_t source)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ ASSERT(source <= MAX_PLIC_INT);
+
+ PLIC->TARGET[plic_hart_lookup[hart_id]].CLAIM_COMPLETE = source;
+}
+
+/***************************************************************************//**
+ *
+ * The function PLIC_SetPriority_Threshold() sets the threshold for a particular
+ * hart. The default threshold on reset is 0.
+ * The PFSoC Core Complex supports setting of an interrupt priority threshold
+ * via the threshold register. The threshold is a WARL field, where the PFSoC
+ * Core Complex supports a maximum threshold of 7.
+ * The PFSoC Core Complex will mask all PLIC interrupts of a priority less than
+ * or equal to threshold. For example, a threshold value of zero permits all
+ * interrupts with non-zero priority, whereas a value of 7 masks all
+ * interrupts.
+ */
+static inline void PLIC_SetPriority_Threshold(uint32_t threshold)
+{
+ uint64_t hart_id = read_csr(mhartid);
+
+ ASSERT(threshold <= 7);
+
+ PLIC->TARGET[plic_hart_lookup[hart_id]].PRIORITY_THRESHOLD = threshold;
+}
+
+/***************************************************************************//**
+ * PLIC_ClearPendingIRQ(void)
+ * This is only called by the startup hart and only once
+ * Clears any pending interrupts as PLIC can be in unknown state on startup
+ */
+static inline void PLIC_ClearPendingIRQ(void)
+{
+ volatile uint32_t int_num = PLIC_ClaimIRQ();
+ volatile int32_t wait_possible_int;
+
+ while ( int_num != INVALID_IRQn)
+ {
+ PLIC_CompleteIRQ(int_num);
+ wait_possible_int = 0xFU;
+ while (wait_possible_int)
+ {
+ wait_possible_int--;
+ }
+ int_num = PLIC_ClaimIRQ(); /* obtain interrupt, auto clears */
+ }
+}
+
+/***************************************************************************//**
+ * This function is only called from one hart on startup
+ */
+static inline void PLIC_init_on_reset(void)
+{
+ uint32_t inc;
+
+ /* default all priorities so effectively disabled */
+ for(inc = 0U; inc < PLIC_NUM_SOURCES; ++inc)
+ {
+ /* priority must be greater than threshold to be enabled, so setting to
+ * 7 disables */
+ PLIC->SOURCE_PRIORITY[inc] = 0U;
+ }
+
+ for(inc = 0U; inc < NUM_CLAIM_REGS; ++inc)
+ {
+ PLIC->TARGET[inc].PRIORITY_THRESHOLD = 7U;
+ }
+
+ /* and clear all the enables */
+ for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
+ {
+ PLIC->HART0_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_MMODE_ENA[inc] = 0U;
+ PLIC->HART1_SMODE_ENA[inc] = 0U;
+ PLIC->HART2_MMODE_ENA[inc] = 0U;
+ PLIC->HART2_SMODE_ENA[inc] = 0U;
+ PLIC->HART3_MMODE_ENA[inc] = 0U;
+ PLIC->HART3_SMODE_ENA[inc] = 0U;
+ PLIC->HART4_MMODE_ENA[inc] = 0U;
+ PLIC->HART4_SMODE_ENA[inc] = 0U;
+ }
+
+ /* clear any pending interrupts- in case already there */
+ PLIC_ClearPendingIRQ();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MSS_PLIC_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_pmp.c b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_pmp.c
new file mode 100644
index 00000000..2e21f5bb
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_pmp.c
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_pmp.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PMP configuration using MSS configurator values.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#include
+#include
+#include "mpfs_hal/mss_hal.h"
+
+/**
+ * \brief PMP configuration from Libero
+ *
+ */
+const uint64_t pmp_values[][18] = {
+ /* hart 0 */
+ {LIBERO_SETTING_HART0_CSR_PMPCFG0,
+ LIBERO_SETTING_HART0_CSR_PMPCFG2,
+ LIBERO_SETTING_HART0_CSR_PMPADDR0,
+ LIBERO_SETTING_HART0_CSR_PMPADDR1,
+ LIBERO_SETTING_HART0_CSR_PMPADDR2,
+ LIBERO_SETTING_HART0_CSR_PMPADDR3,
+ LIBERO_SETTING_HART0_CSR_PMPADDR4,
+ LIBERO_SETTING_HART0_CSR_PMPADDR5,
+ LIBERO_SETTING_HART0_CSR_PMPADDR6,
+ LIBERO_SETTING_HART0_CSR_PMPADDR7,
+ LIBERO_SETTING_HART0_CSR_PMPADDR8,
+ LIBERO_SETTING_HART0_CSR_PMPADDR9,
+ LIBERO_SETTING_HART0_CSR_PMPADDR10,
+ LIBERO_SETTING_HART0_CSR_PMPADDR11,
+ LIBERO_SETTING_HART0_CSR_PMPADDR12,
+ LIBERO_SETTING_HART0_CSR_PMPADDR13,
+ LIBERO_SETTING_HART0_CSR_PMPADDR14,
+ LIBERO_SETTING_HART0_CSR_PMPADDR15},
+ /* hart 1 */
+ {LIBERO_SETTING_HART1_CSR_PMPCFG0,
+ LIBERO_SETTING_HART1_CSR_PMPCFG2,
+ LIBERO_SETTING_HART1_CSR_PMPADDR0,
+ LIBERO_SETTING_HART1_CSR_PMPADDR1,
+ LIBERO_SETTING_HART1_CSR_PMPADDR2,
+ LIBERO_SETTING_HART1_CSR_PMPADDR3,
+ LIBERO_SETTING_HART1_CSR_PMPADDR4,
+ LIBERO_SETTING_HART1_CSR_PMPADDR5,
+ LIBERO_SETTING_HART1_CSR_PMPADDR6,
+ LIBERO_SETTING_HART1_CSR_PMPADDR7,
+ LIBERO_SETTING_HART1_CSR_PMPADDR8,
+ LIBERO_SETTING_HART1_CSR_PMPADDR9,
+ LIBERO_SETTING_HART1_CSR_PMPADDR10,
+ LIBERO_SETTING_HART1_CSR_PMPADDR11,
+ LIBERO_SETTING_HART1_CSR_PMPADDR12,
+ LIBERO_SETTING_HART1_CSR_PMPADDR13,
+ LIBERO_SETTING_HART1_CSR_PMPADDR14,
+ LIBERO_SETTING_HART1_CSR_PMPADDR15},
+ /* hart 2 */
+ {LIBERO_SETTING_HART2_CSR_PMPCFG0,
+ LIBERO_SETTING_HART2_CSR_PMPCFG2,
+ LIBERO_SETTING_HART2_CSR_PMPADDR0,
+ LIBERO_SETTING_HART2_CSR_PMPADDR1,
+ LIBERO_SETTING_HART2_CSR_PMPADDR2,
+ LIBERO_SETTING_HART2_CSR_PMPADDR3,
+ LIBERO_SETTING_HART2_CSR_PMPADDR4,
+ LIBERO_SETTING_HART2_CSR_PMPADDR5,
+ LIBERO_SETTING_HART2_CSR_PMPADDR6,
+ LIBERO_SETTING_HART2_CSR_PMPADDR7,
+ LIBERO_SETTING_HART2_CSR_PMPADDR8,
+ LIBERO_SETTING_HART2_CSR_PMPADDR9,
+ LIBERO_SETTING_HART2_CSR_PMPADDR10,
+ LIBERO_SETTING_HART2_CSR_PMPADDR11,
+ LIBERO_SETTING_HART2_CSR_PMPADDR12,
+ LIBERO_SETTING_HART2_CSR_PMPADDR13,
+ LIBERO_SETTING_HART2_CSR_PMPADDR14,
+ LIBERO_SETTING_HART2_CSR_PMPADDR15},
+ /* hart 3 */
+ {LIBERO_SETTING_HART3_CSR_PMPCFG0,
+ LIBERO_SETTING_HART3_CSR_PMPCFG2,
+ LIBERO_SETTING_HART3_CSR_PMPADDR0,
+ LIBERO_SETTING_HART3_CSR_PMPADDR1,
+ LIBERO_SETTING_HART3_CSR_PMPADDR2,
+ LIBERO_SETTING_HART3_CSR_PMPADDR3,
+ LIBERO_SETTING_HART3_CSR_PMPADDR4,
+ LIBERO_SETTING_HART3_CSR_PMPADDR5,
+ LIBERO_SETTING_HART3_CSR_PMPADDR6,
+ LIBERO_SETTING_HART3_CSR_PMPADDR7,
+ LIBERO_SETTING_HART3_CSR_PMPADDR8,
+ LIBERO_SETTING_HART3_CSR_PMPADDR9,
+ LIBERO_SETTING_HART3_CSR_PMPADDR10,
+ LIBERO_SETTING_HART3_CSR_PMPADDR11,
+ LIBERO_SETTING_HART3_CSR_PMPADDR12,
+ LIBERO_SETTING_HART3_CSR_PMPADDR13,
+ LIBERO_SETTING_HART3_CSR_PMPADDR14,
+ LIBERO_SETTING_HART3_CSR_PMPADDR15},
+ /* hart 4 */
+ {LIBERO_SETTING_HART4_CSR_PMPCFG0,
+ LIBERO_SETTING_HART4_CSR_PMPCFG2,
+ LIBERO_SETTING_HART4_CSR_PMPADDR0,
+ LIBERO_SETTING_HART4_CSR_PMPADDR1,
+ LIBERO_SETTING_HART4_CSR_PMPADDR2,
+ LIBERO_SETTING_HART4_CSR_PMPADDR3,
+ LIBERO_SETTING_HART4_CSR_PMPADDR4,
+ LIBERO_SETTING_HART4_CSR_PMPADDR5,
+ LIBERO_SETTING_HART4_CSR_PMPADDR6,
+ LIBERO_SETTING_HART4_CSR_PMPADDR7,
+ LIBERO_SETTING_HART4_CSR_PMPADDR8,
+ LIBERO_SETTING_HART4_CSR_PMPADDR9,
+ LIBERO_SETTING_HART4_CSR_PMPADDR10,
+ LIBERO_SETTING_HART4_CSR_PMPADDR11,
+ LIBERO_SETTING_HART4_CSR_PMPADDR12,
+ LIBERO_SETTING_HART4_CSR_PMPADDR13,
+ LIBERO_SETTING_HART4_CSR_PMPADDR14,
+ LIBERO_SETTING_HART4_CSR_PMPADDR15},
+};
+
+/**
+ * pmp_configure()
+ * Set PMP's up with configuration from Libero
+ * @param hart_id hart Id
+ * @return
+ */
+uint8_t pmp_configure(uint8_t hart_id) /* set-up with settings from Libero */
+{
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ uint64_t pmp0cfg;
+#endif
+ /* make sure enables are off */
+ write_csr(pmpcfg0, 0);
+ write_csr(pmpcfg2, 0);
+ /* set required addressing */
+ write_csr(pmpaddr0, pmp_values[hart_id][2]);
+ write_csr(pmpaddr1, pmp_values[hart_id][3]);
+ write_csr(pmpaddr2, pmp_values[hart_id][4]);
+ write_csr(pmpaddr3, pmp_values[hart_id][5]);
+ write_csr(pmpaddr4, pmp_values[hart_id][6]);
+ write_csr(pmpaddr5, pmp_values[hart_id][7]);
+ write_csr(pmpaddr6, pmp_values[hart_id][8]);
+ write_csr(pmpaddr7, pmp_values[hart_id][9]);
+ write_csr(pmpaddr8, pmp_values[hart_id][10]);
+ write_csr(pmpaddr9, pmp_values[hart_id][11]);
+ write_csr(pmpaddr10, pmp_values[hart_id][12]);
+ write_csr(pmpaddr11, pmp_values[hart_id][13]);
+ write_csr(pmpaddr12, pmp_values[hart_id][14]);
+ write_csr(pmpaddr13, pmp_values[hart_id][15]);
+ write_csr(pmpaddr14, pmp_values[hart_id][16]);
+ write_csr(pmpaddr15, pmp_values[hart_id][17]);
+#if ((LIBERO_SETTING_MEM_CONFIGS_ENABLED & PMP_ENABLED_MASK) == PMP_ENABLED_MASK)
+ pmp0cfg = pmp_values[hart_id][0];
+ pmp_master_configs(hart_id, &pmp0cfg);
+ write_csr(pmpcfg0, pmp0cfg);
+ write_csr(pmpcfg2, pmp_values[hart_id][1]);
+#endif
+
+ return(0);
+}
+
+/*-------------------------------------------------------------------------*//**
+ Please note the first four PMP's are set to zero by MSS Configurator v2021.1
+ These will need to be set by the HSS. The first three relate to HSS footprint
+ The PMP4 is used to open a hole for debug region.
+
+ | PMP | cfg | L | XWR | Detail |
+ |-----|-----------|-----|----------------------------------------------------|
+ | 0 | 0x18 | N | | 256KB | Closes access for s and U mode |
+ | 1 | 0x98 | Y | X R | 256KB | Opens up area for m-mode only |
+ | 2 | 0x98 | Y | XRW | 64KB | OpenSBI scratch per scratch |
+ | 3 | 0x98 | Y | XRW | 4KB | Open window for debug |
+ | .. | .. | .. | .. | .. | .. |
+ | 15 | 0x18 | Y | | - | Close everything not opened |
+
+ @param pmp0cfg return with config for first four PMP's
+
+ */
+__attribute__((weak)) void pmp_master_configs(uint8_t hart_id, uint64_t * pmp0cfg)
+{
+ if ( hart_id == 0U )
+ {
+ *pmp0cfg = LIBERO_SETTING_HART0_CSR_PMPCFG0;
+ write_csr(pmpaddr0, pmp_values[hart_id][2]);
+ write_csr(pmpaddr1, pmp_values[hart_id][3]);
+ write_csr(pmpaddr2, pmp_values[hart_id][4]);
+ write_csr(pmpaddr3, pmp_values[hart_id][5]);
+ }
+ else
+ {
+ /*
+ * Example of closed memory map, must be created based on HSS footprint
+ */
+#define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG0 0x2007FFFULL /* 256K LIM */
+#define CLOSE_S_U_ACCESS_HSS_PMP0_LIM_EG1 0x200FFFFULL /* 512K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_LIM_EG0 0x2007FFFULL /* 256K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_LIM_EG1 0x200FFFFULL /* 512K LIM */
+#define OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG 0x280FFFFULL /* 512K SCRATCHPAD */
+#define OPEN_CONTEXT_ACCESS_LIM_PMP2_H1 0x2011FFFULL /* 64K LIM */
+#define OPEN_CONTEXT_ACCESS_LIM_PMP2_H2 0x2015FFFULL /* 64K LIM */
+#define OPEN_DEBUG_ACCESS_PMP3 0x1FFULL
+#define HSS_CLOSED_CFG_MASK ~0xFFFFFFFFULL
+#define HSS_CLOSED_CFG 0x9F9F9D18ULL
+ /*
+ * We will open 512K LIM and scratchpad in weak pmp_master_configs()
+ * for all harts.
+ */
+#define LIM_512K_FROM_BASE 0x200FFFFULL /* 512K LIM */
+#define SCRATCH_512K_FROM_BASE 0x280FFFFULL /* 512K LIM */
+ *pmp0cfg &= HSS_CLOSED_CFG_MASK;
+ *pmp0cfg |= 0x9F009F9FULL; /* open 0,1 and 3 to allow open access */
+ write_csr(pmpaddr0, OPEN_M_ACCESS_HSS_PMP1_LIM_EG1);
+ write_csr(pmpaddr1, OPEN_M_ACCESS_HSS_PMP1_SCRATCH_EG);
+ write_csr(pmpaddr2, 0ULL);
+ write_csr(pmpaddr3, OPEN_DEBUG_ACCESS_PMP3);
+ }
+
+ /*
+ *
+ */
+#define LOCAL_PMP_SETTINGS
+#ifdef LOCAL_PMP_SETTINGS
+
+#endif
+ return;
+}
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_pmp.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_pmp.h
new file mode 100644
index 00000000..d4319a04
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_pmp.h
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_pmp.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS PMP configuration using MSS configurator values.
+ *
+ */
+/*=========================================================================*//**
+
+ *//*=========================================================================*/
+#ifndef MSS_PMP_H
+#define MSS_PMP_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined (LIBERO_SETTING_MEM_CONFIGS_ENABLED)
+#define LIBERO_SETTING_MEM_CONFIGS_ENABLED 0ULL
+/* Enabled when bit set to 1 */
+/* PMP [0:0] RW value= 0x0 */
+/* MPU [1:0] RW value= 0x0 */
+#endif
+#define PMP_ENABLED_MASK 1UL
+#define MPU_ENABLED_MASK 2UL
+
+/*
+ * Bit offsets associated with LIBERO_SETTING_CONTEXT_A_HART_EN and
+ * LIBERO_SETTING_CONTEXT_B_HART_EN
+ */
+#define CONTEXT_EN_MASK_MMUART0 (1U<<0)
+#define CONTEXT_EN_MASK_MMUART1 (1U<<1)
+#define CONTEXT_EN_MASK_MMUART2 (1U<<2)
+#define CONTEXT_EN_MASK_MMUART3 (1U<<3)
+#define CONTEXT_EN_MASK_MMUART4 (1U<<4)
+#define CONTEXT_EN_MASK_WDOG0 (1U<<5)
+#define CONTEXT_EN_MASK_WDOG1 (1U<<6)
+#define CONTEXT_EN_MASK_WDOG2 (1U<<7)
+#define CONTEXT_EN_MASK_WDOG3 (1U<<8)
+#define CONTEXT_EN_MASK_WDOG4 (1U<<9)
+#define CONTEXT_EN_MASK_SPI0 (1U<<10)
+#define CONTEXT_EN_MASK_SPI1 (1U<<11)
+#define CONTEXT_EN_MASK_I2C0 (1U<<12)
+#define CONTEXT_EN_MASK_I2C1 (1U<<13)
+#define CONTEXT_EN_MASK_CAN0 (1U<<14)
+#define CONTEXT_EN_MASK_CAN1 (1U<<15)
+#define CONTEXT_EN_MASK_MAC0 (1U<<16)
+#define CONTEXT_EN_MASK_MAC1 (1U<<17)
+#define CONTEXT_EN_MASK_TIMER (1U<<18)
+#define CONTEXT_EN_MASK_GPIO0 (1U<<19)
+#define CONTEXT_EN_MASK_GPIO1 (1U<<20)
+#define CONTEXT_EN_MASK_GPIO2 (1U<<21)
+#define CONTEXT_EN_MASK_RTC (1U<<22)
+#define CONTEXT_EN_MASK_H2FINT (1U<<23)
+#define CONTEXT_EN_MASK_CRYPTO (1U<<24)
+#define CONTEXT_EN_MASK_USB (1U<<25)
+#define CONTEXT_EN_MASK_QSPIXIP (1U<<26)
+#define CONTEXT_EN_MASK_ATHENA (1U<<27)
+#define CONTEXT_EN_MASK_TRACE (1U<<28)
+#define CONTEXT_EN_MASK_MAILBOX_SC (1U<<29)
+#define CONTEXT_EN_MASK_MMC (1U<<30)
+#define CONTEXT_EN_MASK_CFM (1U<<31)
+
+/*
+ * Bit offsets associated with LIBERO_SETTING_CONTEXT_A_FIC_EN and
+ * LIBERO_SETTING_CONTEXT_B_FIC_EN
+ */
+#define CONTEXT_EN_MASK_FIC0 (1U<<0)
+#define CONTEXT_EN_MASK_FIC1 (1U<<1)
+#define CONTEXT_EN_MASK_FIC2 (1U<<2)
+#define CONTEXT_EN_MASK_FIC3 (1U<<3)
+
+
+uint8_t pmp_configure(uint8_t hart_id);
+void pmp_master_configs(uint8_t hart_id, uint64_t * pmp0cfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MSS_PMP_H */
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_seg.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_seg.h
new file mode 100644
index 00000000..32534501
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_seg.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/***************************************************************************
+ *
+ * @file mss_seg.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief segmentation block defines
+ *
+ * These blocks allow the DDR memory to be allocated to cached, non-cached
+ * regions and trace depending on the amount of DDR memory physically connected.
+ * Conceptually an address offset is added/subtracted from the DDR address
+ * provided by the Core Complex to point at a base address in the DDR memory.
+ *
+ * The AXI bus simply passes through the segmentation block, and the address
+ * is modified.
+ *
+ * There are two segmentation blocks, they are grouped into the same address
+ * ranges as the MPU blocks. Each one has seven 32-segmentation registers, but
+ * only two in SEG0 and five in SEG1 are actually implemented.
+ *
+ * DDRC blocker - blocks writes to DDR before it is set-up
+ * SEG0.CFG[7]
+ * Is cleared at reset. When written to '1' disables the blocker function
+ * Is allowing the L2 cache controller to access the DDRC.
+ * Is Once written to '1' the register cannot be written to 0, only an MSS reset
+ * Is will clear the register
+ *
+ */
+
+#ifndef MSS_SEG_H
+#define MSS_SEG_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ union {
+ struct {
+ volatile int32_t offset : 15;
+ volatile int32_t rsrvd : 16;
+ volatile int32_t locked : 1;
+ } CFG;
+ uint32_t raw;
+ } u[8u];
+
+ uint32_t fill[64U-8U];
+
+} seg_t;
+
+#define SEG ((seg_t*) 0x20005d00)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*MSS_SEG_H*/
diff --git a/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_sysreg.h b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_sysreg.h
new file mode 100644
index 00000000..7a255e25
--- /dev/null
+++ b/driver-examples/mss-can/mpfs-can-full/src/platform/mpfs_hal/common/mss_sysreg.h
@@ -0,0 +1,4069 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+
+/**************************************************************************
+ *
+ * @file mss_sysreg.h
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief Hardware register definitions.
+
+ *
+ */
+#ifndef MSS_SYSREG_H
+#define MSS_SYSREG_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* IO definitions (access restrictions to peripheral registers) */
+ /**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+