From 9fba0322ece754504557828dfcd89476e43b71c4 Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 9 Jun 2023 17:35:20 +0200 Subject: [PATCH 01/24] Spider: Add serial communication support --- .../config/cortex-a-r/armv8/spider/config.oil | 6 ++ .../drivers/serial/renesas/config.oil | 7 ++ .../drivers/serial/renesas/spider_serial.c | 90 ++++++++++++++++++ .../drivers/serial/renesas/spider_serial.h | 95 +++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 goil/templates/libraries/drivers/serial/renesas/config.oil create mode 100644 libraries/drivers/serial/renesas/spider_serial.c create mode 100644 libraries/drivers/serial/renesas/spider_serial.h diff --git a/goil/templates/config/cortex-a-r/armv8/spider/config.oil b/goil/templates/config/cortex-a-r/armv8/spider/config.oil index 3193107a3..e66a4e925 100755 --- a/goil/templates/config/cortex-a-r/armv8/spider/config.oil +++ b/goil/templates/config/cortex-a-r/armv8/spider/config.oil @@ -5,6 +5,7 @@ IMPLEMENTATION spider { BOOLEAN [ TRUE { ENUM [ + serial, can ] LIBRARY[]; }, @@ -45,6 +46,11 @@ CPU spider { CFILE = "tpl_vector_table_ns.s"; }; + LIBRARY serial { + GLOBAL = TRUE; + PATH = "drivers/serial/renesas"; + }; + LIBRARY net_can_renesas_spider_driver { GLOBAL = TRUE; PATH = "drivers/can/renesas"; diff --git a/goil/templates/libraries/drivers/serial/renesas/config.oil b/goil/templates/libraries/drivers/serial/renesas/config.oil new file mode 100644 index 000000000..6cf0d8395 --- /dev/null +++ b/goil/templates/libraries/drivers/serial/renesas/config.oil @@ -0,0 +1,7 @@ +CPU net_serial_renesas_spider_driver_files { + LIBRARY serial { + PATH = "drivers/serial/renesas"; + CFILE = "spider_serial.c"; + CFILE = "printf.c"; + }; +}; diff --git a/libraries/drivers/serial/renesas/spider_serial.c b/libraries/drivers/serial/renesas/spider_serial.c new file mode 100644 index 000000000..e56b5765c --- /dev/null +++ b/libraries/drivers/serial/renesas/spider_serial.c @@ -0,0 +1,90 @@ +#include "spider_serial.h" + +uint32 Serial_Init(void) +{ + volatile uint8 wait_cmpt; + + /* Clear bits TE and RE in HSSCR to 0 */ + SERIAL_SCR = SERIAL_SCR_INT_VALUE; + + /* Set bits TFRST and RFRST in FCR to 1 */ + SERIAL_FCR |= SERIAL_FCR_TFRST_MASK | SERIAL_FCR_RFRS_MASK; + + /* Clear flags ER, DR, BRK, and RDF in FSR */ + SERIAL_FSR = SERIAL_FSR_INIT_VALUE; + + /* Clear TO and ORER in LSR,*/ + SERIAL_LSR = SERIAL_LSR_INIT_VALUE; + + /* Set bits CKE[1:0] in SCR (leaving other bits cleared to 0) */ + SERIAL_SCR = (SERIAL_SCR & ~SERIAL_SCR_CKE_MASK) | SERIAL_SCR_CKE_INIT_VALUE; + + /* Set data transfer format in HSSMR ( 8 bits, no parity, 1 stop bit, async) */ + SERIAL_SMR = SERIAL_SMR_INIT_VALUE; + + /* Baud rate setting */ + SERIAL_BRR = SERIAL_BAUDRATE; + +#if (SERIAL_BASE_ADDR == SCIF_BASE_ADDR) + /* SCIF module used */ + SERIAL_DL = SERIAL_DL_SETTING_VALUE; + SERIAL_CKS &= ~(SERIAL_CKS_DIV_MASK | SERIAL_CKS_XIN_MASK); +#else + /* HSCIF module used */ + /* Sampling rate 8 */ + SERIAL_SRR = SERIAL_SRR_VAL; +#endif + + for (wait_cmpt = 0; wait_cmpt < 100; wait_cmpt++) + { + } + + /* reset-off, tx-fifo, rx-fifo */ + SERIAL_FCR = SERIAL_FCR_INIT_VALUE; + + /* Enable TE and RE bits*/ + SERIAL_SCR |= SERIAL_SCR_TE_MASK | SERIAL_SCR_RE_MASK; + + return 1; +} + +void Serial_Tx_Wait(void) +{ + /* Wait until TX FIFO is empty */ + do + { + } while ((SERIAL_FSR & SERIAL_TX_DONE) != SERIAL_TX_DONE); +} + +uint32 Serial_Tx(uint8 data) +{ + Serial_Tx_Wait(); + + /* Fill FTDR register with data to send */ + SERIAL_FTDR = data; + + /* Clear TX status bits */ + SERIAL_FSR &= ~SERIAL_TX_DONE; + + return 1; +} + +uint8 Serial_Rx(uint8* data) +{ + /* Check if data available */ + if((SERIAL_FSR & SERIAL_FSR_RDF_MASK) != SERIAL_FSR_RDF_MASK) + return 0; + + /* Check Data Ready and no break, timeout, overrun nor receive errors */ + if (((SERIAL_FSR & SERIAL_RX_READY) != 0) || (SERIAL_LSR != 0)) + return 2; + + /* Get rx data */ + *data = SERIAL_FRDR; + /* Send back data */ + Serial_Tx(*data); + /* Clear RDF flag */ + SERIAL_FSR &= ~SERIAL_FSR_RDF_MASK; + + return 1; +} diff --git a/libraries/drivers/serial/renesas/spider_serial.h b/libraries/drivers/serial/renesas/spider_serial.h new file mode 100644 index 000000000..a32563166 --- /dev/null +++ b/libraries/drivers/serial/renesas/spider_serial.h @@ -0,0 +1,95 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#include "tpl_os.h" + +/* SCIF3 */ +#define SCIF_BASE_ADDR 0xE6C50000 + +/* HSCIF0 */ +#define HSCIF_BASE_ADDR 0xE6540000 + +/* BRR computing: + * HSBRR: Register value = Internal clock / ( Sr * 2^(2*n + 1) * B) * 10^6 -1 + * SCBRR: Register value = PCK / ( 64 * 2^(2*n - 1) * B) * 10^6 -1 + * + * with: + * - PCK: Peripheral module operating frequency (MHz) + * - B: Baudrate + * - Sr: Sampling rate (8 to 32) + * - n: Baudrate generator clock (0 to 3) + * + * In our case: Internal clock = 266, Sr = 8, PCK = 66 and n = 0 + */ +#define HSBRR_1843200BPS (uint8)(0x08U) +#define HSBRR_921600BPS (uint8)(0x11U) +#define SCBRR_115200BPS (uint8)(0x11U) + +/* A proper #define must be used between: SCIF_115200BPS, HSCIF_921600BPS and HSCIF_1843200BPS */ +#if defined SCIF_115200BPS +#define SERIAL_BASE_ADDR SCIF_BASE_ADDR +#define SERIAL_BAUDRATE SCBRR_115200BPS +#elif defined HSCIF_921600BPS +#define SERIAL_BASE_ADDR HSCIF_BASE_ADDR +#define SERIAL_BAUDRATE HSBRR_921600BPS +#elif defined HSCIF_1843200BPS +#define SERIAL_BASE_ADDR HSCIF_BASE_ADDR +#define SERIAL_BAUDRATE HSBRR_1843200BPS +#else +#error "No baudrate defined for serial communication" +#endif + +#define SERIAL_SMR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x00)) +#define SERIAL_BRR (*(volatile uint8 *)(SERIAL_BASE_ADDR + 0x04)) +#define SERIAL_SCR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x08)) +#define SERIAL_FTDR (*(volatile uint8 *)(SERIAL_BASE_ADDR + 0x0C)) +#define SERIAL_FSR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x10)) +#define SERIAL_FRDR (*(volatile uint8 *)(SERIAL_BASE_ADDR + 0x14)) +#define SERIAL_FCR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x18)) +#define SERIAL_FDR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x1C)) +#define SERIAL_SPTR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x20)) +#define SERIAL_LSR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x24)) +#define SERIAL_DL (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x30)) /* Only used by SCIF */ +#define SERIAL_CKS (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x34)) /* Only used by SCIF */ +#define SERIAL_SRR (*(volatile uint16 *)(SERIAL_BASE_ADDR + 0x40)) /* Only used by HSCIF */ + +#define SERIAL_SMR_INIT_VALUE (0x0000U) + +#define SERIAL_SCR_INT_VALUE (0x0000U) +#define SERIAL_SCR_CKE_MASK (3U << 0) +#define SERIAL_SCR_CKE_BRG_VALUE (0x0002U) +#define SERIAL_SCR_CKE_INIT_VALUE (0x0000U) +#define SERIAL_SCR_RE_MASK (1U << 4) +#define SERIAL_SCR_TE_MASK (1U << 5) + +#define SERIAL_FSR_INIT_VALUE (0x0000U) +#define SERIAL_FSR_DR_MASK (1U << 0) +#define SERIAL_FSR_RDF_MASK (1U << 1) +#define SERIAL_FSR_BRK_MASK (1U << 4) +#define SERIAL_FSR_TDFE_MASK (1U << 5) +#define SERIAL_FSR_TEND_MASK (1U << 6) +#define SERIAL_FSR_ER_MASK (1U << 7) +#define SERIAL_RX_READY (SERIAL_FSR_DR_MASK | SERIAL_FSR_BRK_MASK | SERIAL_FSR_ER_MASK) +#define SERIAL_TX_DONE (SERIAL_FSR_TDFE_MASK | SERIAL_FSR_TEND_MASK) + +#define SERIAL_FCR_INIT_VALUE (0x0000U) +#define SERIAL_FCR_TFRST_MASK (1U << 2) +#define SERIAL_FCR_RFRS_MASK (1U << 1) + +#define SERIAL_LSR_INIT_VALUE (0x0000U) + +#define SERIAL_DL_SETTING_VALUE (0x0008U) + +#define SERIAL_CKS_DIV_MASK (1U << 15) +#define SERIAL_CKS_XIN_MASK (1U << 14) + +#define SERIAL_SRR_SRE (1U << 15) +#define SERIAL_SRR_SRCYC8 (7U << 0) +#define SERIAL_SRR_VAL (SERIAL_SRR_SRE | SERIAL_SRR_SRCYC8) + +uint32 Serial_Init(void); +void Serial_Tx_Wait(void); +uint32 Serial_Tx(uint8 data); +uint8 Serial_Rx(uint8* data); + +#endif From 02c97c77e4e2791518c3b2159d60bb3b37c65c7a Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 9 Jun 2023 17:37:21 +0200 Subject: [PATCH 02/24] Spider: Add serial example --- .../cortex-a-r/armv8/spider/serial/build.sh | 15 ++++ .../cortex-a-r/armv8/spider/serial/serial.c | 33 +++++++++ .../cortex-a-r/armv8/spider/serial/serial.oil | 72 +++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100755 examples/cortex-a-r/armv8/spider/serial/build.sh create mode 100755 examples/cortex-a-r/armv8/spider/serial/serial.c create mode 100755 examples/cortex-a-r/armv8/spider/serial/serial.oil diff --git a/examples/cortex-a-r/armv8/spider/serial/build.sh b/examples/cortex-a-r/armv8/spider/serial/build.sh new file mode 100755 index 000000000..3e642b991 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/serial/build.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +#stop on errors +set -e + +if [[ ! -d "_build" ]] +then + mkdir _build +fi + +echo "*** Run Goil ***" +goil --target=cortex-a-r/armv8/spider --templates=../../../../../goil/templates/ serial.oil + +echo "*** Run Make ***" +./make.py diff --git a/examples/cortex-a-r/armv8/spider/serial/serial.c b/examples/cortex-a-r/armv8/spider/serial/serial.c new file mode 100755 index 000000000..097497854 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/serial/serial.c @@ -0,0 +1,33 @@ +#include "tpl_os.h" + +#include "spider_serial.h" + +FUNC(int, OS_APPL_CODE) main(void) +{ + Serial_Init(); + + StartOS(OSDEFAULTAPPMODE); + return 0; +} + +volatile uint32 tmp = 0; +TASK(serial_rx) +{ + uint8 uart_rx; + while(1) + { + if (Serial_Rx(&uart_rx)) + { + /* If received a char, send back the next one */ + Serial_Tx(uart_rx+1); + } + } +} + +TASK(serial_tx) +{ + /* Send next alphabet letter each time*/ + static uint8 uart_char=0; + uart_char = (uart_char+1) % 26; + Serial_Tx('a' + uart_char); +} diff --git a/examples/cortex-a-r/armv8/spider/serial/serial.oil b/examples/cortex-a-r/armv8/spider/serial/serial.oil new file mode 100755 index 000000000..b0ae804da --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/serial/serial.oil @@ -0,0 +1,72 @@ +OIL_VERSION = "4.0"; + +IMPLEMENTATION trampoline { + + /* This fix the default STACKSIZE of tasks */ + TASK { + UINT32 STACKSIZE = 1000 ; + } ; + + /* This fix the default STACKSIZE of ISRs */ + ISR { + UINT32 STACKSIZE = 1000 ; + } ; +}; + +CPU serial { + OS config { + STATUS = EXTENDED; + + BUILD = TRUE { + TRAMPOLINE_BASE_PATH = "../../../../.."; + APP_SRC = "serial.c"; + APP_NAME = "serial_exe.elf"; + CFLAGS = "-O0 -DHSCIF_1843200BPS"; + LDFLAGS = "-Map=serial.map"; + COMPILER = "arm-none-eabi-gcc"; + CPPCOMPILER = "arm-none-eabi-g++"; + ASSEMBLER = "arm-none-eabi-as"; + LINKER = "arm-none-eabi-ld"; + COPIER = "arm-none-eabi-objcopy"; + SYSTEM = PYTHON; + + LIBRARY = serial; + }; + SYSTEM_CALL = TRUE; + MEMMAP = TRUE { + COMPILER = gcc; + LINKER = gnu_ld { SCRIPT = "script.ld"; }; + ASSEMBLER = gnu_as; + MEMORY_PROTECTION = FALSE; + }; + }; + + APPMODE std {}; + + TASK serial_rx { + PRIORITY = 1; + AUTOSTART = TRUE { APPMODE = std; }; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + TASK serial_tx { + PRIORITY = 2; + AUTOSTART = FALSE; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + ALARM serial_serial { + COUNTER = SystemCounter; + ACTION = ACTIVATETASK { + TASK = serial_tx; + }; + AUTOSTART = TRUE { + APPMODE = std; + ALARMTIME = 100; + CYCLETIME = 100; + }; + }; +}; + From 44532b67388eef1288386ff9e89b419d1659da23 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 6 Jun 2023 17:57:04 +0200 Subject: [PATCH 03/24] irq: adding support for ethernet interrupts Interrupt numbers were taken from MCAL code and checked against the excel file with the full list of interrupts, so numbers should be quite reliable. Signed-off-by: Valerio Setti --- .../config/cortex-a-r/armv8/spider/config.oil | 10 ++++++++++ .../cortex-a-r/armv8/spider/interruptSources.oil | 12 +++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/goil/templates/config/cortex-a-r/armv8/spider/config.oil b/goil/templates/config/cortex-a-r/armv8/spider/config.oil index e66a4e925..ede076659 100755 --- a/goil/templates/config/cortex-a-r/armv8/spider/config.oil +++ b/goil/templates/config/cortex-a-r/armv8/spider/config.oil @@ -34,6 +34,16 @@ CPU spider { // TO BE UPDATED INTERRUPT_SOURCE ARM_TIMER { SOURCE_NUM = 27; VECTOR = IRQ_Interrupt; ACK = TRUE; }; INTERRUPT_SOURCE ICCOM_INT { SOURCE_NUM = 353; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE GWCA0_RX_TX_INT { SOURCE_NUM = 312; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE GWCA1_RX_TX_INT { SOURCE_NUM = 320; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE GWCA0_RX_TS_INT { SOURCE_NUM = 328; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE GWCA1_RX_TS_INT { SOURCE_NUM = 330; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE COMA_ERR_INT { SOURCE_NUM = 290; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE GWCA0_ERR_INT { SOURCE_NUM = 291; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE GWCA1_ERR_INT { SOURCE_NUM = 292; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE ETHA0_ERR_INT { SOURCE_NUM = 293; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE ETHA1_ERR_INT { SOURCE_NUM = 294; VECTOR = IRQ_Interrupt; ACK = TRUE; }; + INTERRUPT_SOURCE ETHA2_ERR_INT { SOURCE_NUM = 295; VECTOR = IRQ_Interrupt; ACK = TRUE; }; PLATFORM_FILES spider { PATH = "cortex-a-r/armv8/spider"; diff --git a/goil/templates/config/cortex-a-r/armv8/spider/interruptSources.oil b/goil/templates/config/cortex-a-r/armv8/spider/interruptSources.oil index 07aef5022..cb298815c 100755 --- a/goil/templates/config/cortex-a-r/armv8/spider/interruptSources.oil +++ b/goil/templates/config/cortex-a-r/armv8/spider/interruptSources.oil @@ -4,5 +4,15 @@ ENUM [ /* ARM IRQs */ ARM_TIMER, /* 0 */ - ICCOM_INT /* 1 */ + ICCOM_INT, /* 1 */ + GWCA0_RX_TX_INT, /* 2 */ + GWCA1_RX_TX_INT, /* 3 */ + GWCA0_RX_TS_INT, /* 4 */ + GWCA1_RX_TS_INT, /* 5 */ + COMA_ERR_INT, /* 6 */ + GWCA0_ERR_INT, /* 7 */ + GWCA1_ERR_INT, /* 8 */ + ETHA0_ERR_INT, /* 9 */ + ETHA1_ERR_INT, /* 10 */ + ETHA2_ERR_INT /* 11 */ ] SOURCE; From 58284b0842616462be8e975c06e196b49d56a932 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 6 Jun 2023 18:04:15 +0200 Subject: [PATCH 04/24] example: adding sample code for ethernet This include: - CR52 initialization taken from MCAL - serdes initialization taken from MCAL and compared against the User Manual Signed-off-by: Valerio Setti --- .../cortex-a-r/armv8/spider/ethernet/build.sh | 15 + .../armv8/spider/ethernet/err_codes.h | 6 + .../cortex-a-r/armv8/spider/ethernet/eth.oil | 80 ++++ .../armv8/spider/ethernet/eth_serdes.c | 357 ++++++++++++++++++ .../armv8/spider/ethernet/eth_serdes.h | 7 + .../cortex-a-r/armv8/spider/ethernet/main.c | 137 +++++++ .../armv8/spider/ethernet/rswitch.c | 29 ++ .../armv8/spider/ethernet/rswitch.h | 6 + .../cortex-a-r/armv8/spider/ethernet/utils.c | 104 +++++ .../cortex-a-r/armv8/spider/ethernet/utils.h | 9 + 10 files changed, 750 insertions(+) create mode 100755 examples/cortex-a-r/armv8/spider/ethernet/build.sh create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/err_codes.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/eth.oil create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/main.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/rswitch.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/rswitch.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/utils.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/utils.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/build.sh b/examples/cortex-a-r/armv8/spider/ethernet/build.sh new file mode 100755 index 000000000..cb0690389 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/build.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +#stop on errors +set -e + +if [[ ! -d "_build" ]] +then + mkdir _build +fi + +echo "*** Run Goil ***" +goil --target=cortex-a-r/armv8/spider --templates=../../../../../goil/templates/ eth.oil + +echo "*** Run Make ***" +./make.py diff --git a/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h b/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h new file mode 100644 index 000000000..6bfc7b434 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h @@ -0,0 +1,6 @@ +#ifndef _ERR_CODES_H_ +#define _ERR_CODES_H_ + +#define ERR_TIMEOUT (-1) + +#endif /* _ERR_CODES_H_ */ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil new file mode 100644 index 000000000..5ee5fd01f --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil @@ -0,0 +1,80 @@ +OIL_VERSION = "4.0"; + +IMPLEMENTATION trampoline { + TASK { + UINT32 STACKSIZE = 2048 ; + } ; + + ISR { + UINT32 STACKSIZE = 2048 ; + } ; +}; + +CPU eth { + OS config { + STATUS = EXTENDED; + + BUILD = TRUE { + TRAMPOLINE_BASE_PATH = "../../../../.."; + APP_SRC = "main.c"; + APP_SRC = "utils.c"; + APP_SRC = "eth_serdes.c"; + APP_SRC = "rswitch.c"; + APP_NAME = "eth_exe.elf"; + CFLAGS = "-O0"; + LDFLAGS = "-Map=eth_exe.map"; + COMPILER = "arm-none-eabi-gcc"; + CPPCOMPILER = "arm-none-eabi-g++"; + ASSEMBLER = "arm-none-eabi-as"; + LINKER = "arm-none-eabi-ld"; + COPIER = "arm-none-eabi-objcopy"; + SYSTEM = PYTHON; + }; + SYSTEM_CALL = TRUE; + MEMMAP = TRUE { + COMPILER = gcc; + LINKER = gnu_ld { SCRIPT = "script.ld"; }; + ASSEMBLER = gnu_as; + MEMORY_PROTECTION = FALSE; + }; + }; + + APPMODE std {}; + + TASK sample_init { + PRIORITY = 1; + AUTOSTART = TRUE { APPMODE = std; }; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + ISR gwca1_rx_tx_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = GWCA1_RX_TX_INT; + }; + + ISR gwca1_rx_ts_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = GWCA1_RX_TS_INT; + }; + + ISR coma_err_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = COMA_ERR_INT; + }; + + ISR gwca1_err_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = GWCA1_ERR_INT; + }; + + ISR etha0_err_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = ETHA0_ERR_INT; + }; +}; diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c b/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c new file mode 100644 index 000000000..bd4bdfe99 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c @@ -0,0 +1,357 @@ +#include "tpl_os.h" +#include "eth_serdes.h" +#include "err_codes.h" +#include "utils.h" + +//#define ETH_SERDES_AN_ENABLED + +#define ETH_SERDES_CH_NUM 3 +#define ETH_SERDES_XPCS_CH0 0UL +#define ETH_SERDES_XPCS_CH1 1UL +#define ETH_SERDES_XPCS_CH2 2UL + +/* Maximum Ethernet Timeout Count */ +#define ETH_TIMEOUT_COUNT 63158UL + +/* Ethernet SERDES registers Base Address */ +#define ETH_SERDES_XPCS0_BASE 0xE6444000UL +#define ETH_SERDES_XPCS1_BASE 0xE6444400UL +#define ETH_SERDES_XPCS2_BASE 0xE6444800UL +/* Ehternet SERDES Bank Register Address */ +#define ETH_SERDES_XPCS0_BANK 0xE64443FCUL +#define ETH_SERDES_XPCS1_BANK 0xE64447FCUL +#define ETH_SERDES_XPCS2_BANK 0xE6444BFCUL + +uint32 eth_serdes_base_addr[ETH_SERDES_CH_NUM] = { + ETH_SERDES_XPCS0_BASE, + ETH_SERDES_XPCS1_BASE, + ETH_SERDES_XPCS2_BASE +}; + +uint32 eth_serdes_bank_addr[ETH_SERDES_CH_NUM] = { + ETH_SERDES_XPCS0_BANK, + ETH_SERDES_XPCS1_BANK, + ETH_SERDES_XPCS2_BANK +}; + +typedef enum { + ETH_MAC_LAYER_SPEED_10M = 0, + ETH_MAC_LAYER_SPEED_100M, + ETH_MAC_LAYER_SPEED_1G, + ETH_MAC_LAYER_SPEED_2500M, + ETH_MAC_LAYER_SPEED_10G +} eth_serdes_speed_t; + +#define ETH_SERDES_BPS ETH_MAC_LAYER_SPEED_1G + +#define ETH_SERDES_SEL_BANK(ch, value) \ + {*(volatile uint32*)eth_serdes_bank_addr[ch] = (uint32)value;} +#define ETH_SERDES_REG_WRITE(ch, offset, value) \ + {*(volatile uint32*)(eth_serdes_base_addr[ch] + (uint16)offset) = (uint32)value;} +#define ETH_SERDES_REG_READ(ch, offset) \ + (*(volatile uint32*)(eth_serdes_base_addr[ch] + (uint16)offset)) + +extern volatile VAR(uint32, OS_VAR) tpl_time_counter; + +void eth_disable_fuse_ovr(void) +{ + /* Disable Fuse_override_en */ + uint32 address; + volatile uint32 val; + + address = 0xE6446600; + val = *((volatile uint32*)address); + *((volatile uint32*)address) = 0x00000000U; + val = *((volatile uint32*)address); + (void) val; +} + +static int eth_serdes_wait_for_update(uint32 ch, uint16 offset, uint32 mask, + uint32 exp_val, uint32 timeout) +{ + uint32 start_time; + uint32 elapsed_time; + uint32 curr_time; + uint32 reg_val; + + start_time = tpl_time_counter; + + do { + curr_time = tpl_time_counter; + reg_val = ETH_SERDES_REG_READ(ch, offset); + elapsed_time = curr_time - start_time; + if ((reg_val & mask) == exp_val) { + return 0; + } + } while (elapsed_time < timeout); + + return ERR_TIMEOUT; +} + +static int eth_serdes_wait_reset(void) +{ + int ch, ret; + + for (ch = 0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0180U); + ret = eth_serdes_wait_for_update(ch, 0x026C, BIT(0), BIT(0), ETH_TIMEOUT_COUNT); + if (ret != 0) { + break; + } + } + return ret; +} + +static int eth_serdes_initialize_SRAM(void) +{ + int ch, ret; + + ret = eth_serdes_wait_reset(); + if (ret != 0) { + return ret; + } + + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0180); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x026C, 0x3); + + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0300U); + ret = eth_serdes_wait_for_update(ch, 0x0000U, BIT(15), 0UL, ETH_TIMEOUT_COUNT); + if (ret != 0) { + break; + } + } + + return ret; +} + +static void eth_serdes_set_SGMII_common_settings(void) +{ + /* Steps S.4.1 to S.4.5 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0180); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x0244, 0x97); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01D0, 0x60); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01D8, 0x2200); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01D4, 0x0); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01E0, 0x3D); +} + +static int eth_serdes_PHY_soft_reset(void) +{ + int ret; + + /* Step:5 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0380); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x0000, 0x8000); + + /* Step:6 */ + ret = eth_serdes_wait_reset(); + if (ret != 0) { + return ret; + } + + /* Step:7 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0180U); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x026CU, 0x00000003UL); + + /* Step:8 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0380U); + ret = eth_serdes_wait_for_update(ETH_SERDES_XPCS_CH0, 0x0000U, BIT(15), 0UL, ETH_TIMEOUT_COUNT); + + return ret; +} + +static int eth_serdes_channel_SGMII_common_configuration(uint32 ch) +{ + int ret; + + /* Steps S/SA.9.1 to S/SA.9.14 */ + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2000); + ETH_SERDES_SEL_BANK(ch, 0x0180); + ETH_SERDES_REG_WRITE(ch, 0x01C0, 0x11); + ETH_SERDES_REG_WRITE(ch, 0x0248, 0x540); + ETH_SERDES_REG_WRITE(ch, 0x0258, 0x15); + ETH_SERDES_REG_WRITE(ch, 0x0144, 0x100); + ETH_SERDES_REG_WRITE(ch, 0x01A0, 0x0); + ETH_SERDES_REG_WRITE(ch, 0x00D0, 0x2); + ETH_SERDES_REG_WRITE(ch, 0x0150, 0x3); + ETH_SERDES_REG_WRITE(ch, 0x00C8, 0x100); + ETH_SERDES_REG_WRITE(ch, 0x0148, 0x100); + ETH_SERDES_REG_WRITE(ch, 0x0174, 0x0); + ETH_SERDES_REG_WRITE(ch, 0x0160, 0x7); + ETH_SERDES_REG_WRITE(ch, 0x01AC, 0x0); + ETH_SERDES_REG_WRITE(ch, 0x00C4, 0x310); + + /* Step: S/SA.9.15 */ + ETH_SERDES_REG_WRITE(ch, 0x00C8, 0x101); + + /* Step: S/SA.9.16 */ + ret = eth_serdes_wait_for_update(ch, 0x00C8, BIT(0), 0x0, ETH_TIMEOUT_COUNT); + if (ret != 0) { + return ret; + } + + /* Step: S/SA.9.17 */ + ETH_SERDES_REG_WRITE(ch, 0x0148, 0x101); + + /* Step: S/SA.9.18 */ + ret = eth_serdes_wait_for_update(ch, 0x0148, BIT(0), 0x0, ETH_TIMEOUT_COUNT); + if (ret != 0) { + return ret; + } + + /* Steps S/SA.9.19 to S/SA.9.24 */ + ETH_SERDES_REG_WRITE(ch, 0x00C4, 0x1310); + ETH_SERDES_REG_WRITE(ch, 0x00D8, 0x1800); + ETH_SERDES_REG_WRITE(ch, 0x00DC, 0x0); + + ETH_SERDES_SEL_BANK(ch, 0x0300); + ETH_SERDES_REG_WRITE(ch, 0x001C, 0x1); + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2100); + + ret = eth_serdes_wait_for_update(ch, 0x0000, BIT(8), 0x0, ETH_TIMEOUT_COUNT); + + return ret; +} + +#if defined(ETH_SERDES_AN_ENABLED) +static void eth_serdes_channel_SGMII_enable_AN(uint32 ch, eth_serdes_speed_t LenSpeed) +{ + /* Step: SA.9.25 */ + ETH_SERDES_SEL_BANK(ch, 0x1F00); + if (ETH_MAC_LAYER_SPEED_1G == ch) { + /* select when 1Gbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x140); + } else { + /* select when 100Mbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2100); + } + + /* Steps SA.9.26 to SA.9.28 */ + ETH_SERDES_SEL_BANK(ch, 0x1F80); + ETH_SERDES_REG_WRITE(ch, 0x0004, 0x005); + ETH_SERDES_REG_WRITE(ch, 0x0028, 0x7A1); + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x208); +} +#endif + +#if defined(ETH_SERDES_AN_ENABLED) +static int eth_serdes_channel_set_bps_SGMII_ANON(uint32 ch, eth_serdes_speed_t LenSpeed) +{ + int ret; + + /* Step: SA.10.1 */ + ETH_SERDES_SEL_BANK(ch, 0x1F00); + + /* Mode Selection Method is provisional */ + if (ETH_MAC_LAYER_SPEED_1G == LenSpeed) { + /* select 1Gbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x1140); + } else { + /* select 100Mbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x3100); + } + + /* Step: SA.10.2 */ + ETH_SERDES_SEL_BANK(ch, 0x1F80); + ret = eth_serdes_wait_for_update(ch, 0x0008, BIT(0), BIT(0), ETH_TIMEOUT_COUNT); + if (ret != 0) { + return ret; + } + + ETH_SERDES_REG_WRITE(ch, 0x0008, 0x0); + + return ret; +} +#endif + +static void eth_serdes_channel_set_bps_SGMII_ANOFF(uint32 ch, eth_serdes_speed_t LenSpeed) +{ + /* Step:S.10.1 */ + ETH_SERDES_SEL_BANK(ch, 0x1F00); + + /* Mode Selection Method is provisional */ + if (ETH_MAC_LAYER_SPEED_1G == LenSpeed) { + /* select 1Gbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x140); + } else { + /* select 100Mbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2100); + } +} + +/* Following User's Manual at section 100.6.3 */ +int eth_serdes_initialize(void) +{ + int ret, ch; + + /* Step 1: Initialize SRAM */ + ret = eth_serdes_initialize_SRAM(); + if (ret != 0) { + return ret; + } + + /* Step 2 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x03D4, 0x443); + } + + /* Step 3 */ + eth_serdes_set_SGMII_common_settings(); + + /* Step 4 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0X03D0, 0x1); + } + + /* Steps 5 to 8 */ + ret = eth_serdes_PHY_soft_reset(); + if (ret != 0) { + return ret; + } + + /* Step 9 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + /* Steps S/SA.9.1 to S/SA.9.24 */ + ret = eth_serdes_channel_SGMII_common_configuration(ch); + if (ret != 0) { + return ret; + } +#if defined(ETH_SERDES_AN_ENABLED) + /* Steps SA.9.25 to SA.9.28 */ + eth_serdes_channel_SGMII_enable_AN(ch, ETH_SERDES_BPS); +#endif + } + + /* Step 10: */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { +#if defined(ETH_SERDES_AN_ENABLED) + /* Steps SA.10.1 to SA.10.3 */ + ret = eth_serdes_channel_set_bps_SGMII_ANON(ch, ETH_SERDES_BPS); + if (ret != 0) { + return ret; + } +#else + /* Step: S.10.1 */ + eth_serdes_channel_set_bps_SGMII_ANOFF(ch, ETH_SERDES_BPS); +#endif + } + + /* Step 11 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x03C0, 0x0); + } + + /* Step 12 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x03D0, 0x0); + } + + return 0; +} diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.h b/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.h new file mode 100644 index 000000000..e75a08785 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.h @@ -0,0 +1,7 @@ +#ifndef _ETH_SERDES_H_ +#define _ETH_SERDES_H_ + +void eth_disable_fuse_ovr(void); +int eth_serdes_initialize(void); + +#endif /* _ETH_SERDES_H_ */ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c new file mode 100644 index 000000000..e73253277 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -0,0 +1,137 @@ +#include "tpl_os.h" +#include "utils.h" +#include "eth_serdes.h" +#include "rswitch.h" + +#define debug_msg(x) do { (void)x; } while(0) + +#define APP_Task_sample_init_START_SEC_CODE +#include "tpl_memmap.h" + +extern volatile VAR(uint32, OS_VAR) tpl_time_counter; + +// Is this the right section for the main function?? +FUNC(int, OS_APPL_CODE) main(void) +{ + StartOS(OSDEFAULTAPPMODE); + return 0; +} + +TASK(sample_init) { + int ret; + + mcu_init(); + port_init(); + // Interrupt initializazion done by Trampoline + eth_disable_fuse_ovr(); + + ret = eth_serdes_initialize(); + if (ret != 0) { + debug_msg("Error in serdes initialization\n"); + goto exit; + } + + rswitch_init(); + + +exit: + TerminateTask(); +} + +#define APP_Task_sample_init_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_rx_tx_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_rx_tx_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_RX_TX_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_gwca1_rx_tx_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_rx_ts_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_rx_ts_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_RX_TS_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_gwca1_rx_ts_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_coma_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(coma_err_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) COMA_ERR_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_coma_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_err_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_ERR_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_gwca1_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_etha0_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(etha0_err_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) ETHA0_ERR_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_etha0_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c new file mode 100644 index 000000000..6627a82f8 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c @@ -0,0 +1,29 @@ +#include "tpl_os.h" +#include "rswitch.h" + +#define RSWITCH_BASE 0xE6880000 + +#define RSWITCH_FWD_ADDR (RSWITCH_BASE + 0x00000000) +#define RSWITCH_FAB_ADDR (RSWITCH_BASE + 0x00008000) +#define RSWITCH_COMA_ADDR (RSWITCH_BASE + 0x00009000) +#define RSWITCH_ETHA0_ADDR (RSWITCH_BASE + 0x0000a000) +#define RSWITCH_ETHA1_ADDR (RSWITCH_BASE + 0x0000c000) +#define RSWITCH_ETHA2_ADDR (RSWITCH_BASE + 0x0000e000) +#define RSWITCH_GWCA0_ADDR (RSWITCH_BASE + 0x00010000) +#define RSWITCH_GWCA1_ADDR (RSWITCH_BASE + 0x00012000) +#define RSWITCH_GPTP_ADDR (RSWITCH_BASE + 0x00018000) + +static inline uint32 reg_read32(void *addr) +{ + return *((volatile uint32*)addr); +} + +static inline void reg_write32(uint32 data, void *addr) +{ + *((volatile uint32*)addr) = data; +} + +int rswitch_init(void) +{ + return 0; +} \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h new file mode 100644 index 000000000..4bee5aae7 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h @@ -0,0 +1,6 @@ +#ifndef _ETH_H_ +#define _ETH_H_ + +int rswitch_init(void); + +#endif /* _ETH_H_ */ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.c b/examples/cortex-a-r/armv8/spider/ethernet/utils.c new file mode 100644 index 000000000..9a9c1bb57 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.c @@ -0,0 +1,104 @@ +#include "tpl_os.h" +#include "utils.h" +#include "pfcmap.h" +#include "device_cfg.h" + +#define ETH_CPUCLK_MHZ 1066UL +#define ETH_WAIT_NS(t) { volatile uint32 cnt; \ + for ( cnt = 0;cnt < ((((uint32)ETH_CPUCLK_MHZ * ((uint32)t)) / (uint32)1000) + (uint32)1);cnt++ ); } + +/* Module Standby, Software reset */ +#define MSTPCR_ETH_1 (*((volatile uint32 *)0xE6152D3CUL)) /* MSTPCR15 Register */ +#define MSTPSR_ETH_1 (*((volatile uint32 *)0xE6152E3CUL)) /* MSTPSR15 Register */ +#define MSTP_BIT_ETHIP (uint32)(1 << 5) +#define MSTP_BIT_ETHPHY (uint32)(1 << 6) + +/* CPG */ +#define CPG_CPGWPR (*((volatile uint32 *)0xE6150000UL)) /* CPGWPR Register used to remove MSTPCR write protection */ +#define CKCR_ETH_1 (*((volatile uint32 *)0xE61508E8UL)) /* RSW2CKCR Register */ +#define CKCR_BIT_ETHIP (uint32)(1 << 8) + +#define SRCR_ETH_1 (*((volatile uint32 *)0xE6152C3CUL)) /* SRCR15 Register */ +#define SRSTCLR_ETH_1 (*((volatile uint32 *)0xE6152CBCUL)) /* SRSTCLCR15 Register */ +#define SRCR_BIT_ETHIP (uint32)(1 << 5) +#define SRCR_BIT_ETHPHY (uint32)(1 << 6) + +void mcu_init(void) +{ + volatile uint32 regval = 0x0UL; + + /* Supply RSW2�� clock by writing 0 to CKCR */ + regval = CKCR_ETH_1; /* RSW2CKCR */ + if (regval & CKCR_BIT_ETHIP) /* 1: Stops the clock */ + { + regval &= ~CKCR_BIT_ETHIP; + CKCR_ETH_1 = regval; /* 0: Supplies the clock */ + while (CKCR_ETH_1 & CKCR_BIT_ETHIP); /* Wait for the register value to change */ + } + + /* Supply RSW2 and ETHPHY clock by writing 0 to MSTPSR */ + regval = MSTPSR_ETH_1; + if (regval & (MSTP_BIT_ETHIP | MSTP_BIT_ETHPHY)) /* If either one is 1(=Stops the clock), execute the process */ + { + regval &= ~(MSTP_BIT_ETHIP | MSTP_BIT_ETHPHY); + CPG_CPGWPR = ~regval; /* Release MSTPCR write protection by writing the inverse of the value to CPGWPR */ + MSTPCR_ETH_1 = regval; /* 0: Supplies the clock */ + while (MSTPSR_ETH_1 & (MSTP_BIT_ETHIP | MSTP_BIT_ETHPHY)); /* Wait for the register value to change */ + } + + /* Reset RSW2 and ETHPHY by writing 1 to SRCR */ + CPG_CPGWPR = ~(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* Release SRCR write protection by writing the inverse of the value to CPGWR */ + SRCR_ETH_1 = (uint32)(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* SRCR does not require read-modify write */ + ETH_WAIT_NS(20*1000); + + /* Release the reset RSW2 and ETHPHY by writing 1 to SRSTCLR */ + CPG_CPGWPR = ~(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* Release SRSTCLR write protection by writing the inverse of the value to CPGWR */ + SRSTCLR_ETH_1 = (uint32)(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* SRSTCLR does not require read-modify write */ + ETH_WAIT_NS(40*1000); +} + +void port_init(void) +{ + uint32 dataL; + + /*------- + * GPSR3[18:0] = 18'b1111111111111111111 + * = TSNx_AVTP_CAPTURE, TSNx_AVTP_MATCH, TSNx_AVTP_PPS, TSN0_MAGIC, TSNx_PHY_INT, TSNx_LINK, TSNx_MDC, TSNx_MDIO */ + dataL = *((volatile uint32 *)(PFC_GPSR_GPn_DM0(3))); + dataL &= ~(0x0007FFFFUL); + dataL |= (0x0007FFFFUL); + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_GPSR_GPn_DM0(3))) = dataL; + + /*------- + * DRV0CTRL4 [31:28] AVB0_TXC + * [27:24] AVB0_TX_CTL + * DRV1CTRL4 [15:12] AVB0_TD3 + * [11:8] AVB0_TD2 + * [7:4] AVB0_TD1 + * [3:0] AVB0_TD0 */ + dataL = *((volatile uint32 *)PFC_DRVCTRLm_GPn_DM0(0,3)); + dataL &= ~0x77777777UL; + dataL |= 0x33333333UL; + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_DRVCTRLm_GPn_DM0(0,3))) = dataL; + + dataL = *((volatile uint32 *)PFC_DRVCTRLm_GPn_DM0(1,3)); + dataL &= ~0x77777777UL; + dataL |= 0x33333333UL; + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_DRVCTRLm_GPn_DM0(1,3))) = dataL; + + dataL = *((volatile uint32 *)PFC_DRVCTRLm_GPn_DM0(2,3)); + dataL &= ~0x00000777UL; + dataL |= 0x00000333UL; + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_DRVCTRLm_GPn_DM0(2,3))) = dataL; + + /* Ether TSN IO voltage level = 1.8V + * POC3 bit[18:0] = 0 = IO voltage level = 1.8V */ + dataL = *((volatile uint32 *)PFC_POC_GPn_DM0(3)); + dataL &= ~(0x0007FFFFUL); + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_POC_GPn_DM0(3))) = dataL; +} diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.h b/examples/cortex-a-r/armv8/spider/ethernet/utils.h new file mode 100644 index 000000000..db0aa20da --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.h @@ -0,0 +1,9 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#define BIT(x) (1UL << x) + +void mcu_init(void); +void port_init(void); + +#endif /* _UTILS_H_ */ \ No newline at end of file From 68529cdd0e13ed4e6b4ed7ec1297df65c4f91d0a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 7 Jun 2023 10:40:01 +0200 Subject: [PATCH 05/24] minor code improvements Signed-off-by: Valerio Setti --- .../armv8/spider/ethernet/eth_serdes.c | 10 ++----- .../cortex-a-r/armv8/spider/ethernet/main.c | 2 +- .../cortex-a-r/armv8/spider/ethernet/utils.c | 26 ++++++++++++++----- .../cortex-a-r/armv8/spider/ethernet/utils.h | 6 ++++- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c b/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c index bd4bdfe99..d83ea9ad1 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c @@ -51,8 +51,6 @@ typedef enum { #define ETH_SERDES_REG_READ(ch, offset) \ (*(volatile uint32*)(eth_serdes_base_addr[ch] + (uint16)offset)) -extern volatile VAR(uint32, OS_VAR) tpl_time_counter; - void eth_disable_fuse_ovr(void) { /* Disable Fuse_override_en */ @@ -70,20 +68,16 @@ static int eth_serdes_wait_for_update(uint32 ch, uint16 offset, uint32 mask, uint32 exp_val, uint32 timeout) { uint32 start_time; - uint32 elapsed_time; - uint32 curr_time; uint32 reg_val; - start_time = tpl_time_counter; + start_time = get_time(); do { - curr_time = tpl_time_counter; reg_val = ETH_SERDES_REG_READ(ch, offset); - elapsed_time = curr_time - start_time; if ((reg_val & mask) == exp_val) { return 0; } - } while (elapsed_time < timeout); + } while (get_elapsed_time(start_time) < timeout); return ERR_TIMEOUT; } diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c index e73253277..50d446dea 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/main.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -20,7 +20,7 @@ FUNC(int, OS_APPL_CODE) main(void) TASK(sample_init) { int ret; - mcu_init(); + rswitch_enable_clock_and_reset(); port_init(); // Interrupt initializazion done by Trampoline eth_disable_fuse_ovr(); diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.c b/examples/cortex-a-r/armv8/spider/ethernet/utils.c index 9a9c1bb57..7b0abd572 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.c @@ -1,11 +1,14 @@ #include "tpl_os.h" #include "utils.h" -#include "pfcmap.h" -#include "device_cfg.h" #define ETH_CPUCLK_MHZ 1066UL -#define ETH_WAIT_NS(t) { volatile uint32 cnt; \ - for ( cnt = 0;cnt < ((((uint32)ETH_CPUCLK_MHZ * ((uint32)t)) / (uint32)1000) + (uint32)1);cnt++ ); } +#define ETH_WAIT_NS(t) \ + { \ + volatile uint32 cnt; \ + for (cnt = 0; \ + cnt < ((((uint32)ETH_CPUCLK_MHZ * ((uint32)t)) / (uint32)1000) + (uint32)1); \ + cnt++); \ + } /* Module Standby, Software reset */ #define MSTPCR_ETH_1 (*((volatile uint32 *)0xE6152D3CUL)) /* MSTPCR15 Register */ @@ -23,11 +26,11 @@ #define SRCR_BIT_ETHIP (uint32)(1 << 5) #define SRCR_BIT_ETHPHY (uint32)(1 << 6) -void mcu_init(void) +void rswitch_enable_clock_and_reset(void) { volatile uint32 regval = 0x0UL; - /* Supply RSW2�� clock by writing 0 to CKCR */ + /* Enable RSW2 clock by writing 0 to CKCR */ regval = CKCR_ETH_1; /* RSW2CKCR */ if (regval & CKCR_BIT_ETHIP) /* 1: Stops the clock */ { @@ -57,6 +60,17 @@ void mcu_init(void) ETH_WAIT_NS(40*1000); } +extern volatile VAR(uint32, OS_VAR) tpl_time_counter; +uint32 get_time(void) +{ + return tpl_time_counter; +} + +uint32 get_elapsed_time(uint32 start_val) +{ + return (tpl_time_counter - start_val); +} + void port_init(void) { uint32 dataL; diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.h b/examples/cortex-a-r/armv8/spider/ethernet/utils.h index db0aa20da..cfadb3018 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.h @@ -1,9 +1,13 @@ #ifndef _UTILS_H_ #define _UTILS_H_ +#include "tpl_os.h" + #define BIT(x) (1UL << x) -void mcu_init(void); +void rswitch_enable_clock_and_reset(void); void port_init(void); +uint32 get_time(void); +uint32 get_elapsed_time(uint32 start_val); #endif /* _UTILS_H_ */ \ No newline at end of file From b37cd996f0133ce0193c461b70e5e76bc4a6a552 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 13 Jun 2023 16:24:18 +0200 Subject: [PATCH 06/24] rswitch: initial support (WIP) Signed-off-by: Valerio Setti --- .../cortex-a-r/armv8/spider/ethernet/eth.oil | 1 + .../armv8/spider/ethernet/eth_gptp.c | 35 + .../armv8/spider/ethernet/eth_gptp.h | 14 + .../cortex-a-r/armv8/spider/ethernet/main.c | 23 +- .../cortex-a-r/armv8/spider/ethernet/pfcmap.h | 60 ++ .../armv8/spider/ethernet/rswitch.c | 829 +++++++++++++++++- .../armv8/spider/ethernet/rswitch.h | 1 + .../armv8/spider/ethernet/rswitch_regs.h | 659 ++++++++++++++ .../cortex-a-r/armv8/spider/ethernet/utils.c | 25 + .../cortex-a-r/armv8/spider/ethernet/utils.h | 23 + 10 files changed, 1652 insertions(+), 18 deletions(-) create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/pfcmap.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil index 5ee5fd01f..28d557a07 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil @@ -20,6 +20,7 @@ CPU eth { APP_SRC = "utils.c"; APP_SRC = "eth_serdes.c"; APP_SRC = "rswitch.c"; + APP_SRC = "eth_gptp.c"; APP_NAME = "eth_exe.elf"; CFLAGS = "-O0"; LDFLAGS = "-Map=eth_exe.map"; diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.c b/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.c new file mode 100644 index 000000000..eaedc3d40 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.c @@ -0,0 +1,35 @@ +#include "eth_gptp.h" +#include "rswitch_regs.h" +#include "utils.h" + +/* Note: we are only using Timer0 */ + +#define PTPTIVC_INIT 0x19000000 /* 320MHz */ +#define RCAR_GEN4_PTP_CLOCK_S4 PTPTIVC_INIT + +#define PTPRO RSWITCH_GPTP_ADDR + +#define PTPTMEC PTPRO + 0x0010 +#define PTPTMDC PTPRO + 0x0014 +#define PTPTIVC0 PTPRO + 0x0020 +#define PTPTOVC00 PTPRO + 0x0030 +#define PTPTOVC10 PTPRO + 0x0034 +#define PTPTOVC20 PTPRO + 0x0038 +#define PTPGPTPTM00 PTPRO + 0x0050 +#define PTPGPTPTM10 PTPRO + 0x0054 +#define PTPGPTPTM20 PTPRO + 0x0058 + +void eth_gptp_init(void) +{ + reg_write32(RCAR_GEN4_PTP_CLOCK_S4, PTPTIVC0); + reg_write32(0x1, PTPTMEC); +} + +void eth_gptp_get_time(struct gptp_time *output) +{ + output->nano = reg_read32(PTPGPTPTM00); + output->seconds = reg_read32(PTPGPTPTM10) + + (((uint64) reg_read32(PTPGPTPTM20)) << 32); + /* A better implementation might check that none of the above + registers overflowed while reading others... */ +} \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.h b/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.h new file mode 100644 index 000000000..83d6c5bbe --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.h @@ -0,0 +1,14 @@ +#ifndef _ETH_GPTP_H_ +#define _ETH_GPTP_H_ + +#include "tpl_os.h" + +struct gptp_time { + uint64 seconds; + uint32 nano; +}; + +void eth_gptp_init(void); +void eth_gptp_get_time(struct gptp_time *output); + +#endif /* _ETH_GPTP_H_ */ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c index 50d446dea..f87c247b8 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/main.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -2,8 +2,7 @@ #include "utils.h" #include "eth_serdes.h" #include "rswitch.h" - -#define debug_msg(x) do { (void)x; } while(0) +#include "eth_gptp.h" #define APP_Task_sample_init_START_SEC_CODE #include "tpl_memmap.h" @@ -27,12 +26,23 @@ TASK(sample_init) { ret = eth_serdes_initialize(); if (ret != 0) { - debug_msg("Error in serdes initialization\n"); + debug_msg("Error in eth_serdes_initialize\n"); + goto exit; + } + + ret = rswitch_init(); + if (ret != 0) { + debug_msg("Error in rswitch_init\n"); goto exit; } - rswitch_init(); + eth_gptp_init(); + ret = rswitch_open(); + if (ret != 0) { + debug_msg("Error in rswitch_open\n"); + goto exit; + } exit: TerminateTask(); @@ -49,6 +59,7 @@ TASK(sample_init) { ISR(gwca1_rx_tx_int) { + debug_msg("gwca1_rx_tx_int"); //CallTerminateISR2(); } @@ -68,6 +79,7 @@ FUNC(void, OS_CODE) GWCA1_RX_TX_INT_ClearFlag(void) ISR(gwca1_rx_ts_int) { + debug_msg("gwca1_rx_ts_int"); //CallTerminateISR2(); } @@ -87,6 +99,7 @@ FUNC(void, OS_CODE) GWCA1_RX_TS_INT_ClearFlag(void) ISR(coma_err_int) { + debug_msg("coma_err_int"); //CallTerminateISR2(); } @@ -106,6 +119,7 @@ FUNC(void, OS_CODE) COMA_ERR_INT_ClearFlag(void) ISR(gwca1_err_int) { + debug_msg("gwca1_err_int"); //CallTerminateISR2(); } @@ -125,6 +139,7 @@ FUNC(void, OS_CODE) GWCA1_ERR_INT_ClearFlag(void) ISR(etha0_err_int) { + debug_msg("etha0_err_int"); //CallTerminateISR2(); } diff --git a/examples/cortex-a-r/armv8/spider/ethernet/pfcmap.h b/examples/cortex-a-r/armv8/spider/ethernet/pfcmap.h new file mode 100644 index 000000000..f0b063f36 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/pfcmap.h @@ -0,0 +1,60 @@ +#ifndef PFCMAP_H +#define PFCMAP_H + +/* PFC base */ +#define PFC_GP0_BASE (0xE6050000UL) +#define PFC_GP4_BASE (0xDFD90000UL) + +static const unsigned int PRTGRP_OFFSET[] = +{ + 0x0000U, /* PRTGRP0 */ + 0x0000U, /* PRTGRP1 */ + 0x0800U, /* PRTGRP2 */ + 0x0800U, /* PRTGRP3 */ + 0x0000U, /* PRTGRP4 */ + 0x0800U, /* PRTGRP5 */ + 0x0000U, /* PRTGRP6 */ + 0x0800U, /* PRTGRP7 */ + 0x1000U, /* PRTGRP8 */ + 0x1800U, /* PRTGRP9 */ + 0x0000U, /* PRTGRP10 */ +}; + +#define PFC_GPSR_BmPlTt_OFFSET(m, l, t) (0x0040U + PFC_GROUPS_OFFSET(m, l, t)) + +/* PFC[0] = m=0~3, l=1, t=0~2 */ +/* PFC[1] = m=0~3, l=0, t=0~2 */ +/* PFC[2] = m=0~3, l=4,5, t=0~2 */ +/* PFC[3] = m=0~3, l=6~9, t=0~2 */ + +#define PFC_IPnSR_BmPlTt_OFFSET(n, m, l, t) (0x0060U + (0x0004U * n) + PFC_GROUPS_OFFSET(m, l, t)) + +/* PFC[0] = m=0~3, l=1, t=0~2 */ +/* PFC[1] = m=0~3, l=0, t=0~2 */ +/* PFC[2] = m=0~3, l=4,5, t=0~2 */ +/* PFC[3] = m=0~3, l=6~9, t=0~2 */ + +#define PFC_POC_BmPlTt_OFFSET(m, l, t) (0x00A0U + PFC_GROUPS_OFFSET(m, l, t)) + +/* PFC[0] = m=0~3, l=1, t=0~2 */ +/* PFC[1] = m=0~3, l=0, t=0~2 */ +/* PFC[2] = m=0~3, l=4,5, t=0~2 */ +/* PFC[3] = m=0~3, l=6~9, t=0~2 */ + +#define PFC_DRVnCTRL_BmPlTt_OFFSET(n, m, l, t) (0x0080U + (0x0004U * n) + PFC_GROUPS_OFFSET(m, l, t)) + +#define PFC_GROUPS_OFFSET(m, l, t) (((m) * 0x2000U) + PRTGRP_OFFSET[l] + ((t) * 0x0200U)) +/* R/W 32 LSI Multiplexed Pin Setting Mask Register */ +#define PFC_PMMR(addr) ((addr & 0xFFFFF800U) + 0x0000UL) + +#define PFC_PORTGP_OFFSET (0x800U) +#define PFC_GPn_BASE(n) (((n < 4)? PFC_GP0_BASE : PFC_GP4_BASE) + (PFC_PORTGP_OFFSET * (n % 4))) + +#define PFC_GPSR_GPn_DM0(n) (PFC_GPn_BASE(n) + PFC_GPSR_BmPlTt_OFFSET(0,0,0)) +#define PFC_IPSRm_GPn_DM0(m, n) (PFC_GPn_BASE(n) + PFC_IPnSR_BmPlTt_OFFSET(m,0,0,0)) +/* R/W 32 POC control register0 PortGroup 3 */ +#define PFC_POC_GPn_DM0(n) (PFC_GPn_BASE(n) + PFC_POC_BmPlTt_OFFSET(0,0,0)) +/* R/W 32 POC control register0 PortGroup 3 */ +#define PFC_DRVCTRLm_GPn_DM0(m, n) (PFC_GPn_BASE(n) + PFC_DRVnCTRL_BmPlTt_OFFSET(m,0,0,0)) + +#endif /* PFCMAP_H */ diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c index 6627a82f8..c653266da 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c @@ -1,29 +1,830 @@ #include "tpl_os.h" +#include "utils.h" #include "rswitch.h" +#include "rswitch_regs.h" +#include "err_codes.h" +#include -#define RSWITCH_BASE 0xE6880000 +#define PORT_TSNA_N 3 +#define PORT_GWCA_N 2 +#define TOT_PORT_NUM (PORT_TSNA_N + PORT_GWCA_N) -#define RSWITCH_FWD_ADDR (RSWITCH_BASE + 0x00000000) -#define RSWITCH_FAB_ADDR (RSWITCH_BASE + 0x00008000) -#define RSWITCH_COMA_ADDR (RSWITCH_BASE + 0x00009000) -#define RSWITCH_ETHA0_ADDR (RSWITCH_BASE + 0x0000a000) -#define RSWITCH_ETHA1_ADDR (RSWITCH_BASE + 0x0000c000) -#define RSWITCH_ETHA2_ADDR (RSWITCH_BASE + 0x0000e000) -#define RSWITCH_GWCA0_ADDR (RSWITCH_BASE + 0x00010000) -#define RSWITCH_GWCA1_ADDR (RSWITCH_BASE + 0x00012000) -#define RSWITCH_GPTP_ADDR (RSWITCH_BASE + 0x00018000) +#define RSWITCH_GWCA_IDX_TO_HW_NUM(i) ((i) + PORT_TSNA_N) +#define RSWITCH_HW_NUM_TO_GWCA_IDX(i) ((i) - PORT_TSNA_N) -static inline uint32 reg_read32(void *addr) +#define TSNA0_PORT_NUM 0 +#define TSNA1_PORT_NUM 1 +#define TSNA2_PORT_NUM 2 +#define GWCA0_PORT_NUM 3 +#define GWCA1_PORT_NUM 4 + +#define TSN_PORT_IN_USE TSNA0_PORT_NUM +#define GWCA_PORT_IN_USE GWCA1_PORT_NUM + +/* GWCA */ +enum rswitch_gwca_mode { + GWMC_OPC_RESET, + GWMC_OPC_DISABLE, + GWMC_OPC_CONFIG, + GWMC_OPC_OPERATION, +}; +#define GWMS_OPS_MASK GWMC_OPC_OPERATION +#define GWVCC_VEM_SC_TAG (0x3 << 16) +#define GWMTIRM_MTIOG BIT(0) +#define GWMTIRM_MTR BIT(1) +#define GWARIRM_ARIOG BIT(0) +#define GWARIRM_ARR BIT(1) + +#define GWDCC_BALR BIT(24) +#define GWDCC_DCP(q, idx) ((q + (idx * 2)) << 16) +#define GWDCC_DQT BIT(11) +#define GWDCC_ETS BIT(9) +#define GWDCC_EDE BIT(8) +#define GWDCC_OFFS(chain) (GWDCC0 + (chain) * 4) + +enum DIE_DT { + /* Frame data */ + DT_FSINGLE = 0x80, + DT_FSTART = 0x90, + DT_FMID = 0xA0, + DT_FEND = 0xB8, + + /* Chain control */ + DT_LEMPTY = 0xC0, + DT_EEMPTY = 0xD0, + DT_LINKFIX = 0x00, + DT_LINK = 0xE0, + DT_EOS = 0xF0, + /* HW/SW arbitration */ + DT_FEMPTY = 0x40, + DT_FEMPTY_IS = 0x10, + DT_FEMPTY_IC = 0x20, + DT_FEMPTY_ND = 0x38, + DT_FEMPTY_START = 0x50, + DT_FEMPTY_MID = 0x60, + DT_FEMPTY_END = 0x70, + + DT_MASK = 0xF0, + DIE = 0x08, /* Descriptor Interrupt Enable */ +}; + +struct rswitch_desc { + uint16 info_ds; /* Descriptor size */ + uint8 die_dt; /* Descriptor interrupt enable and type */ + uint8 dptrh; /* Descriptor pointer MSB */ + uint32 dptrl; /* Descriptor pointer LSW */ +} __attribute__((packed)); + +struct rswitch_ts_desc { + uint16 info_ds; /* Descriptor size */ + uint8 die_dt; /* Descriptor interrupt enable and type */ + uint8 dptrh; /* Descriptor pointer MSB */ + uint32 dptrl; /* Descriptor pointer LSW */ + uint32 ts_nsec; + uint32 ts_sec; +} __attribute__((packed)); + +struct rswitch_ext_desc { + uint16 info_ds; /* Descriptor size */ + uint8 die_dt; /* Descriptor interrupt enable and type */ + uint8 dptrh; /* Descriptor pointer MSB */ + uint32 dptrl; /* Descriptor pointer LSW */ + uint64 info1; +} __attribute__((packed)); + +struct rswitch_ext_ts_desc { + uint16 info_ds; /* Descriptor size */ + uint8 die_dt; /* Descriptor interrupt enable and type */ + uint8 dptrh; /* Descriptor pointer MSB */ + uint32 dptrl; /* Descriptor pointer LSW */ + uint64 info1; + uint32 ts_nsec; + uint32 ts_sec; +} __attribute__((packed)); + +#define NUM_DEVICES 3 +#define NUM_CHAINS_PER_NDEV 2 + +#define RSWITCH_MAX_NUM_CHAINS 128 +#define RSWITCH_NUM_IRQ_REGS (RSWITCH_MAX_NUM_CHAINS / BITS_PER_TYPE(uint32)) + +#define MAC_ADDRESS_LEN 6 +struct rswitch_etha { + uint8 port_num; + uint32 base_addr; + uint8 mac_addr[MAC_ADDRESS_LEN]; + int speed; +} etha_props[PORT_TSNA_N] = { - return *((volatile uint32*)addr); + { .port_num = TSNA0_PORT_NUM, .base_addr = RSWITCH_ETHA0_ADDR }, + { .port_num = TSNA1_PORT_NUM, .base_addr = RSWITCH_ETHA1_ADDR }, + { .port_num = TSNA2_PORT_NUM, .base_addr = RSWITCH_ETHA2_ADDR }, +}; + +enum rswitch_etha_mode { + EAMC_OPC_RESET, + EAMC_OPC_DISABLE, + EAMC_OPC_CONFIG, + EAMC_OPC_OPERATION, +}; +#define EAMS_OPS_MASK EAMC_OPC_OPERATION +#define EAVCC_VEM_SC_TAG (0x3 << 16) + +#define MPIC_PIS_MII 0x00 +#define MPIC_PIS_GMII 0x02 +#define MPIC_PIS_XGMII 0x04 +#define MPIC_LSC_SHIFT 3 +#define MPIC_LSC_10M (0 << MPIC_LSC_SHIFT) +#define MPIC_LSC_100M (1 << MPIC_LSC_SHIFT) +#define MPIC_LSC_1G (2 << MPIC_LSC_SHIFT) +#define MPIC_LSC_2_5G (3 << MPIC_LSC_SHIFT) +#define MPIC_LSC_5G (4 << MPIC_LSC_SHIFT) +#define MPIC_LSC_10G (5 << MPIC_LSC_SHIFT) +#define MPIC_PSMCS_SHIFT 16 +#define MPIC_PSMCS_MASK GENMASK(22, MPIC_PSMCS_SHIFT) +#define MPIC_PSMCS(val) ((val) << MPIC_PSMCS_SHIFT) +#define MPIC_PSMHT_SHIFT 24 +#define MPIC_PSMHT_MASK GENMASK(26, MPIC_PSMHT_SHIFT) +#define MPIC_PSMHT(val) ((val) << MPIC_PSMHT_SHIFT) +#define MPSM_MFF_C45 BIT(2) +#define MLVC_PLV BIT(16) +#define MDIO_READ_C45 0x03 +#define MDIO_WRITE_C45 0x01 +#define MII_ADDR_C45 (1<<30) +#define MII_DEVADDR_C45_SHIFT 16 +#define MII_REGADDR_C45_MASK GENMASK(15, 0) +#define MMIS1_PAACS BIT(2) /* Address */ +#define MMIS1_PWACS BIT(1) /* Write */ +#define MMIS1_PRACS BIT(0) /* Read */ +#define MMIS1_CLEAR_FLAGS 0xf +#define MPSM_PSME BIT(0) +#define MPSM_MFF_C45 BIT(2) +#define MPSM_PDA_SHIFT 3 +#define MPSM_PDA_MASK GENMASK(7, MPSM_PDA_SHIFT) +#define MPSM_PDA(val) ((val) << MPSM_PDA_SHIFT) +#define MPSM_PRA_SHIFT 8 +#define MPSM_PRA_MASK GENMASK(12, MPSM_PRA_SHIFT) +#define MPSM_PRA(val) ((val) << MPSM_PRA_SHIFT) +#define MPSM_POP_SHIFT 13 +#define MPSM_POP_MASK GENMASK(14, MPSM_POP_SHIFT) +#define MPSM_POP(val) ((val) << MPSM_POP_SHIFT) +#define MPSM_PRD_SHIFT 16 +#define MPSM_PRD_MASK GENMASK(31, MPSM_PRD_SHIFT) +#define MPSM_PRD_WRITE(val) ((val) << MPSM_PRD_SHIFT) +#define MPSM_PRD_READ(val) ((val) & MPSM_PRD_MASK >> MPSM_PRD_SHIFT) + +#define TX_RX_RING_SIZE 32 +#define PKT_BUF_SZ 1584 +#define PKT_BUF_SZ_ALIGN 1792 /* 0x700 to keep elements aligned to the value + specified by RSWITCH_ALIGN */ +#define RSWITCH_ALIGN 1 /* kenel uses 128, so 7 bits (=log_2(128)) are enough + * to represent this value, so we round up to 1 byte. */ + +/* These elements should either be rswitch_ext_desc or rswitch_ext_ts_desc + * depending if gptp is used or not. */ +struct rswitch_ext_ts_desc rx_ring[TX_RX_RING_SIZE]; +struct rswitch_ext_desc tx_ring[TX_RX_RING_SIZE]; + +uint8 rx_data_buff[TX_RX_RING_SIZE][PKT_BUF_SZ_ALIGN] __attribute__((aligned(RSWITCH_ALIGN))); +uint8 tx_data_buff[TX_RX_RING_SIZE][PKT_BUF_SZ_ALIGN] __attribute__((aligned(RSWITCH_ALIGN))); + +struct rswitch_gwca_chain { + uint8 chain_index; + uint8 dir_tx; + // bool gptp; + union { + struct rswitch_ext_desc *ring; + struct rswitch_ext_ts_desc *ts_ring; + }; + uint32 num_ring; + uint32 cur; + uint32 dirty; + uint8 *data_buffers[TX_RX_RING_SIZE]; +}; + +struct rswitch_gwca { + uint8 port_num; + uint32 base_addr; + struct rswitch_gwca_chain rx_chain; + struct rswitch_gwca_chain tx_chain; + uint32 irq_queue; + int speed; +} gwca_props[PORT_GWCA_N] = { + { .port_num = GWCA0_PORT_NUM, .base_addr = RSWITCH_GWCA0_ADDR }, + { .port_num = GWCA1_PORT_NUM, .base_addr = RSWITCH_GWCA1_ADDR }, +}; + +struct rswitch_device { + struct rswitch_desc base_descriptors[NUM_CHAINS_PER_NDEV]; + struct rswitch_etha *etha; + struct rswitch_gwca *gwca; + uint32 fwd_base_addr; + uint32 coma_base_addr; +} rsw_dev = { + .fwd_base_addr = RSWITCH_FWD_ADDR, + .coma_base_addr = RSWITCH_COMA_ADDR, + .etha = ða_props[TSN_PORT_IN_USE], + .gwca = &gwca_props[GWCA_PORT_IN_USE], +}; + +/* MFWD */ +#define FWPC0_LTHTA BIT(0) +#define FWPC0_IP4UE BIT(3) +#define FWPC0_IP4TE BIT(4) +#define FWPC0_IP4OE BIT(5) +#define FWPC0_L2SE BIT(9) +#define FWPC0_IP4EA BIT(10) +#define FWPC0_IPDSA BIT(12) +#define FWPC0_IPHLA BIT(18) +#define FWPC0_MACSDA BIT(20) +#define FWPC0_MACHLA BIT(26) +#define FWPC0_MACHMA BIT(27) +#define FWPC0_VLANSA BIT(28) + +#define FWPC0(i) (FWPC00 + (i) * 0x10) +#define FWPC1(i) (FWPC10 + (i) * 0x10) +#define FWPC0_DEFAULT (FWPC0_LTHTA | FWPC0_IP4UE | FWPC0_IP4TE | \ + FWPC0_IP4OE | FWPC0_L2SE | FWPC0_IP4EA | \ + FWPC0_IPDSA | FWPC0_IPHLA | FWPC0_MACSDA | \ + FWPC0_MACHLA | FWPC0_MACHMA | FWPC0_VLANSA) +#define FWPC1_DDE BIT(0) +#define FWPBFC(i) (FWPBFCi + (i) * 0x10) +#define FWPBFCSDC(j, i) (FWPBFCSDC00 + (i) * 0x10 + (j) * 0x04) + +/* Interrupts */ +#define GWCA0_RX_TX_IRQ 312 +#define GWCA1_RX_TX_IRQ 320 +#define GWCA0_RX_TS_IRQ 328 +#define GWCA1_RX_TS_IRQ 330 +#define COMA_ERR_IRQ 290 +#define GWCA0_ERR_IRQ 291 +#define GWCA1_ERR_IRQ 292 +#define ETHA0_ERR_IRQ 293 +#define ETHA1_ERR_IRQ 294 +#define ETHA2_ERR_IRQ 295 + +#define RSWITCH_TIMEOUT_MS 1000 +static int rswitch_reg_wait(uint32 addr, uint32 mask, uint32 expected) +{ + int i; + + for (i = 0; i < RSWITCH_TIMEOUT_MS; i++) { + if ((reg_read32(addr) & mask) == expected) + return 0; + + ms_delay(1); + } + + return ERR_TIMEOUT; +} + +static void rswitch_modify(uint32 addr, uint32 clear, uint32 set) +{ + uint32 val = reg_read32(addr) & ~clear; + reg_write32(val | set, addr); +} + +static int rswitch_mii_set_access(struct rswitch_etha *etha, uint8 read, + uint32 phyad, uint32 devad, uint32 regad, + uint16 *data) +{ + int pop = read ? MDIO_READ_C45 : MDIO_WRITE_C45; + uint32 val; + int ret; + + /* Clear completion flags */ + reg_write32(MMIS1_CLEAR_FLAGS, etha->base_addr + MMIS1); + + /* Submit address to PHY (MDIO_ADDR_C45 << 13) */ + val = MPSM_PSME | MPSM_MFF_C45; + reg_write32((regad << 16) | (devad << 8) | (phyad << 3) | val, + etha->base_addr + MPSM); + + CHECK_RET(rswitch_reg_wait(etha->base_addr + MMIS1, MMIS1_PAACS, MMIS1_PAACS)); + + /* Clear address completion flag */ + rswitch_modify(etha->base_addr + MMIS1, MMIS1_PAACS, MMIS1_PAACS); + + /* Read/Write PHY register */ + if (read) { + reg_write32((pop << 13) | (devad << 8) | (phyad << 3) | val, + etha->base_addr + MPSM); + + CHECK_RET(rswitch_reg_wait(etha->base_addr + MMIS1, MMIS1_PRACS, MMIS1_PRACS)); + + /* Read data */ + ret = (reg_read32(etha->base_addr + MPSM) & MPSM_PRD_MASK) >> 16; + *data = ret; + + /* Clear read completion flag */ + rswitch_modify(etha->base_addr + MMIS1, MMIS1_PRACS, MMIS1_PRACS); + } else { + reg_write32((*data << 16) | (pop << 13) | (devad << 8) | (phyad << 3) | val, + etha->base_addr + MPSM); + + ret = rswitch_reg_wait(etha->base_addr + MMIS1, MMIS1_PWACS, MMIS1_PWACS); + } + + return 0; } -static inline void reg_write32(uint32 data, void *addr) +static int rswitch_mii_read(struct rswitch_etha *etha, uint32 phyaddr, + uint32 devad, uint32 regad, uint32 *data) { - *((volatile uint32*)addr) = data; + uint16 tmp; + int ret; + ret = rswitch_mii_set_access(etha, TRUE, phyaddr, devad, regad, &tmp); + *data = tmp; + + return ret; +} + +static int rswitch_mii_write(struct rswitch_etha *etha, uint32 phyaddr, + uint32 devad, uint32 regad, uint32 *data) +{ + uint16 tmp = (uint16) *data; + return rswitch_mii_set_access(etha, FALSE, phyaddr, devad, regad, &tmp); +} + +static int rswitch_agent_clock_is_enabled(int port) +{ + uint32 val = reg_read32(rsw_dev.coma_base_addr + RCEC); + + if (val & RCEC_RCE) + return (val & BIT(port)) ? TRUE : FALSE; + else + return FALSE; +} + +static void rswitch_agent_clock_ctrl(int port, int enable) +{ + uint32 val; + + if (enable) { + val = reg_read32(rsw_dev.coma_base_addr + RCEC); + reg_write32(val | RCEC_RCE | BIT(port), + rsw_dev.coma_base_addr + RCEC); + } else { + val = reg_read32(RCDC); + reg_write32(val | BIT(port), RCDC); + } +} + +// mac is supposed to be an array of 6 bytes +static void rswitch_etha_read_mac_address(struct rswitch_etha *eth_dev) +{ + uint32 mrmac0 = reg_read32(eth_dev->base_addr + MRMAC0); + uint32 mrmac1 = reg_read32(eth_dev->base_addr + MRMAC1); + + eth_dev->mac_addr[0] = (mrmac0 >> 8) & 0xFF; + eth_dev->mac_addr[1] = (mrmac0 >> 0) & 0xFF; + eth_dev->mac_addr[2] = (mrmac1 >> 24) & 0xFF; + eth_dev->mac_addr[3] = (mrmac1 >> 16) & 0xFF; + eth_dev->mac_addr[4] = (mrmac1 >> 8) & 0xFF; + eth_dev->mac_addr[5] = (mrmac1 >> 0) & 0xFF; +} + +/* This function sets only data in the global strucure, not on the hardware */ +static void rswitch_set_mac_address(struct rswitch_etha *eth_dev) +{ + int i; + + // Values from MCAL + static const uint8 predefined_mac_address[PORT_TSNA_N][6] = { + {0x74U, 0x90U, 0x50U, 0x00U, 0x00U, 0x00U}, + {0x74U, 0x90U, 0x50U, 0x00U, 0x00U, 0x01U}, + {0x74U, 0x90U, 0x50U, 0x00U, 0x00U, 0x02U}, + }; + + // Set only if not already valid (at least 1 value != 0) + for (i = 0; i < MAC_ADDRESS_LEN; i++) { + if (eth_dev->mac_addr[i] != 0) { + return; + } + } + + /* The following works only because TSN port's numbers starts from 0 as + * if they were indexes. */ + for (i = 0; i < MAC_ADDRESS_LEN; i++) { + eth_dev->mac_addr[i] = predefined_mac_address[eth_dev->port_num][i]; + } +} + +static void rswitch_soft_reset(void) +{ + reg_write32(RRC_RR, rsw_dev.coma_base_addr + RRC); + reg_write32(RRC_RR_CLR, rsw_dev.coma_base_addr + RRC); + + /* Clock initialization and module reset have already been done before + * in utils.c */ +} + +static int rswitch_gwca_change_mode(struct rswitch_gwca *gwca, + enum rswitch_gwca_mode mode) +{ + int ret; + + /* Enable clock */ + if (!rswitch_agent_clock_is_enabled(gwca->port_num)) + rswitch_agent_clock_ctrl(gwca->port_num, 1); + + reg_write32(mode, gwca->base_addr + GWMC); + + ret = rswitch_reg_wait(gwca->base_addr + GWMS, GWMS_OPS_MASK, mode); + + /* Disable clock */ + if (mode == GWMC_OPC_DISABLE) + rswitch_agent_clock_ctrl(gwca->port_num, 0); + + return ret; +} + +static int rswitch_gwca_mcast_table_reset(struct rswitch_gwca *gwca) +{ + reg_write32(GWMTIRM_MTIOG, gwca->base_addr + GWMTIRM); + return rswitch_reg_wait(gwca->base_addr + GWMTIRM, GWMTIRM_MTR, GWMTIRM_MTR); +} + +static int rswitch_gwca_axi_ram_reset(struct rswitch_gwca *gwca) +{ + reg_write32(GWARIRM_ARIOG, gwca->base_addr + GWARIRM); + return rswitch_reg_wait(gwca->base_addr + GWARIRM, GWARIRM_ARR, GWARIRM_ARR); +} + +static void rswitch_gwca_set_rate_limit(struct rswitch_gwca *gwca) +{ + uint32 gwgrlulc, gwgrlc; + + switch (gwca->speed) { + case 1000: + gwgrlulc = 0x0000005f; + gwgrlc = 0x00010260; + break; + default: + debug_msg("%s: This rate is not supported (%d)\n", __func__, gwca->speed); + return; + } + + reg_write32(gwgrlulc, gwca->base_addr + GWGRLULC); + reg_write32(gwgrlc, gwca->base_addr + GWGRLC); +} + +static int rswitch_gwca_hw_init(struct rswitch_device *rswitch) +{ + int ret, i; + uint64 descriptors_addr = (uint32) rswitch->base_descriptors; + struct rswitch_gwca *gwca = rswitch->gwca; + + /* Note: this is setting the base descriptors for all the devices but + * perhaps we should just set the one we are using. Setting for all + * might impact what Linux/Uboot has already configured on its side. */ + for (i = 0; i < NUM_CHAINS_PER_NDEV * NUM_DEVICES; i++) { + rswitch->base_descriptors[i].die_dt = DT_EOS; + } + + CHECK_RET(rswitch_gwca_change_mode(gwca, GWMC_OPC_DISABLE)); + CHECK_RET(rswitch_gwca_change_mode(gwca, GWMC_OPC_CONFIG)); + CHECK_RET(rswitch_gwca_mcast_table_reset(gwca)); + CHECK_RET(rswitch_gwca_axi_ram_reset(gwca)); + + /* Full setting flow */ + reg_write32(GWVCC_VEM_SC_TAG, gwca->base_addr + GWVCC); + reg_write32(0, gwca->base_addr + GWTTFC); + reg_write32(0x00, gwca->base_addr + GWDCBAC1); + reg_write32((descriptors_addr >> 32) & 0xFFFFFFFF, gwca->base_addr + GWDCBAC0); + + gwca->speed = 1000; + rswitch_gwca_set_rate_limit(gwca); + + CHECK_RET(rswitch_gwca_change_mode(gwca, GWMC_OPC_DISABLE)); + CHECK_RET(rswitch_gwca_change_mode(gwca, GWMC_OPC_OPERATION)); + + return 0; +} + +static void rswitch_gwca_chain_format(struct rswitch_device *rswitch, + struct rswitch_gwca_chain *c) +{ + struct rswitch_ext_desc *ring; + struct rswitch_desc *base_desc; + int tx_ring_size = sizeof(*ring) * c->num_ring; + int i; + + memset(c->ring, 0, tx_ring_size); + for (i = 0, ring = c->ring; i < c->num_ring; i++, ring++) { + if (!c->dir_tx) { + ring->info_ds = PKT_BUF_SZ; + ring->dptrl = (uint32) c->data_buffers[i]; + ring->dptrh = 0x00; + ring->die_dt = DT_FEMPTY | DIE; + } else { + ring->die_dt = DT_EEMPTY | DIE; + } + } + + /* Close the loop */ + ring->dptrl = (uint32) c->ring; + ring->dptrh = 0x00; + ring->die_dt = DT_LINKFIX; + + /* Configure the base descriptor */ + base_desc = &rswitch->base_descriptors[c->chain_index]; + base_desc->die_dt = DT_LINKFIX; + base_desc->dptrl = (uint32) c->ring; + base_desc->dptrh = 0x00; + + /* FIXME: GWDCC_DCP */ + reg_write32(GWDCC_BALR | (c->dir_tx ? GWDCC_DQT : 0) | GWDCC_EDE, + rswitch->gwca->base_addr + GWDCC_OFFS(c->chain_index)); +} + +static __unused void rswitch_gwca_chain_ts_format(struct rswitch_device *rswitch, + struct rswitch_gwca_chain *c) +{ + struct rswitch_ext_ts_desc *ring; + struct rswitch_desc *base_desc; + int tx_ring_size = sizeof(*ring) * c->num_ring; + int i; + + memset(c->ring, 0, tx_ring_size); + for (i = 0, ring = c->ts_ring; i < c->num_ring; i++, ring++) { + if (!c->dir_tx) { + ring->info_ds = PKT_BUF_SZ; + ring->dptrl = (uint32) c->data_buffers[i]; + ring->dptrh = 0x00; + ring->die_dt = DT_FEMPTY | DIE; + } else { + ring->die_dt = DT_EEMPTY | DIE; + } + } + + /* Close the loop */ + ring->dptrl = (uint32) c->ring; + ring->dptrh = 0x00; + ring->die_dt = DT_LINKFIX; + + /* Configure the base descriptor */ + base_desc = &rswitch->base_descriptors[c->chain_index]; + base_desc->die_dt = DT_LINKFIX; + base_desc->dptrl = (uint32) c->ring; + base_desc->dptrh = 0x00; + + /* FIXME: GWDCC_DCP */ + reg_write32(GWDCC_BALR | (c->dir_tx ? GWDCC_DQT : 0) | GWDCC_ETS | GWDCC_EDE, + rswitch->gwca->base_addr + GWDCC_OFFS(c->chain_index)); +} + +static int rswitch_bpool_config(struct rswitch_device *rswitch) +{ + uint32 val; + + val = reg_read32(rswitch->coma_base_addr + CABPIRM); + if (val & CABPIRM_BPR) + return 0; + + reg_write32(CABPIRM_BPIOG, rswitch->coma_base_addr + CABPIRM); + return rswitch_reg_wait(rswitch->coma_base_addr + CABPIRM, CABPIRM_BPR, CABPIRM_BPR); +} + +static void rswitch_fwd_init(struct rswitch_device *rswitch) +{ + int i; + int eth_port_num = rswitch->etha->port_num; + int gwca_port_num = rswitch->gwca->port_num; + int gwca_idx = RSWITCH_HW_NUM_TO_GWCA_IDX(gwca_port_num); + + /* Note: this configures FWD for all the ports, but this might conflict + * with previous configurations... */ + for (i = 0; i < TOT_PORT_NUM; i++) { + reg_write32(FWPC0_DEFAULT, rswitch->fwd_base_addr + FWPC0(i)); + reg_write32(0, rswitch->fwd_base_addr + FWPBFC(i)); + } + + /* Static routing between the specified ETHA and GWCA ports. */ + reg_write32(rswitch->gwca->rx_chain.chain_index, + rswitch->fwd_base_addr + FWPBFCSDC(gwca_idx, eth_port_num)); + reg_write32(BIT(rswitch->gwca->port_num), + rswitch->fwd_base_addr + FWPBFC(eth_port_num)); + + /* For GWCA */ + reg_write32(FWPC0_DEFAULT, rswitch->fwd_base_addr + FWPC0(gwca_port_num)); + reg_write32(FWPC1_DDE, rswitch->fwd_base_addr + FWPC1(gwca_port_num)); + reg_write32(0, rswitch->fwd_base_addr + FWPBFC(gwca_port_num)); + reg_write32(eth_port_num, rswitch->fwd_base_addr + FWPBFC(gwca_port_num)); +} + +static __unused void rswitch_get_data_irq_status(struct rswitch_device *rswitch, uint32 *dis) +{ + int i; + + for (i = 0; i < RSWITCH_NUM_IRQ_REGS; i++) { + dis[i] = reg_read32(rswitch->gwca->base_addr + GWDIS0 + i * 0x10); + } +} + +static void rswitch_enadis_data_irq(struct rswitch_gwca *gwca, int index, + int enable) +{ + uint32 offs = (enable ? GWDIE0 : GWDID0) + (index / 32) * 0x10; + uint32 tmp = 0; + + /* For VPF? */ + if (enable) + tmp = reg_read32(gwca->base_addr + offs); + + reg_write32(BIT(index % 32) | tmp, gwca->base_addr + offs); +} + +static void rswitch_enable_irqs(void) +{ + /* Enables IRQs on the core side */ + enable_int(GWCA1_RX_TX_IRQ); + enable_int(GWCA1_RX_TS_IRQ); + enable_int(GWCA1_ERR_IRQ); + enable_int(ETHA0_ERR_IRQ); + enable_int(COMA_ERR_IRQ); } int rswitch_init(void) { + int i, ret; + + // Enable clocks to all the agents + for (i = 0; i < TOT_PORT_NUM; i++) { + rswitch_agent_clock_ctrl(i, 1); + } + + /* Read MAC addresses (since it's only reading it does not affect other + * ports that we are not using) */ + for (i = 0; i < NUM_DEVICES; i++) { + rswitch_etha_read_mac_address(ða_props[i]); + } + + rswitch_soft_reset(); + + CHECK_RET(rswitch_gwca_hw_init(&rsw_dev)); + + /* Copy speed property from GWCA */ + rsw_dev.etha->speed = rsw_dev.gwca->speed; + + rswitch_set_mac_address(rsw_dev.etha); + + rsw_dev.gwca->rx_chain.chain_index = 0; + rsw_dev.gwca->rx_chain.ts_ring = rx_ring; + for (i = 0; i < TX_RX_RING_SIZE; i++) { + rsw_dev.gwca->rx_chain.data_buffers[i] = rx_data_buff[i]; + } + rsw_dev.gwca->rx_chain.num_ring = TX_RX_RING_SIZE; + rsw_dev.gwca->rx_chain.dir_tx = 0; + rswitch_gwca_chain_ts_format(&rsw_dev, &(rsw_dev.gwca->rx_chain)); + rsw_dev.gwca->irq_queue = 0; + + rsw_dev.gwca->tx_chain.chain_index = 1; + rsw_dev.gwca->tx_chain.ring = tx_ring; + for (i = 0; i < TX_RX_RING_SIZE; i++) { + rsw_dev.gwca->tx_chain.data_buffers[i] = tx_data_buff[i]; + } + rsw_dev.gwca->tx_chain.num_ring = TX_RX_RING_SIZE; + rsw_dev.gwca->tx_chain.dir_tx = 1; + rswitch_gwca_chain_format(&rsw_dev, &(rsw_dev.gwca->tx_chain)); + rsw_dev.gwca->irq_queue = 1; + + CHECK_RET(rswitch_bpool_config(&rsw_dev)); + + rswitch_fwd_init(&rsw_dev); + + rswitch_enable_irqs(); + + return 0; +} + +static int rswitch_etha_change_mode(struct rswitch_etha *etha, + enum rswitch_etha_mode mode) +{ + int ret; + + /* Enable clock */ + if (!rswitch_agent_clock_is_enabled(etha->port_num)) + rswitch_agent_clock_ctrl(etha->port_num, 1); + + reg_write32(mode, etha->base_addr + EAMC); + + ret = rswitch_reg_wait(etha->base_addr + EAMS, EAMS_OPS_MASK, mode); + + /* Disable clock */ + if (mode == EAMC_OPC_DISABLE) + rswitch_agent_clock_ctrl(etha->port_num, 0); + + return ret; +} + +static void rswitch_rmac_setting(struct rswitch_etha *etha) +{ + uint32 val; + + switch (etha->speed) { + case 10: + val = MPIC_LSC_10M; + break; + case 100: + val = MPIC_LSC_100M; + break; + case 1000: + val = MPIC_LSC_1G; + break; + default: + return; + } + + reg_write32(MPIC_PIS_GMII | val, etha->base_addr + MPIC); +} + +static void rswitch_etha_enable_mii(struct rswitch_etha *etha) +{ + rswitch_modify(etha->base_addr + MPIC, MPIC_PSMCS_MASK | MPIC_PSMHT_MASK, + MPIC_PSMCS(0x05) | MPIC_PSMHT(0x06)); + rswitch_modify(etha->base_addr + MPSM, 0, MPSM_MFF_C45); +} + +static uint8 rswitch_etha_wait_link_verification(struct rswitch_etha *etha) +{ + /* Request Link Verification */ + reg_write32(MLVC_PLV, etha->base_addr + MLVC); + return rswitch_reg_wait(etha->base_addr + MLVC, MLVC_PLV, 0); +} + +static int rswitch_etha_hw_init(struct rswitch_etha *etha) +{ + int ret; + + /* Change to CONFIG Mode */ + CHECK_RET(rswitch_etha_change_mode(etha, EAMC_OPC_DISABLE)); + CHECK_RET(rswitch_etha_change_mode(etha, EAMC_OPC_CONFIG)); + + reg_write32(EAVCC_VEM_SC_TAG, etha->base_addr + EAVCC); + + rswitch_rmac_setting(etha); + rswitch_etha_enable_mii(etha); + + /* Change to OPERATION Mode */ + CHECK_RET(rswitch_etha_change_mode(etha, EAMC_OPC_OPERATION)); + + /* Link Verification */ + return rswitch_etha_wait_link_verification(etha); +} + +static int rswitch_phy_init(struct rswitch_etha *etha) +{ + uint32 reg_data; + int ret; + + /* Reset */ + CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0xC04A, ®_data)); + reg_data |= BIT(15); + CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0xC04A, ®_data)); + CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0xC04A, ®_data)); /* MCAL does it twice... */ + + /* Check mode */ + CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0xC04A, ®_data)); + if ((reg_data & 0x7) != 0x4 ) { /* 4 stands for SGMII */ + reg_data &= ~0x7; + reg_data |= BIT(15) | 0x4; + CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0xC04A, ®_data)); + + /* Run SERDES Init */ + CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0x800F, ®_data)); + reg_data |= BIT(15) | BIT(13); + CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0x800F, ®_data)); + + reg_data = 0x0U; + do { + CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0x800F, ®_data)); + } while (reg_data & BIT(15)); + + /* Auto SERDES Init Disable */ + reg_data &= ~BIT(13); + CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0x800F, ®_data)); + } + + return 0; +} + +int rswitch_open(void) +{ + int ret; + + CHECK_RET(rswitch_etha_hw_init(rsw_dev.etha)); + CHECK_RET(rswitch_phy_init(rsw_dev.etha)); + + /* Enable RX */ + rswitch_modify(rsw_dev.gwca->base_addr + GWTRC0, 0, + BIT(rsw_dev.gwca->rx_chain.chain_index)); + + /* Enable interrupt */ + rswitch_enadis_data_irq(rsw_dev.gwca, rsw_dev.gwca->tx_chain.chain_index, + TRUE); + rswitch_enadis_data_irq(rsw_dev.gwca, rsw_dev.gwca->rx_chain.chain_index, + TRUE); + return 0; } \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h index 4bee5aae7..fee6f6333 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h @@ -2,5 +2,6 @@ #define _ETH_H_ int rswitch_init(void); +int rswitch_open(void); #endif /* _ETH_H_ */ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h b/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h new file mode 100644 index 000000000..20646df12 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h @@ -0,0 +1,659 @@ +#ifndef RSWITCH_REGS_H +#define RSWITCH_REGS_H + +#define RSWITCH_BASE 0xE6880000 + +#define RSWITCH_FWD_ADDR (RSWITCH_BASE + 0x00000000) +#define RSWITCH_FAB_ADDR (RSWITCH_BASE + 0x00008000) +#define RSWITCH_COMA_ADDR (RSWITCH_BASE + 0x00009000) +#define RSWITCH_ETHA0_ADDR (RSWITCH_BASE + 0x0000a000) +#define RSWITCH_ETHA1_ADDR (RSWITCH_BASE + 0x0000c000) +#define RSWITCH_ETHA2_ADDR (RSWITCH_BASE + 0x0000e000) +#define RSWITCH_GWCA0_ADDR (RSWITCH_BASE + 0x00010000) +#define RSWITCH_GWCA1_ADDR (RSWITCH_BASE + 0x00012000) +#define RSWITCH_GPTP_ADDR (RSWITCH_BASE + 0x00018000) + +#define FWRO 0 +#define CARO 0 +#define GWRO 0 +#define TARO 0 +#define RMRO 0x1000 + +#define FWGC (FWRO + 0x0000) +#define FWTTC0 (FWRO + 0x0010) +#define FWTTC1 (FWRO + 0x0014) +#define FWLBMC (FWRO + 0x0018) +#define FWCEPTC (FWRO + 0x020) +#define FWCEPRC0 (FWRO + 0x024) +#define FWCEPRC1 (FWRO + 0x028) +#define FWCEPRC2 (FWRO + 0x02C) +#define FWCLPTC (FWRO + 0x030) +#define FWCLPRC (FWRO + 0x034) +#define FWCMPTC (FWRO + 0x040) +#define FWEMPTC (FWRO + 0x044) +#define FWSDMPTC (FWRO + 0x050) +#define FWSDMPVC (FWRO + 0x054) +#define FWLBWMC0 (FWRO + 0x080) +#define FWPC00 (FWRO + 0x100) +#define FWPC10 (FWRO + 0x104) +#define FWPC20 (FWRO + 0x108) +#define FWCTGC00 (FWRO + 0x400) +#define FWCTGC10 (FWRO + 0x404) +#define FWCTTC00 (FWRO + 0x408) +#define FWCTTC10 (FWRO + 0x40C) +#define FWCTTC200 (FWRO + 0x410) +#define FWCTSC00 (FWRO + 0x420) +#define FWCTSC10 (FWRO + 0x424) +#define FWCTSC20 (FWRO + 0x428) +#define FWCTSC30 (FWRO + 0x42C) +#define FWCTSC40 (FWRO + 0x430) +#define FWTWBFC0 (FWRO + 0x1000) +#define FWTWBFVC0 (FWRO + 0x1004) +#define FWTHBFC0 (FWRO + 0x1400) +#define FWTHBFV0C0 (FWRO + 0x1404) +#define FWTHBFV1C0 (FWRO + 0x1408) +#define FWFOBFC0 (FWRO + 0x1800) +#define FWFOBFV0C0 (FWRO + 0x1804) +#define FWFOBFV1C0 (FWRO + 0x1808) +#define FWRFC0 (FWRO + 0x1C00) +#define FWRFVC0 (FWRO + 0x1C04) +#define FWCFC0 (FWRO + 0x2000) +#define FWCFMC00 (FWRO + 0x2004) +#define FWIP4SC (FWRO + 0x4008) +#define FWIP6SC (FWRO + 0x4018) +#define FWIP6OC (FWRO + 0x401C) +#define FWL2SC (FWRO + 0x4020) +#define FWSFHEC (FWRO + 0x4030) +#define FWSHCR0 (FWRO + 0x4040) +#define FWSHCR1 (FWRO + 0x4044) +#define FWSHCR2 (FWRO + 0x4048) +#define FWSHCR3 (FWRO + 0x404C) +#define FWSHCR4 (FWRO + 0x4050) +#define FWSHCR5 (FWRO + 0x4054) +#define FWSHCR6 (FWRO + 0x4058) +#define FWSHCR7 (FWRO + 0x405C) +#define FWSHCR8 (FWRO + 0x4060) +#define FWSHCR9 (FWRO + 0x4064) +#define FWSHCR10 (FWRO + 0x4068) +#define FWSHCR11 (FWRO + 0x406C) +#define FWSHCR12 (FWRO + 0x4070) +#define FWSHCR13 (FWRO + 0x4074) +#define FWSHCRR (FWRO + 0x4078) +#define FWLTHHEC (FWRO + 0x4090) +#define FWLTHHC (FWRO + 0x4094) +#define FWLTHTL0 (FWRO + 0x40A0) +#define FWLTHTL1 (FWRO + 0x40A4) +#define FWLTHTL2 (FWRO + 0x40A8) +#define FWLTHTL3 (FWRO + 0x40AC) +#define FWLTHTL4 (FWRO + 0x40B0) +#define FWLTHTL5 (FWRO + 0x40B4) +#define FWLTHTL6 (FWRO + 0x40B8) +#define FWLTHTL7 (FWRO + 0x40BC) +#define FWLTHTL80 (FWRO + 0x40C0) +#define FWLTHTL9 (FWRO + 0x40D0) +#define FWLTHTLR (FWRO + 0x40D4) +#define FWLTHTIM (FWRO + 0x40E0) +#define FWLTHTEM (FWRO + 0x40E4) +#define FWLTHTS0 (FWRO + 0x4100) +#define FWLTHTS1 (FWRO + 0x4104) +#define FWLTHTS2 (FWRO + 0x4108) +#define FWLTHTS3 (FWRO + 0x410C) +#define FWLTHTS4 (FWRO + 0x4110) +#define FWLTHTSR0 (FWRO + 0x4120) +#define FWLTHTSR1 (FWRO + 0x4124) +#define FWLTHTSR2 (FWRO + 0x4128) +#define FWLTHTSR3 (FWRO + 0x412C) +#define FWLTHTSR40 (FWRO + 0x4130) +#define FWLTHTSR5 (FWRO + 0x4140) +#define FWLTHTR (FWRO + 0x4150) +#define FWLTHTRR0 (FWRO + 0x4154) +#define FWLTHTRR1 (FWRO + 0x4158) +#define FWLTHTRR2 (FWRO + 0x415C) +#define FWLTHTRR3 (FWRO + 0x4160) +#define FWLTHTRR4 (FWRO + 0x4164) +#define FWLTHTRR5 (FWRO + 0x4168) +#define FWLTHTRR6 (FWRO + 0x416C) +#define FWLTHTRR7 (FWRO + 0x4170) +#define FWLTHTRR8 (FWRO + 0x4174) +#define FWLTHTRR9 (FWRO + 0x4180) +#define FWLTHTRR10 (FWRO + 0x4190) +#define FWIPHEC (FWRO + 0x4214) +#define FWIPHC (FWRO + 0x4218) +#define FWIPTL0 (FWRO + 0x4220) +#define FWIPTL1 (FWRO + 0x4224) +#define FWIPTL2 (FWRO + 0x4228) +#define FWIPTL3 (FWRO + 0x422C) +#define FWIPTL4 (FWRO + 0x4230) +#define FWIPTL5 (FWRO + 0x4234) +#define FWIPTL6 (FWRO + 0x4238) +#define FWIPTL7 (FWRO + 0x4240) +#define FWIPTL8 (FWRO + 0x4250) +#define FWIPTLR (FWRO + 0x4254) +#define FWIPTIM (FWRO + 0x4260) +#define FWIPTEM (FWRO + 0x4264) +#define FWIPTS0 (FWRO + 0x4270) +#define FWIPTS1 (FWRO + 0x4274) +#define FWIPTS2 (FWRO + 0x4278) +#define FWIPTS3 (FWRO + 0x427C) +#define FWIPTS4 (FWRO + 0x4280) +#define FWIPTSR0 (FWRO + 0x4284) +#define FWIPTSR1 (FWRO + 0x4288) +#define FWIPTSR2 (FWRO + 0x428C) +#define FWIPTSR3 (FWRO + 0x4290) +#define FWIPTSR4 (FWRO + 0x42A0) +#define FWIPTR (FWRO + 0x42B0) +#define FWIPTRR0 (FWRO + 0x42B4) +#define FWIPTRR1 (FWRO + 0x42B8) +#define FWIPTRR2 (FWRO + 0x42BC) +#define FWIPTRR3 (FWRO + 0x42C0) +#define FWIPTRR4 (FWRO + 0x42C4) +#define FWIPTRR5 (FWRO + 0x42C8) +#define FWIPTRR6 (FWRO + 0x42CC) +#define FWIPTRR7 (FWRO + 0x42D0) +#define FWIPTRR8 (FWRO + 0x42E0) +#define FWIPTRR9 (FWRO + 0x42F0) +#define FWIPHLEC (FWRO + 0x4300) +#define FWIPAGUSPC (FWRO + 0x4500) +#define FWIPAGC (FWRO + 0x4504) +#define FWIPAGM0 (FWRO + 0x4510) +#define FWIPAGM1 (FWRO + 0x4514) +#define FWIPAGM2 (FWRO + 0x4518) +#define FWIPAGM3 (FWRO + 0x451C) +#define FWIPAGM4 (FWRO + 0x4520) +#define FWMACHEC (FWRO + 0x4620) +#define FWMACHC (FWRO + 0x4624) +#define FWMACTL0 (FWRO + 0x4630) +#define FWMACTL1 (FWRO + 0x4634) +#define FWMACTL2 (FWRO + 0x4638) +#define FWMACTL3 (FWRO + 0x463C) +#define FWMACTL4 (FWRO + 0x4640) +#define FWMACTL5 (FWRO + 0x4650) +#define FWMACTLR (FWRO + 0x4654) +#define FWMACTIM (FWRO + 0x4660) +#define FWMACTEM (FWRO + 0x4664) +#define FWMACTS0 (FWRO + 0x4670) +#define FWMACTS1 (FWRO + 0x4674) +#define FWMACTSR0 (FWRO + 0x4678) +#define FWMACTSR1 (FWRO + 0x467C) +#define FWMACTSR2 (FWRO + 0x4680) +#define FWMACTSR3 (FWRO + 0x4690) +#define FWMACTR (FWRO + 0x46A0) +#define FWMACTRR0 (FWRO + 0x46A4) +#define FWMACTRR1 (FWRO + 0x46A8) +#define FWMACTRR2 (FWRO + 0x46AC) +#define FWMACTRR3 (FWRO + 0x46B0) +#define FWMACTRR4 (FWRO + 0x46B4) +#define FWMACTRR5 (FWRO + 0x46C0) +#define FWMACTRR6 (FWRO + 0x46D0) +#define FWMACHLEC (FWRO + 0x4700) +#define FWMACAGUSPC (FWRO + 0x4880) +#define FWMACAGC (FWRO + 0x4884) +#define FWMACAGM0 (FWRO + 0x4888) +#define FWMACAGM1 (FWRO + 0x488C) +#define FWVLANTEC (FWRO + 0x4900) +#define FWVLANTL0 (FWRO + 0x4910) +#define FWVLANTL1 (FWRO + 0x4914) +#define FWVLANTL2 (FWRO + 0x4918) +#define FWVLANTL3 (FWRO + 0x4920) +#define FWVLANTL4 (FWRO + 0x4930) +#define FWVLANTLR (FWRO + 0x4934) +#define FWVLANTIM (FWRO + 0x4940) +#define FWVLANTEM (FWRO + 0x4944) +#define FWVLANTS (FWRO + 0x4950) +#define FWVLANTSR0 (FWRO + 0x4954) +#define FWVLANTSR1 (FWRO + 0x4958) +#define FWVLANTSR2 (FWRO + 0x4960) +#define FWVLANTSR3 (FWRO + 0x4970) +#define FWPBFCi (FWRO + 0x4A00) +#define FWPBFCSDC00 (FWRO + 0x4A04) +#define FWL23URL0 (FWRO + 0x4E00) +#define FWL23URL1 (FWRO + 0x4E04) +#define FWL23URL2 (FWRO + 0x4E08) +#define FWL23URL3 (FWRO + 0x4E0C) +#define FWL23URLR (FWRO + 0x4E10) +#define FWL23UTIM (FWRO + 0x4E20) +#define FWL23URR (FWRO + 0x4E30) +#define FWL23URRR0 (FWRO + 0x4E34) +#define FWL23URRR1 (FWRO + 0x4E38) +#define FWL23URRR2 (FWRO + 0x4E3C) +#define FWL23URRR3 (FWRO + 0x4E40) +#define FWL23URMC0 (FWRO + 0x4F00) +#define FWPMFGC0 (FWRO + 0x5000) +#define FWPGFC0 (FWRO + 0x5100) +#define FWPGFIGSC0 (FWRO + 0x5104) +#define FWPGFENC0 (FWRO + 0x5108) +#define FWPGFENM0 (FWRO + 0x510c) +#define FWPGFCSTC00 (FWRO + 0x5110) +#define FWPGFCSTC10 (FWRO + 0x5114) +#define FWPGFCSTM00 (FWRO + 0x5118) +#define FWPGFCSTM10 (FWRO + 0x511C) +#define FWPGFCTC0 (FWRO + 0x5120) +#define FWPGFCTM0 (FWRO + 0x5124) +#define FWPGFHCC0 (FWRO + 0x5128) +#define FWPGFSM0 (FWRO + 0x512C) +#define FWPGFGC0 (FWRO + 0x5130) +#define FWPGFGL0 (FWRO + 0x5500) +#define FWPGFGL1 (FWRO + 0x5504) +#define FWPGFGLR (FWRO + 0x5518) +#define FWPGFGR (FWRO + 0x5510) +#define FWPGFGRR0 (FWRO + 0x5514) +#define FWPGFGRR1 (FWRO + 0x5518) +#define FWPGFRIM (FWRO + 0x5520) +#define FWPMTRFC0 (FWRO + 0x5600) +#define FWPMTRCBSC0 (FWRO + 0x5604) +#define FWPMTRC0RC0 (FWRO + 0x5608) +#define FWPMTREBSC0 (FWRO + 0x560C) +#define FWPMTREIRC0 (FWRO + 0x5610) +#define FWPMTRFM0 (FWRO + 0x5614) +#define FWFTL0 (FWRO + 0x6000) +#define FWFTL1 (FWRO + 0x6004) +#define FWFTLR (FWRO + 0x6008) +#define FWFTOC (FWRO + 0x6010) +#define FWFTOPC (FWRO + 0x6014) +#define FWFTIM (FWRO + 0x6020) +#define FWFTR (FWRO + 0x6030) +#define FWFTRR0 (FWRO + 0x6034) +#define FWFTRR1 (FWRO + 0x6038) +#define FWFTRR2 (FWRO + 0x603C) +#define FWSEQNGC0 (FWRO + 0x6100) +#define FWSEQNGM0 (FWRO + 0x6104) +#define FWSEQNRC (FWRO + 0x6200) +#define FWCTFDCN0 (FWRO + 0x6300) +#define FWLTHFDCN0 (FWRO + 0x6304) +#define FWIPFDCN0 (FWRO + 0x6308) +#define FWLTWFDCN0 (FWRO + 0x630C) +#define FWPBFDCN0 (FWRO + 0x6310) +#define FWMHLCN0 (FWRO + 0x6314) +#define FWIHLCN0 (FWRO + 0x6318) +#define FWICRDCN0 (FWRO + 0x6500) +#define FWWMRDCN0 (FWRO + 0x6504) +#define FWCTRDCN0 (FWRO + 0x6508) +#define FWLTHRDCN0 (FWRO + 0x650C) +#define FWIPRDCN0 (FWRO + 0x6510) +#define FWLTWRDCN0 (FWRO + 0x6514) +#define FWPBRDCN0 (FWRO + 0x6518) +#define FWPMFDCN0 (FWRO + 0x6700) +#define FWPGFDCN0 (FWRO + 0x6780) +#define FWPMGDCN0 (FWRO + 0x6800) +#define FWPMYDCN0 (FWRO + 0x6804) +#define FWPMRDCN0 (FWRO + 0x6808) +#define FWFRPPCN0 (FWRO + 0x6A00) +#define FWFRDPCN0 (FWRO + 0x6A04) +#define FWEIS00 (FWRO + 0x7900) +#define FWEIE00 (FWRO + 0x7904) +#define FWEID00 (FWRO + 0x7908) +#define FWEIS1 (FWRO + 0x7A00) +#define FWEIE1 (FWRO + 0x7A04) +#define FWEID1 (FWRO + 0x7A08) +#define FWEIS2 (FWRO + 0x7A10) +#define FWEIE2 (FWRO + 0x7A14) +#define FWEID2 (FWRO + 0x7A18) +#define FWEIS3 (FWRO + 0x7A20) +#define FWEIE3 (FWRO + 0x7A24) +#define FWEID3 (FWRO + 0x7A28) +#define FWEIS4 (FWRO + 0x7A30) +#define FWEIE4 (FWRO + 0x7A34) +#define FWEID4 (FWRO + 0x7A38) +#define FWEIS5 (FWRO + 0x7A40) +#define FWEIE5 (FWRO + 0x7A44) +#define FWEID5 (FWRO + 0x7A48) +#define FWEIS60 (FWRO + 0x7A50) +#define FWEIE60 (FWRO + 0x7A54) +#define FWEID60 (FWRO + 0x7A58) +#define FWEIS61 (FWRO + 0x7A60) +#define FWEIE61 (FWRO + 0x7A64) +#define FWEID61 (FWRO + 0x7A68) +#define FWEIS62 (FWRO + 0x7A70) +#define FWEIE62 (FWRO + 0x7A74) +#define FWEID62 (FWRO + 0x7A78) +#define FWEIS63 (FWRO + 0x7A80) +#define FWEIE63 (FWRO + 0x7A84) +#define FWEID63 (FWRO + 0x7A88) +#define FWEIS70 (FWRO + 0x7A90) +#define FWEIE70 (FWRO + 0x7A94) +#define FWEID70 (FWRO + 0x7A98) +#define FWEIS71 (FWRO + 0x7AA0) +#define FWEIE71 (FWRO + 0x7AA4) +#define FWEID71 (FWRO + 0x7AA8) +#define FWEIS72 (FWRO + 0x7AB0) +#define FWEIE72 (FWRO + 0x7AB4) +#define FWEID72 (FWRO + 0x7AB8) +#define FWEIS73 (FWRO + 0x7AC0) +#define FWEIE73 (FWRO + 0x7AC4) +#define FWEID73 (FWRO + 0x7AC8) +#define FWEIS80 (FWRO + 0x7AD0) +#define FWEIE80 (FWRO + 0x7AD4) +#define FWEID80 (FWRO + 0x7AD8) +#define FWEIS81 (FWRO + 0x7AE0) +#define FWEIE81 (FWRO + 0x7AE4) +#define FWEID81 (FWRO + 0x7AE8) +#define FWEIS82 (FWRO + 0x7AF0) +#define FWEIE82 (FWRO + 0x7AF4) +#define FWEID82 (FWRO + 0x7AF8) +#define FWEIS83 (FWRO + 0x7B00) +#define FWEIE83 (FWRO + 0x7B04) +#define FWEID83 (FWRO + 0x7B08) +#define FWMIS0 (FWRO + 0x7C00) +#define FWMIE0 (FWRO + 0x7C04) +#define FWMID0 (FWRO + 0x7C08) +#define FWSCR0 (FWRO + 0x7D00) +#define FWSCR1 (FWRO + 0x7D04) +#define FWSCR2 (FWRO + 0x7D08) +#define FWSCR3 (FWRO + 0x7D0C) +#define FWSCR4 (FWRO + 0x7D10) +#define FWSCR5 (FWRO + 0x7D14) +#define FWSCR6 (FWRO + 0x7D18) +#define FWSCR7 (FWRO + 0x7D1C) +#define FWSCR8 (FWRO + 0x7D20) +#define FWSCR9 (FWRO + 0x7D24) +#define FWSCR10 (FWRO + 0x7D28) +#define FWSCR11 (FWRO + 0x7D2C) +#define FWSCR12 (FWRO + 0x7D30) +#define FWSCR13 (FWRO + 0x7D34) +#define FWSCR14 (FWRO + 0x7D38) +#define FWSCR15 (FWRO + 0x7D3C) +#define FWSCR16 (FWRO + 0x7D40) +#define FWSCR17 (FWRO + 0x7D44) +#define FWSCR18 (FWRO + 0x7D48) +#define FWSCR19 (FWRO + 0x7D4C) +#define FWSCR20 (FWRO + 0x7D50) +#define FWSCR21 (FWRO + 0x7D54) +#define FWSCR22 (FWRO + 0x7D58) +#define FWSCR23 (FWRO + 0x7D5C) +#define FWSCR24 (FWRO + 0x7D60) +#define FWSCR25 (FWRO + 0x7D64) +#define FWSCR26 (FWRO + 0x7D68) +#define FWSCR27 (FWRO + 0x7D6C) +#define FWSCR28 (FWRO + 0x7D70) +#define FWSCR29 (FWRO + 0x7D74) +#define FWSCR30 (FWRO + 0x7D78) +#define FWSCR31 (FWRO + 0x7D7C) +#define FWSCR32 (FWRO + 0x7D80) +#define FWSCR33 (FWRO + 0x7D84) +#define FWSCR34 (FWRO + 0x7D88) +#define FWSCR35 (FWRO + 0x7D8C) +#define FWSCR36 (FWRO + 0x7D90) +#define FWSCR37 (FWRO + 0x7D94) +#define FWSCR38 (FWRO + 0x7D98) +#define FWSCR39 (FWRO + 0x7D9C) +#define FWSCR40 (FWRO + 0x7DA0) +#define FWSCR41 (FWRO + 0x7DA4) +#define FWSCR42 (FWRO + 0x7DA8) +#define FWSCR43 (FWRO + 0x7DAC) +#define FWSCR44 (FWRO + 0x7DB0) +#define FWSCR45 (FWRO + 0x7DB4) +#define FWSCR46 (FWRO + 0x7DB8) + +#define RIPV (CARO + 0x0000) +#define RRC (CARO + 0x0004) +#define RCEC (CARO + 0x0008) +#define RCDC (CARO + 0x000C) +#define RSSIS (CARO + 0x0010) +#define RSSIE (CARO + 0x0014) +#define RSSID (CARO + 0x0018) +#define CABPIBWMC (CARO + 0x0020) +#define CABPWMLC (CARO + 0x0040) +#define CABPPFLC0 (CARO + 0x0050) +#define CABPPWMLC0 (CARO + 0x0060) +#define CABPPPFLC00 (CARO + 0x00A0) +#define CABPULC (CARO + 0x0100) +#define CABPIRM (CARO + 0x0140) +#define CABPPCM (CARO + 0x0144) +#define CABPLCM (CARO + 0x0148) +#define CABPCPM (CARO + 0x0180) +#define CABPMCPM (CARO + 0x0200) +#define CARDNM (CARO + 0x0280) +#define CARDMNM (CARO + 0x0284) +#define CARDCN (CARO + 0x0290) +#define CAEIS0 (CARO + 0x0300) +#define CAEIE0 (CARO + 0x0304) +#define CAEID0 (CARO + 0x0308) +#define CAEIS1 (CARO + 0x0310) +#define CAEIE1 (CARO + 0x0314) +#define CAEID1 (CARO + 0x0318) +#define CAMIS0 (CARO + 0x0340) +#define CAMIE0 (CARO + 0x0344) +#define CAMID0 (CARO + 0x0348) +#define CAMIS1 (CARO + 0x0350) +#define CAMIE1 (CARO + 0x0354) +#define CAMID1 (CARO + 0x0358) +#define CASCR (CARO + 0x0380) + +/* Ethernet Agent Address space Empty in spec */ +#define EAMC (TARO + 0x0000) +#define EAMS (TARO + 0x0004) +#define EAIRC (TARO + 0x0010) +#define EATDQSC (TARO + 0x0014) +#define EATDQC (TARO + 0x0018) +#define EATDQAC (TARO + 0x001C) +#define EATPEC (TARO + 0x0020) +#define EATMFSC0 (TARO + 0x0040) +#define EATDQDC0 (TARO + 0x0060) +#define EATDQM0 (TARO + 0x0080) +#define EATDQMLM0 (TARO + 0x00A0) +#define EACTQC (TARO + 0x0100) +#define EACTDQDC (TARO + 0x0104) +#define EACTDQM (TARO + 0x0108) +#define EACTDQMLM (TARO + 0x010C) +#define EAVCC (TARO + 0x0130) +#define EAVTC (TARO + 0x0134) +#define EATTFC (TARO + 0x0138) +#define EACAEC (TARO + 0x0200) +#define EACC (TARO + 0x0204) +#define EACAIVC0 (TARO + 0x0220) +#define EACAULC0 (TARO + 0x0240) +#define EACOEM (TARO + 0x0260) +#define EACOIVM0 (TARO + 0x0280) +#define EACOULM0 (TARO + 0x02A0) +#define EACGSM (TARO + 0x02C0) +#define EATASC (TARO + 0x0300) +#define EATASENC0 (TARO + 0x0320) +#define EATASCTENC (TARO + 0x0340) +#define EATASENM0 (TARO + 0x0360) +#define EATASCTENM (TARO + 0x0380) +#define EATASCSTC0 (TARO + 0x03A0) +#define EATASCSTC1 (TARO + 0x03A4) +#define EATASCSTM0 (TARO + 0x03A8) +#define EATASCSTM1 (TARO + 0x03AC) +#define EATASCTC (TARO + 0x03B0) +#define EATASCTM (TARO + 0x03B4) +#define EATASGL0 (TARO + 0x03C0) +#define EATASGL1 (TARO + 0x03C4) +#define EATASGLR (TARO + 0x03C8) +#define EATASGR (TARO + 0x03D0) +#define EATASGRR (TARO + 0x03D4) +#define EATASHCC (TARO + 0x03E0) +#define EATASRIRM (TARO + 0x03E4) +#define EATASSM (TARO + 0x03E8) +#define EAUSMFSECN (TARO + 0x0400) +#define EATFECN (TARO + 0x0404) +#define EAFSECN (TARO + 0x0408) +#define EADQOECN (TARO + 0x040C) +#define EADQSECN (TARO + 0x0410) +#define EACKSECN (TARO + 0x0414) +#define EAEIS0 (TARO + 0x0500) +#define EAEIE0 (TARO + 0x0504) +#define EAEID0 (TARO + 0x0508) +#define EAEIS1 (TARO + 0x0510) +#define EAEIE1 (TARO + 0x0514) +#define EAEID1 (TARO + 0x0518) +#define EAEIS2 (TARO + 0x0520) +#define EAEIE2 (TARO + 0x0524) +#define EAEID2 (TARO + 0x0528) +#define EASCR (TARO + 0x0580) + +#define MPSM (RMRO + 0x0000) +#define MPIC (RMRO + 0x0004) +#define MPIM (RMRO + 0x0008) +#define MIOC (RMRO + 0x0010) +#define MIOM (RMRO + 0x0014) +#define MXMS (RMRO + 0x0018) +#define MTFFC (RMRO + 0x0020) +#define MTPFC (RMRO + 0x0024) +#define MTPFC2 (RMRO + 0x0028) +#define MTPFC30 (RMRO + 0x0030) +#define MTATC0 (RMRO + 0x0050) +#define MTIM (RMRO + 0x0060) +#define MRGC (RMRO + 0x0080) +#define MRMAC0 (RMRO + 0x0084) +#define MRMAC1 (RMRO + 0x0088) +#define MRAFC (RMRO + 0x008C) +#define MRSCE (RMRO + 0x0090) +#define MRSCP (RMRO + 0x0094) +#define MRSCC (RMRO + 0x0098) +#define MRFSCE (RMRO + 0x009C) +#define MRFSCP (RMRO + 0x00a0) +#define MTRC (RMRO + 0x00a4) +#define MRIM (RMRO + 0x00a8) +#define MRPFM (RMRO + 0x00aC) +#define MPFC0 (RMRO + 0x0100) +#define MLVC (RMRO + 0x0180) +#define MEEEC (RMRO + 0x0184) +#define MLBC (RMRO + 0x0188) +#define MXGMIIC (RMRO + 0x0190) +#define MPCH (RMRO + 0x0194) +#define MANC (RMRO + 0x0198) +#define MANM (RMRO + 0x019C) +#define MPLCA1 (RMRO + 0x01a0) +#define MPLCA2 (RMRO + 0x01a4) +#define MPLCA3 (RMRO + 0x01a8) +#define MPLCA4 (RMRO + 0x01ac) +#define MPLCAM (RMRO + 0x01b0) +#define MHDC1 (RMRO + 0x01c0) +#define MHDC2 (RMRO + 0x01c4) +#define MEIS (RMRO + 0x0200) +#define MEIE (RMRO + 0x0204) +#define MEID (RMRO + 0x0208) +#define MMIS0 (RMRO + 0x0210) +#define MMIE0 (RMRO + 0x0214) +#define MMID0 (RMRO + 0x0218) +#define MMIS1 (RMRO + 0x0220) +#define MMIE1 (RMRO + 0x0224) +#define MMID1 (RMRO + 0x0228) +#define MMIS2 (RMRO + 0x0230) +#define MMIE2 (RMRO + 0x0234) +#define MMID2 (RMRO + 0x0238) +#define MMPFTCT (RMRO + 0x0300) +#define MAPFTCT (RMRO + 0x0304) +#define MPFRCT (RMRO + 0x0308) +#define MFCICT (RMRO + 0x030c) +#define MEEECT (RMRO + 0x0310) +#define MMPCFTCT0 (RMRO + 0x0320) +#define MAPCFTCT0 (RMRO + 0x0330) +#define MPCFRCT0 (RMRO + 0x0340) +#define MHDCC (RMRO + 0x0350) +#define MROVFC (RMRO + 0x0354) +#define MRHCRCEC (RMRO + 0x0358) +#define MRXBCE (RMRO + 0x0400) +#define MRXBCP (RMRO + 0x0404) +#define MRGFCE (RMRO + 0x0408) +#define MRGFCP (RMRO + 0x040C) +#define MRBFC (RMRO + 0x0410) +#define MRMFC (RMRO + 0x0414) +#define MRUFC (RMRO + 0x0418) +#define MRPEFC (RMRO + 0x041C) +#define MRNEFC (RMRO + 0x0420) +#define MRFMEFC (RMRO + 0x0424) +#define MRFFMEFC (RMRO + 0x0428) +#define MRCFCEFC (RMRO + 0x042C) +#define MRFCEFC (RMRO + 0x0430) +#define MRRCFEFC (RMRO + 0x0434) +#define MRUEFC (RMRO + 0x043C) +#define MROEFC (RMRO + 0x0440) +#define MRBOEC (RMRO + 0x0444) +#define MTXBCE (RMRO + 0x0500) +#define MTXBCP (RMRO + 0x0504) +#define MTGFCE (RMRO + 0x0508) +#define MTGFCP (RMRO + 0x050C) +#define MTBFC (RMRO + 0x0510) +#define MTMFC (RMRO + 0x0514) +#define MTUFC (RMRO + 0x0518) +#define MTEFC (RMRO + 0x051C) + +#define GWMC (GWRO + 0x0000) +#define GWMS (GWRO + 0x0004) +#define GWIRC (GWRO + 0x0010) +#define GWRDQSC (GWRO + 0x0014) +#define GWRDQC (GWRO + 0x0018) +#define GWRDQAC (GWRO + 0x001C) +#define GWRGC (GWRO + 0x0020) +#define GWRMFSC0 (GWRO + 0x0040) +#define GWRDQDC0 (GWRO + 0x0060) +#define GWRDQM0 (GWRO + 0x0080) +#define GWRDQMLM0 (GWRO + 0x00A0) +#define GWMTIRM (GWRO + 0x0100) +#define GWMSTLS (GWRO + 0x0104) +#define GWMSTLR (GWRO + 0x0108) +#define GWMSTSS (GWRO + 0x010C) +#define GWMSTSR (GWRO + 0x0110) +#define GWMAC0 (GWRO + 0x0120) +#define GWMAC1 (GWRO + 0x0124) +#define GWVCC (GWRO + 0x0130) +#define GWVTC (GWRO + 0x0134) +#define GWTTFC (GWRO + 0x0138) +#define GWTDCAC00 (GWRO + 0x0140) +#define GWTDCAC10 (GWRO + 0x0144) +#define GWTSDCC0 (GWRO + 0x0160) +#define GWTNM (GWRO + 0x0180) +#define GWTMNM (GWRO + 0x0184) +#define GWAC (GWRO + 0x0190) +#define GWDCBAC0 (GWRO + 0x0194) +#define GWDCBAC1 (GWRO + 0x0198) +#define GWIICBSC (GWRO + 0x019C) +#define GWMDNC (GWRO + 0x01A0) +#define GWTRC0 (GWRO + 0x0200) +#define GWTPC0 (GWRO + 0x0300) +#define GWARIRM (GWRO + 0x0380) +#define GWDCC0 (GWRO + 0x0400) +#define GWAARSS (GWRO + 0x0800) +#define GWAARSR0 (GWRO + 0x0804) +#define GWAARSR1 (GWRO + 0x0808) +#define GWIDAUAS0 (GWRO + 0x0840) +#define GWIDASM0 (GWRO + 0x0880) +#define GWIDASAM00 (GWRO + 0x0900) +#define GWIDASAM10 (GWRO + 0x0904) +#define GWIDACAM00 (GWRO + 0x0980) +#define GWIDACAM10 (GWRO + 0x0984) +#define GWGRLC (GWRO + 0x0A00) +#define GWGRLULC (GWRO + 0x0A04) +#define GWRLIVC0 (GWRO + 0x0A80) +#define GWRLULC0 (GWRO + 0x0A84) +#define GWIDPC (GWRO + 0x0B00) +#define GWIDC0 (GWRO + 0x0C00) +#define GWDIS0 (GWRO + 0x1100) +#define GWDIE0 (GWRO + 0x1104) +#define GWDID0 (GWRO + 0x1108) +#define GWTSDIS (GWRO + 0x1180) +#define GWTSDIE (GWRO + 0x1184) +#define GWTSDID (GWRO + 0x1188) +#define GWEIS0 (GWRO + 0x1190) +#define GWEIE0 (GWRO + 0x1194) +#define GWEID0 (GWRO + 0x1198) +#define GWEIS1 (GWRO + 0x11A0) +#define GWEIE1 (GWRO + 0x11A4) +#define GWEID1 (GWRO + 0x11A8) +#define GWEIS20 (GWRO + 0x1200) +#define GWEIE20 (GWRO + 0x1204) +#define GWEID20 (GWRO + 0x1208) +#define GWEIS3 (GWRO + 0x1280) +#define GWEIE3 (GWRO + 0x1284) +#define GWEID3 (GWRO + 0x1288) +#define GWEIS4 (GWRO + 0x1290) +#define GWEIE4 (GWRO + 0x1294) +#define GWEID4 (GWRO + 0x1298) +#define GWEIS5 (GWRO + 0x12A0) +#define GWEIE5 (GWRO + 0x12A4) +#define GWEID5 (GWRO + 0x12A8) +#define GWSCR0 (GWRO + 0x1800) +#define GWSCR1 (GWRO + 0x1900) + +/* COMA */ +#define RRC_RR BIT(0) +#define RRC_RR_CLR (0) +#define RCEC_RCE BIT(16) +#define RCDC_RCD BIT(16) + +#define CABPIRM_BPIOG BIT(0) +#define CABPIRM_BPR BIT(1) + +#endif /* RSWITCH_REGS_H */ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.c b/examples/cortex-a-r/armv8/spider/ethernet/utils.c index 7b0abd572..3f6b23f34 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.c @@ -1,5 +1,6 @@ #include "tpl_os.h" #include "utils.h" +#include "pfcmap.h" #define ETH_CPUCLK_MHZ 1066UL #define ETH_WAIT_NS(t) \ @@ -60,6 +61,16 @@ void rswitch_enable_clock_and_reset(void) ETH_WAIT_NS(40*1000); } +uint32 reg_read32(uint32 addr) +{ + return *((volatile uint32*)addr); +} + +void reg_write32(uint32 data, uint32 addr) +{ + *((volatile uint32*)addr) = data; +} + extern volatile VAR(uint32, OS_VAR) tpl_time_counter; uint32 get_time(void) { @@ -71,6 +82,13 @@ uint32 get_elapsed_time(uint32 start_val) return (tpl_time_counter - start_val); } +void ms_delay(uint32 value) +{ + uint32 start_time = get_time(); + + while((get_elapsed_time(start_time) - start_time) < value); +} + void port_init(void) { uint32 dataL; @@ -116,3 +134,10 @@ void port_init(void) *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; *((volatile uint32 *)(PFC_POC_GPn_DM0(3))) = dataL; } + +#define GICD_ISENABLER (0xf0000100) + +void enable_int(uint32 num) +{ + *((volatile uint32 *)(GICD_ISENABLER + 4 * (num / 32))) = 1 << (num % 32); +} \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.h b/examples/cortex-a-r/armv8/spider/ethernet/utils.h index cfadb3018..4ddd9b039 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.h @@ -3,11 +3,34 @@ #include "tpl_os.h" +#define debug_msg(...) do {} while(0) // TODO + #define BIT(x) (1UL << x) +#define BITS_PER_TYPE(x) (sizeof(x) * 8) +#define BITS_PER_LONG (BITS_PER_TYPE(unsigned long)) + +#define GENMASK(h, l) \ + (((~(0UL)) - ((1UL) << (l)) + 1) & \ + (~(0UL) >> (BITS_PER_LONG - 1 - (h)))) + +#define __unused __attribute__((unused)) + +#define CHECK_RET(f) \ + ret = (f); \ + if (ret != 0) { \ + return ret; \ + } + +uint32 reg_read32(uint32 addr); +void reg_write32(uint32 data, uint32 addr); void rswitch_enable_clock_and_reset(void); void port_init(void); + +void enable_int(uint32 irq); + uint32 get_time(void); uint32 get_elapsed_time(uint32 start_val); +void ms_delay(uint32 value); #endif /* _UTILS_H_ */ \ No newline at end of file From 291a1b1e539e3af294d609ee072d4513a8959b81 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 28 Jun 2023 12:30:23 +0200 Subject: [PATCH 07/24] rswitch_regs: use secure APB accesses instead of the normal one Signed-off-by: Valerio Setti --- examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h b/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h index 20646df12..d740438ce 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h @@ -1,7 +1,7 @@ #ifndef RSWITCH_REGS_H #define RSWITCH_REGS_H -#define RSWITCH_BASE 0xE6880000 +#define RSWITCH_BASE 0xE68C0000 #define RSWITCH_FWD_ADDR (RSWITCH_BASE + 0x00000000) #define RSWITCH_FAB_ADDR (RSWITCH_BASE + 0x00008000) From 6cc46b20b6b72a25a86569cb1da6956fcbeef433 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 3 Jul 2023 17:56:19 +0200 Subject: [PATCH 08/24] phy: fix MII access Signed-off-by: Valerio Setti --- .../cortex-a-r/armv8/spider/ethernet/rswitch.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c index c653266da..64e944aa8 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c @@ -779,31 +779,31 @@ static int rswitch_phy_init(struct rswitch_etha *etha) int ret; /* Reset */ - CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0xC04A, ®_data)); + CHECK_RET(rswitch_mii_read(etha, 1, etha->port_num + 1, 0xC04A, ®_data)); reg_data |= BIT(15); - CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0xC04A, ®_data)); - CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0xC04A, ®_data)); /* MCAL does it twice... */ + CHECK_RET(rswitch_mii_write(etha, 1, etha->port_num + 1, 0xC04A, ®_data)); + CHECK_RET(rswitch_mii_write(etha, 1, etha->port_num + 1, 0xC04A, ®_data)); /* MCAL does it twice... */ /* Check mode */ - CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0xC04A, ®_data)); + CHECK_RET(rswitch_mii_read(etha, 1, etha->port_num + 1, 0xC04A, ®_data)); if ((reg_data & 0x7) != 0x4 ) { /* 4 stands for SGMII */ reg_data &= ~0x7; reg_data |= BIT(15) | 0x4; - CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0xC04A, ®_data)); + CHECK_RET(rswitch_mii_write(etha, 1, etha->port_num + 1, 0xC04A, ®_data)); /* Run SERDES Init */ - CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0x800F, ®_data)); + CHECK_RET(rswitch_mii_read(etha, 1, etha->port_num + 1, 0x800F, ®_data)); reg_data |= BIT(15) | BIT(13); - CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0x800F, ®_data)); + CHECK_RET(rswitch_mii_write(etha, 1, etha->port_num + 1, 0x800F, ®_data)); reg_data = 0x0U; do { - CHECK_RET(rswitch_mii_read(etha, etha->port_num, 1, 0x800F, ®_data)); + CHECK_RET(rswitch_mii_read(etha, 1, etha->port_num + 1, 0x800F, ®_data)); } while (reg_data & BIT(15)); /* Auto SERDES Init Disable */ reg_data &= ~BIT(13); - CHECK_RET(rswitch_mii_write(etha, etha->port_num, 1, 0x800F, ®_data)); + CHECK_RET(rswitch_mii_write(etha, 1, etha->port_num + 1, 0x800F, ®_data)); } return 0; From 683e5e70329f76d39d94dd4619e2466a33f7aa48 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 4 Jul 2023 10:19:04 +0200 Subject: [PATCH 09/24] debug: add printf capability Signed-off-by: Valerio Setti --- .../cortex-a-r/armv8/spider/ethernet/eth.oil | 4 +- .../cortex-a-r/armv8/spider/ethernet/main.c | 15 +- .../cortex-a-r/armv8/spider/ethernet/printf.c | 188 ++++++++++++++++++ .../cortex-a-r/armv8/spider/ethernet/printf.h | 4 + .../cortex-a-r/armv8/spider/ethernet/utils.h | 7 +- 5 files changed, 213 insertions(+), 5 deletions(-) create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/printf.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/printf.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil index 28d557a07..affd669a3 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil @@ -21,8 +21,9 @@ CPU eth { APP_SRC = "eth_serdes.c"; APP_SRC = "rswitch.c"; APP_SRC = "eth_gptp.c"; + APP_SRC = "printf.c"; APP_NAME = "eth_exe.elf"; - CFLAGS = "-O0"; + CFLAGS = "-O0 -g -DHSCIF_1843200BPS"; LDFLAGS = "-Map=eth_exe.map"; COMPILER = "arm-none-eabi-gcc"; CPPCOMPILER = "arm-none-eabi-g++"; @@ -30,6 +31,7 @@ CPU eth { LINKER = "arm-none-eabi-ld"; COPIER = "arm-none-eabi-objcopy"; SYSTEM = PYTHON; + LIBRARY = serial; }; SYSTEM_CALL = TRUE; MEMMAP = TRUE { diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c index f87c247b8..2ffba1320 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/main.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -3,12 +3,11 @@ #include "eth_serdes.h" #include "rswitch.h" #include "eth_gptp.h" +#include "serial.h" #define APP_Task_sample_init_START_SEC_CODE #include "tpl_memmap.h" -extern volatile VAR(uint32, OS_VAR) tpl_time_counter; - // Is this the right section for the main function?? FUNC(int, OS_APPL_CODE) main(void) { @@ -19,31 +18,41 @@ FUNC(int, OS_APPL_CODE) main(void) TASK(sample_init) { int ret; + Serial_Init(); + rswitch_enable_clock_and_reset(); port_init(); // Interrupt initializazion done by Trampoline eth_disable_fuse_ovr(); + debug_msg("Initialize SERDES"); ret = eth_serdes_initialize(); if (ret != 0) { - debug_msg("Error in eth_serdes_initialize\n"); + debug_msg("Error in eth_serdes_initialize"); goto exit; } + debug_msg("SERDES initialization done"); + debug_msg("Initialize RSwitch"); ret = rswitch_init(); if (ret != 0) { debug_msg("Error in rswitch_init\n"); goto exit; } + debug_msg("RSwitch initialization done"); + debug_msg("Initialize gPTP"); eth_gptp_init(); + debug_msg("RSwitch open"); ret = rswitch_open(); if (ret != 0) { debug_msg("Error in rswitch_open\n"); goto exit; } + debug_msg("RSwitch completed"); + debug_msg("Initialization completed"); exit: TerminateTask(); } diff --git a/examples/cortex-a-r/armv8/spider/ethernet/printf.c b/examples/cortex-a-r/armv8/spider/ethernet/printf.c new file mode 100644 index 000000000..a53e9a866 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/printf.c @@ -0,0 +1,188 @@ +/* + Copyright 2001-2021 Georges Menie + https://www.menie.org/georges/embedded/small_printf_source_code.html + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "printf.h" +#include "serial.h" + +static void printchar(char **str, int c) +{ + if (str) { + **str = c; + ++(*str); + } else { + Serial_Tx(c); + } +} + +#define PAD_RIGHT 1 +#define PAD_ZERO 2 + +static int prints(char **out, const char *string, int width, int pad) +{ + register int pc = 0, padchar = ' '; + + if (width > 0) { + register int len = 0; + register const char *ptr; + for (ptr = string; *ptr; ++ptr) ++len; + if (len >= width) width = 0; + else width -= len; + if (pad & PAD_ZERO) padchar = '0'; + } + if (!(pad & PAD_RIGHT)) { + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + } + for ( ; *string ; ++string) { + printchar (out, *string); + ++pc; + } + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + + return pc; +} + +/* the following should be enough for 32 bit int */ +#define PRINT_BUF_LEN 12 + +static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase) +{ + char print_buf[PRINT_BUF_LEN]; + register char *s; + register int t, neg = 0, pc = 0; + register unsigned int u = i; + + if (i == 0) { + print_buf[0] = '0'; + print_buf[1] = '\0'; + return prints (out, print_buf, width, pad); + } + + if (sg && b == 10 && i < 0) { + neg = 1; + u = -i; + } + + s = print_buf + PRINT_BUF_LEN-1; + *s = '\0'; + + while (u) { + t = u % b; + if( t >= 10 ) + t += letbase - '0' - 10; + *--s = t + '0'; + u /= b; + } + + if (neg) { + if( width && (pad & PAD_ZERO) ) { + printchar (out, '-'); + ++pc; + --width; + } + else { + *--s = '-'; + } + } + + return pc + prints (out, s, width, pad); +} + +static int print(char **out, int *varg) +{ + register int width, pad; + register int pc = 0; + register char *format = (char *)(*varg++); + char scr[2]; + + for (; *format != 0; ++format) { + if (*format == '%') { + ++format; + width = pad = 0; + if (*format == '\0') break; + if (*format == '%') goto out; + if (*format == '-') { + ++format; + pad = PAD_RIGHT; + } + while (*format == '0') { + ++format; + pad |= PAD_ZERO; + } + for ( ; *format >= '0' && *format <= '9'; ++format) { + width *= 10; + width += *format - '0'; + } + if( *format == 's' ) { + register char *s = *((char **)varg++); + pc += prints (out, s?s:"(null)", width, pad); + continue; + } + if( *format == 'd' ) { + pc += printi (out, *varg++, 10, 1, width, pad, 'a'); + continue; + } + if( *format == 'x' ) { + pc += printi (out, *varg++, 16, 0, width, pad, 'a'); + continue; + } + if( *format == 'X' ) { + pc += printi (out, *varg++, 16, 0, width, pad, 'A'); + continue; + } + if( *format == 'u' ) { + pc += printi (out, *varg++, 10, 0, width, pad, 'a'); + continue; + } + if( *format == 'c' ) { + /* char are converted to int then pushed on the stack */ + scr[0] = *varg++; + scr[1] = '\0'; + pc += prints (out, scr, width, pad); + continue; + } + } + else { + out: + printchar (out, *format); + ++pc; + } + } + if (out) **out = '\0'; + return pc; +} + +/* assuming sizeof(void *) == sizeof(int) */ + +int debug_printf(const char *format, ...) +{ + register int *varg = (int *)(&format); + return print(0, varg); +} + +int debug_sprintf(char *out, const char *format, ...) +{ + register int *varg = (int *)(&format); + return print(&out, varg); +} \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/printf.h b/examples/cortex-a-r/armv8/spider/ethernet/printf.h new file mode 100644 index 000000000..c1ad80b9f --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/printf.h @@ -0,0 +1,4 @@ +#include "tpl_os.h" + +int debug_printf(const char *format, ...); +int debug_sprintf(char *out, const char *format, ...); \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.h b/examples/cortex-a-r/armv8/spider/ethernet/utils.h index 4ddd9b039..e6850119a 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.h @@ -2,8 +2,13 @@ #define _UTILS_H_ #include "tpl_os.h" +#include "printf.h" -#define debug_msg(...) do {} while(0) // TODO +#define debug_msg(...) \ + do { \ + debug_printf(__VA_ARGS__); \ + debug_printf("\n\r"); \ + } while(0) #define BIT(x) (1UL << x) #define BITS_PER_TYPE(x) (sizeof(x) * 8) From 7ef5dfa42a5a5fd45a8922815ae26b53d47a75a3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 4 Jul 2023 11:42:52 +0200 Subject: [PATCH 10/24] eth: fixes for bringup Signed-off-by: Valerio Setti --- .../armv8/spider/ethernet/rswitch.c | 89 ++++++++----------- 1 file changed, 37 insertions(+), 52 deletions(-) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c index 64e944aa8..40a364b50 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c @@ -19,7 +19,7 @@ #define GWCA1_PORT_NUM 4 #define TSN_PORT_IN_USE TSNA0_PORT_NUM -#define GWCA_PORT_IN_USE GWCA1_PORT_NUM +#define GWCA_PORT_IN_USE (GWCA1_PORT_NUM - PORT_TSNA_N) /* GWCA */ enum rswitch_gwca_mode { @@ -263,7 +263,7 @@ struct rswitch_device { #define ETHA1_ERR_IRQ 294 #define ETHA2_ERR_IRQ 295 -#define RSWITCH_TIMEOUT_MS 1000 +#define RSWITCH_TIMEOUT_MS 10000 static int rswitch_reg_wait(uint32 addr, uint32 mask, uint32 expected) { int i; @@ -365,13 +365,13 @@ static void rswitch_agent_clock_ctrl(int port, int enable) reg_write32(val | RCEC_RCE | BIT(port), rsw_dev.coma_base_addr + RCEC); } else { - val = reg_read32(RCDC); - reg_write32(val | BIT(port), RCDC); + val = reg_read32(rsw_dev.coma_base_addr + RCDC); + reg_write32(val | BIT(port), rsw_dev.coma_base_addr + RCDC); } } -// mac is supposed to be an array of 6 bytes -static void rswitch_etha_read_mac_address(struct rswitch_etha *eth_dev) +/* mac is supposed to be an array of 6 bytes */ +static void __unused rswitch_etha_read_mac_address(struct rswitch_etha *eth_dev) { uint32 mrmac0 = reg_read32(eth_dev->base_addr + MRMAC0); uint32 mrmac1 = reg_read32(eth_dev->base_addr + MRMAC1); @@ -385,9 +385,10 @@ static void rswitch_etha_read_mac_address(struct rswitch_etha *eth_dev) } /* This function sets only data in the global strucure, not on the hardware */ -static void rswitch_set_mac_address(struct rswitch_etha *eth_dev) +static void rswitch_etha_set_mac_address(struct rswitch_etha *eth_dev) { int i; + uint32 tmp = 0; // Values from MCAL static const uint8 predefined_mac_address[PORT_TSNA_N][6] = { @@ -396,18 +397,17 @@ static void rswitch_set_mac_address(struct rswitch_etha *eth_dev) {0x74U, 0x90U, 0x50U, 0x00U, 0x00U, 0x02U}, }; - // Set only if not already valid (at least 1 value != 0) - for (i = 0; i < MAC_ADDRESS_LEN; i++) { - if (eth_dev->mac_addr[i] != 0) { - return; - } - } - /* The following works only because TSN port's numbers starts from 0 as * if they were indexes. */ for (i = 0; i < MAC_ADDRESS_LEN; i++) { eth_dev->mac_addr[i] = predefined_mac_address[eth_dev->port_num][i]; } + + tmp = (eth_dev->mac_addr[0] << 8) + (eth_dev->mac_addr[1]); + reg_write32(tmp, eth_dev->base_addr + MRMAC0); + tmp = (eth_dev->mac_addr[2] << 24) + (eth_dev->mac_addr[3] << 16) + + (eth_dev->mac_addr[4] << 8) + (eth_dev->mac_addr[5]); + reg_write32(tmp, eth_dev->base_addr + MRMAC1); } static void rswitch_soft_reset(void) @@ -472,13 +472,10 @@ static void rswitch_gwca_set_rate_limit(struct rswitch_gwca *gwca) static int rswitch_gwca_hw_init(struct rswitch_device *rswitch) { int ret, i; - uint64 descriptors_addr = (uint32) rswitch->base_descriptors; + uint32 descriptors_addr = (uint32) rswitch->base_descriptors; struct rswitch_gwca *gwca = rswitch->gwca; - /* Note: this is setting the base descriptors for all the devices but - * perhaps we should just set the one we are using. Setting for all - * might impact what Linux/Uboot has already configured on its side. */ - for (i = 0; i < NUM_CHAINS_PER_NDEV * NUM_DEVICES; i++) { + for (i = 0; i < NUM_CHAINS_PER_NDEV; i++) { rswitch->base_descriptors[i].die_dt = DT_EOS; } @@ -490,8 +487,8 @@ static int rswitch_gwca_hw_init(struct rswitch_device *rswitch) /* Full setting flow */ reg_write32(GWVCC_VEM_SC_TAG, gwca->base_addr + GWVCC); reg_write32(0, gwca->base_addr + GWTTFC); - reg_write32(0x00, gwca->base_addr + GWDCBAC1); - reg_write32((descriptors_addr >> 32) & 0xFFFFFFFF, gwca->base_addr + GWDCBAC0); + reg_write32(descriptors_addr, gwca->base_addr + GWDCBAC1); + reg_write32(0x00, gwca->base_addr + GWDCBAC0); gwca->speed = 1000; rswitch_gwca_set_rate_limit(gwca); @@ -507,11 +504,11 @@ static void rswitch_gwca_chain_format(struct rswitch_device *rswitch, { struct rswitch_ext_desc *ring; struct rswitch_desc *base_desc; - int tx_ring_size = sizeof(*ring) * c->num_ring; + int ring_size = sizeof(*ring) * c->num_ring; int i; - memset(c->ring, 0, tx_ring_size); - for (i = 0, ring = c->ring; i < c->num_ring; i++, ring++) { + memset(c->ring, 0, ring_size); + for (i = 0, ring = c->ring; i < c->num_ring - 1; i++, ring++) { if (!c->dir_tx) { ring->info_ds = PKT_BUF_SZ; ring->dptrl = (uint32) c->data_buffers[i]; @@ -538,16 +535,16 @@ static void rswitch_gwca_chain_format(struct rswitch_device *rswitch, rswitch->gwca->base_addr + GWDCC_OFFS(c->chain_index)); } -static __unused void rswitch_gwca_chain_ts_format(struct rswitch_device *rswitch, +static void rswitch_gwca_chain_ts_format(struct rswitch_device *rswitch, struct rswitch_gwca_chain *c) { struct rswitch_ext_ts_desc *ring; struct rswitch_desc *base_desc; - int tx_ring_size = sizeof(*ring) * c->num_ring; + int ring_size = sizeof(*ring) * c->num_ring; int i; - memset(c->ring, 0, tx_ring_size); - for (i = 0, ring = c->ts_ring; i < c->num_ring; i++, ring++) { + memset(c->ring, 0, ring_size); + for (i = 0, ring = c->ts_ring; i < c->num_ring - 1; i++, ring++) { if (!c->dir_tx) { ring->info_ds = PKT_BUF_SZ; ring->dptrl = (uint32) c->data_buffers[i]; @@ -559,14 +556,14 @@ static __unused void rswitch_gwca_chain_ts_format(struct rswitch_device *rswitch } /* Close the loop */ - ring->dptrl = (uint32) c->ring; + ring->dptrl = (uint32) c->ts_ring; ring->dptrh = 0x00; ring->die_dt = DT_LINKFIX; /* Configure the base descriptor */ base_desc = &rswitch->base_descriptors[c->chain_index]; base_desc->die_dt = DT_LINKFIX; - base_desc->dptrl = (uint32) c->ring; + base_desc->dptrl = (uint32) c->ts_ring; base_desc->dptrh = 0x00; /* FIXME: GWDCC_DCP */ @@ -588,29 +585,20 @@ static int rswitch_bpool_config(struct rswitch_device *rswitch) static void rswitch_fwd_init(struct rswitch_device *rswitch) { - int i; int eth_port_num = rswitch->etha->port_num; int gwca_port_num = rswitch->gwca->port_num; int gwca_idx = RSWITCH_HW_NUM_TO_GWCA_IDX(gwca_port_num); - /* Note: this configures FWD for all the ports, but this might conflict - * with previous configurations... */ - for (i = 0; i < TOT_PORT_NUM; i++) { - reg_write32(FWPC0_DEFAULT, rswitch->fwd_base_addr + FWPC0(i)); - reg_write32(0, rswitch->fwd_base_addr + FWPBFC(i)); - } - - /* Static routing between the specified ETHA and GWCA ports. */ + /* Set RX chain as destination for port based forwarding from the selected + * ethernet port. */ reg_write32(rswitch->gwca->rx_chain.chain_index, rswitch->fwd_base_addr + FWPBFCSDC(gwca_idx, eth_port_num)); + /* Static routing ETHA --> GWCA. */ reg_write32(BIT(rswitch->gwca->port_num), rswitch->fwd_base_addr + FWPBFC(eth_port_num)); - - /* For GWCA */ - reg_write32(FWPC0_DEFAULT, rswitch->fwd_base_addr + FWPC0(gwca_port_num)); - reg_write32(FWPC1_DDE, rswitch->fwd_base_addr + FWPC1(gwca_port_num)); + /* Static routing GWCA --> ETHA. */ reg_write32(0, rswitch->fwd_base_addr + FWPBFC(gwca_port_num)); - reg_write32(eth_port_num, rswitch->fwd_base_addr + FWPBFC(gwca_port_num)); + reg_write32(BIT(eth_port_num), rswitch->fwd_base_addr + FWPBFC(gwca_port_num)); } static __unused void rswitch_get_data_irq_status(struct rswitch_device *rswitch, uint32 *dis) @@ -649,17 +637,14 @@ int rswitch_init(void) { int i, ret; + memset(rx_data_buff, 0, sizeof(rx_data_buff)); + memset(tx_data_buff, 0, sizeof(tx_data_buff)); + // Enable clocks to all the agents for (i = 0; i < TOT_PORT_NUM; i++) { rswitch_agent_clock_ctrl(i, 1); } - /* Read MAC addresses (since it's only reading it does not affect other - * ports that we are not using) */ - for (i = 0; i < NUM_DEVICES; i++) { - rswitch_etha_read_mac_address(ða_props[i]); - } - rswitch_soft_reset(); CHECK_RET(rswitch_gwca_hw_init(&rsw_dev)); @@ -667,8 +652,6 @@ int rswitch_init(void) /* Copy speed property from GWCA */ rsw_dev.etha->speed = rsw_dev.gwca->speed; - rswitch_set_mac_address(rsw_dev.etha); - rsw_dev.gwca->rx_chain.chain_index = 0; rsw_dev.gwca->rx_chain.ts_ring = rx_ring; for (i = 0; i < TX_RX_RING_SIZE; i++) { @@ -761,6 +744,8 @@ static int rswitch_etha_hw_init(struct rswitch_etha *etha) CHECK_RET(rswitch_etha_change_mode(etha, EAMC_OPC_DISABLE)); CHECK_RET(rswitch_etha_change_mode(etha, EAMC_OPC_CONFIG)); + rswitch_etha_set_mac_address(etha); + reg_write32(EAVCC_VEM_SC_TAG, etha->base_addr + EAVCC); rswitch_rmac_setting(etha); From 86edffd7cac3b05a03261fe82927a1357c405ced Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 12 Jul 2023 14:41:28 +0200 Subject: [PATCH 11/24] debug: add function to print raw buffer Signed-off-by: Valerio Setti --- examples/cortex-a-r/armv8/spider/ethernet/utils.c | 13 +++++++++++++ examples/cortex-a-r/armv8/spider/ethernet/utils.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.c b/examples/cortex-a-r/armv8/spider/ethernet/utils.c index 3f6b23f34..f24539070 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.c @@ -140,4 +140,17 @@ void port_init(void) void enable_int(uint32 num) { *((volatile uint32 *)(GICD_ISENABLER + 4 * (num / 32))) = 1 << (num % 32); +} + +void debug_print_buffer(uint8 *buf, uint32 len) +{ + uint32 i = 0; + + for (i = 0; i < len; i++) { + if ((i != 0) && ((i % 16) == 0)) { + debug_printf("\n\r"); + } + debug_printf("%02x ", buf[i]); + } + debug_printf("\n\r"); } \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.h b/examples/cortex-a-r/armv8/spider/ethernet/utils.h index e6850119a..4eedbf8b3 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.h @@ -38,4 +38,6 @@ uint32 get_time(void); uint32 get_elapsed_time(uint32 start_val); void ms_delay(uint32 value); +void debug_print_buffer(uint8 *buf, uint32 len); + #endif /* _UTILS_H_ */ \ No newline at end of file From ee3e7bcdd6d32c9dfb52967779e78bcb60de6924 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 12 Jul 2023 14:41:58 +0200 Subject: [PATCH 12/24] rswitch: properly manage RX interrupt Signed-off-by: Valerio Setti --- .../cortex-a-r/armv8/spider/ethernet/eth.oil | 8 +- .../cortex-a-r/armv8/spider/ethernet/main.c | 100 --------- .../armv8/spider/ethernet/rswitch.c | 191 +++++++++++++++++- 3 files changed, 189 insertions(+), 110 deletions(-) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil index affd669a3..166eb6250 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil @@ -59,25 +59,25 @@ CPU eth { ISR gwca1_rx_ts_int { CATEGORY = 2; - PRIORITY = 1; + PRIORITY = 2; SOURCE = GWCA1_RX_TS_INT; }; ISR coma_err_int { CATEGORY = 2; - PRIORITY = 1; + PRIORITY = 3; SOURCE = COMA_ERR_INT; }; ISR gwca1_err_int { CATEGORY = 2; - PRIORITY = 1; + PRIORITY = 4; SOURCE = GWCA1_ERR_INT; }; ISR etha0_err_int { CATEGORY = 2; - PRIORITY = 1; + PRIORITY = 5; SOURCE = ETHA0_ERR_INT; }; }; diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c index 2ffba1320..047058b7a 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/main.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -58,104 +58,4 @@ TASK(sample_init) { } #define APP_Task_sample_init_STOP_SEC_CODE -#include "tpl_memmap.h" - -/*****************************************************************************/ -/*****************************************************************************/ - -#define APP_ISR_gwca1_rx_tx_int_START_SEC_CODE -#include "tpl_memmap.h" - -ISR(gwca1_rx_tx_int) -{ - debug_msg("gwca1_rx_tx_int"); - //CallTerminateISR2(); -} - -FUNC(void, OS_CODE) GWCA1_RX_TX_INT_ClearFlag(void) -{ - -} - -#define APP_ISR_gwca1_rx_tx_int_STOP_SEC_CODE -#include "tpl_memmap.h" - -/*****************************************************************************/ -/*****************************************************************************/ - -#define APP_ISR_gwca1_rx_ts_int_START_SEC_CODE -#include "tpl_memmap.h" - -ISR(gwca1_rx_ts_int) -{ - debug_msg("gwca1_rx_ts_int"); - //CallTerminateISR2(); -} - -FUNC(void, OS_CODE) GWCA1_RX_TS_INT_ClearFlag(void) -{ - -} - -#define APP_ISR_gwca1_rx_ts_int_STOP_SEC_CODE -#include "tpl_memmap.h" - -/*****************************************************************************/ -/*****************************************************************************/ - -#define APP_ISR_coma_err_int_START_SEC_CODE -#include "tpl_memmap.h" - -ISR(coma_err_int) -{ - debug_msg("coma_err_int"); - //CallTerminateISR2(); -} - -FUNC(void, OS_CODE) COMA_ERR_INT_ClearFlag(void) -{ - -} - -#define APP_ISR_coma_err_int_STOP_SEC_CODE -#include "tpl_memmap.h" - -/*****************************************************************************/ -/*****************************************************************************/ - -#define APP_ISR_gwca1_err_int_START_SEC_CODE -#include "tpl_memmap.h" - -ISR(gwca1_err_int) -{ - debug_msg("gwca1_err_int"); - //CallTerminateISR2(); -} - -FUNC(void, OS_CODE) GWCA1_ERR_INT_ClearFlag(void) -{ - -} - -#define APP_ISR_gwca1_err_int_STOP_SEC_CODE -#include "tpl_memmap.h" - -/*****************************************************************************/ -/*****************************************************************************/ - -#define APP_ISR_etha0_err_int_START_SEC_CODE -#include "tpl_memmap.h" - -ISR(etha0_err_int) -{ - debug_msg("etha0_err_int"); - //CallTerminateISR2(); -} - -FUNC(void, OS_CODE) ETHA0_ERR_INT_ClearFlag(void) -{ - -} - -#define APP_ISR_etha0_err_int_STOP_SEC_CODE #include "tpl_memmap.h" \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c index 40a364b50..d44ac123e 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c @@ -197,9 +197,9 @@ struct rswitch_gwca_chain { struct rswitch_ext_ts_desc *ts_ring; }; uint32 num_ring; - uint32 cur; - uint32 dirty; + uint32 next_index; // next descriptor (as index) to be processed uint8 *data_buffers[TX_RX_RING_SIZE]; + uint8 irq_triggered; }; struct rswitch_gwca { @@ -207,7 +207,6 @@ struct rswitch_gwca { uint32 base_addr; struct rswitch_gwca_chain rx_chain; struct rswitch_gwca_chain tx_chain; - uint32 irq_queue; int speed; } gwca_props[PORT_GWCA_N] = { { .port_num = GWCA0_PORT_NUM, .base_addr = RSWITCH_GWCA0_ADDR }, @@ -263,6 +262,14 @@ struct rswitch_device { #define ETHA1_ERR_IRQ 294 #define ETHA2_ERR_IRQ 295 +/* GWCA data interrupt status */ +#define GWDIS0i_OFFSET(index) (GWDIS0 + (index/32) * 0x10) +#define GWDIS0i_BIT(index) (BIT(index % 32)) + +/* Well, this shouldn't be here as it should be included from "tpl_os.h", but + * that doesn't work, so we will redeclare it here... */ +extern FUNC(void, OS_CODE) CallTerminateISR2(void); + #define RSWITCH_TIMEOUT_MS 10000 static int rswitch_reg_wait(uint32 addr, uint32 mask, uint32 expected) { @@ -660,7 +667,6 @@ int rswitch_init(void) rsw_dev.gwca->rx_chain.num_ring = TX_RX_RING_SIZE; rsw_dev.gwca->rx_chain.dir_tx = 0; rswitch_gwca_chain_ts_format(&rsw_dev, &(rsw_dev.gwca->rx_chain)); - rsw_dev.gwca->irq_queue = 0; rsw_dev.gwca->tx_chain.chain_index = 1; rsw_dev.gwca->tx_chain.ring = tx_ring; @@ -670,7 +676,6 @@ int rswitch_init(void) rsw_dev.gwca->tx_chain.num_ring = TX_RX_RING_SIZE; rsw_dev.gwca->tx_chain.dir_tx = 1; rswitch_gwca_chain_format(&rsw_dev, &(rsw_dev.gwca->tx_chain)); - rsw_dev.gwca->irq_queue = 1; CHECK_RET(rswitch_bpool_config(&rsw_dev)); @@ -812,4 +817,178 @@ int rswitch_open(void) TRUE); return 0; -} \ No newline at end of file +} + +/* Determine which chain (rx or tx) generated the interrupt */ +static void rswitch_get_interrupt_source_and_clear() +{ + struct rswitch_gwca_chain *chain; + uint32 chain_index; + uint32 reg_val; + + /* Check if the IRQ was triggered by the RX chain */ + chain = &rsw_dev.gwca->rx_chain; + chain_index = chain->chain_index; + reg_val = reg_read32(rsw_dev.gwca->base_addr + GWDIS0i_OFFSET(chain_index)); + if (reg_val & GWDIS0i_BIT(chain_index)) { + chain->irq_triggered = 1; + reg_write32(GWDIS0i_BIT(chain_index), rsw_dev.gwca->base_addr + + GWDIS0i_OFFSET(chain_index)); + } + + /* Check if the IRQ was triggered by the TX chain */ + chain_index = rsw_dev.gwca->tx_chain.chain_index; + reg_val = reg_read32(rsw_dev.gwca->base_addr + GWDIS0i_OFFSET(chain_index)); + if (reg_val & GWDIS0i_BIT(chain_index)) { + rsw_dev.gwca->tx_chain.irq_triggered = 1; + reg_write32(GWDIS0i_BIT(chain_index), rsw_dev.gwca->base_addr + + GWDIS0i_OFFSET(chain_index)); + } +} + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_rx_tx_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_rx_tx_int) +{ + struct rswitch_gwca_chain *chain; + struct rswitch_ext_ts_desc *desc; + uint8 *data_ptr; + uint16 data_len; + + debug_msg("%s", __func__); + + chain = &rsw_dev.gwca->rx_chain; + if (chain->irq_triggered != 0) { + /* Go through the descriptors chain to parse received data */ + while (1) { + desc = &(chain->ts_ring[chain->next_index]); + /* Stop once we get to a descriptor that was not modified */ + if (desc->die_dt == (DT_FEMPTY | DIE)) { + break; + } + /* We know that "dptrh" is always 0x0 so we ignore it intentionally */ + data_ptr = (uint8 *) desc->dptrl; + data_len = (desc->info_ds) & 0xFFF; + debug_print_buffer(data_ptr, data_len); + /* Reset the data buffer */ + memset(data_ptr, 0, PKT_BUF_SZ_ALIGN); + /* Reset the descriptor so that it can be used again in the next round */ + memset(desc, 0, sizeof(*desc)); + desc->die_dt = (DT_FEMPTY | DIE); + desc->info_ds = PKT_BUF_SZ; + desc->dptrl = (uint32) data_ptr; + /* Move to the next item in the list. */ + chain->next_index++; + /* The last item is a LINKFIX and we know that, so we wrap back + * to the 1st item earlier. */ + if (chain->next_index >= chain->num_ring - 1) { + chain->next_index = 0; + } + } + /* Remove the flag for the received data. + * Note = this is not the best technique because another IRQ might + * be triggered in the meanwhile (is it possible?) so we might + * miss it. Might be improved if problems appear... */ + chain->irq_triggered = 0; + } + + chain = &rsw_dev.gwca->tx_chain; + if (chain->irq_triggered) { + // TODO: restore the descriptors that have been used to send the data + chain->irq_triggered = 0; + } + CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_RX_TX_INT_ClearFlag(void) +{ + //debug_msg("%s", __func__); + rswitch_get_interrupt_source_and_clear(); +} + +#define APP_ISR_gwca1_rx_tx_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_rx_ts_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_rx_ts_int) +{ + debug_msg("%s", __func__); + CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_RX_TS_INT_ClearFlag(void) +{ + debug_msg("%s", __func__); +} + +#define APP_ISR_gwca1_rx_ts_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_coma_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(coma_err_int) +{ + debug_msg("%s", __func__); + CallTerminateISR2(); +} + +FUNC(void, OS_CODE) COMA_ERR_INT_ClearFlag(void) +{ + debug_msg("%s", __func__); +} + +#define APP_ISR_coma_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_err_int) +{ + debug_msg("%s", __func__); + CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_ERR_INT_ClearFlag(void) +{ + debug_msg("%s", __func__); +} + +#define APP_ISR_gwca1_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_etha0_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(etha0_err_int) +{ + debug_msg("%s", __func__); + CallTerminateISR2(); +} + +FUNC(void, OS_CODE) ETHA0_ERR_INT_ClearFlag(void) +{ + debug_msg("%s", __func__); +} + +#define APP_ISR_etha0_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" \ No newline at end of file From 00d9c47e14727e76e11c035cf7d7adffe0b62d11 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 12 Jul 2023 19:11:18 +0200 Subject: [PATCH 13/24] rswitch: adding support for transmission A sample task is also added which simply echoes back the data that it receives. Signed-off-by: Valerio Setti --- .../armv8/spider/ethernet/err_codes.h | 4 +- .../cortex-a-r/armv8/spider/ethernet/eth.oil | 7 ++ .../cortex-a-r/armv8/spider/ethernet/main.c | 56 ++++++++++- .../armv8/spider/ethernet/rswitch.c | 95 ++++++++++++++++--- .../armv8/spider/ethernet/rswitch.h | 5 + 5 files changed, 151 insertions(+), 16 deletions(-) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h b/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h index 6bfc7b434..ca307be8d 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h @@ -1,6 +1,8 @@ #ifndef _ERR_CODES_H_ #define _ERR_CODES_H_ -#define ERR_TIMEOUT (-1) +#define ERR_TIMEOUT (-1) +#define ERR_BUFF_TOO_LARGE (-2) +#define ERR_TX_FAILURE (-3) #endif /* _ERR_CODES_H_ */ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil index 166eb6250..9422eb47e 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil @@ -51,6 +51,13 @@ CPU eth { SCHEDULE = FULL; }; + TASK echo { + PRIORITY = 1; + AUTOSTART = FALSE; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + ISR gwca1_rx_tx_int { CATEGORY = 2; PRIORITY = 1; diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c index 047058b7a..577a7c940 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/main.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -4,10 +4,14 @@ #include "rswitch.h" #include "eth_gptp.h" #include "serial.h" +#include "string.h" #define APP_Task_sample_init_START_SEC_CODE #include "tpl_memmap.h" +uint8 tmp_buffer[1600]; +uint16 tmp_buffer_len = 0; + // Is this the right section for the main function?? FUNC(int, OS_APPL_CODE) main(void) { @@ -15,6 +19,14 @@ FUNC(int, OS_APPL_CODE) main(void) return 0; } +void eth_callback(uint8 *data, uint16 len) +{ + /* Copy the data into the local buffer and then activate the Echo task */ + memcpy(tmp_buffer, data, len); + tmp_buffer_len = len; + ActivateTask(echo); +} + TASK(sample_init) { int ret; @@ -25,7 +37,6 @@ TASK(sample_init) { // Interrupt initializazion done by Trampoline eth_disable_fuse_ovr(); - debug_msg("Initialize SERDES"); ret = eth_serdes_initialize(); if (ret != 0) { debug_msg("Error in eth_serdes_initialize"); @@ -33,7 +44,6 @@ TASK(sample_init) { } debug_msg("SERDES initialization done"); - debug_msg("Initialize RSwitch"); ret = rswitch_init(); if (ret != 0) { debug_msg("Error in rswitch_init\n"); @@ -44,13 +54,14 @@ TASK(sample_init) { debug_msg("Initialize gPTP"); eth_gptp_init(); - debug_msg("RSwitch open"); ret = rswitch_open(); if (ret != 0) { debug_msg("Error in rswitch_open\n"); goto exit; } - debug_msg("RSwitch completed"); + debug_msg("RSwitch open completed"); + + rswitch_regiter_data_received_callback(eth_callback); debug_msg("Initialization completed"); exit: @@ -58,4 +69,41 @@ TASK(sample_init) { } #define APP_Task_sample_init_STOP_SEC_CODE +#include "tpl_memmap.h" + +#define APP_Task_echo_START_SEC_CODE +#include "tpl_memmap.h" + +TASK(echo) +{ + int ret; + uint8 src_mac[6]; + uint8 dst_mac[6]; + + debug_msg("## Echo task ##"); + + debug_msg("Received:"); + debug_print_buffer(tmp_buffer, tmp_buffer_len); + + /* Swap MAC addresses just to play a little with the data */ + memcpy(src_mac, &tmp_buffer[0], 6); + memcpy(dst_mac, &tmp_buffer[6], 6); + memcpy(&tmp_buffer[0], dst_mac, 6); + memcpy(&tmp_buffer[6], src_mac, 6); + + ret = rswitch_send_data(tmp_buffer, tmp_buffer_len); + if (ret != 0) { + debug_msg("Send data back: FAILED"); + } else { + debug_msg("Send data back: SUCCESS"); + } + + /* Clear the data for the next iteration */ + memset(tmp_buffer, 0, sizeof(tmp_buffer)); + tmp_buffer_len = 0; + + TerminateTask(); +} + +#define APP_Task_echo_STOP_SEC_CODE #include "tpl_memmap.h" \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c index d44ac123e..dc0cc9652 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c @@ -270,6 +270,9 @@ struct rswitch_device { * that doesn't work, so we will redeclare it here... */ extern FUNC(void, OS_CODE) CallTerminateISR2(void); +/* This is the callback function that is invoked every time some data is received */ +rx_callback_fn rx_cb = NULL; + #define RSWITCH_TIMEOUT_MS 10000 static int rswitch_reg_wait(uint32 addr, uint32 mask, uint32 expected) { @@ -522,6 +525,9 @@ static void rswitch_gwca_chain_format(struct rswitch_device *rswitch, ring->dptrh = 0x00; ring->die_dt = DT_FEMPTY | DIE; } else { + ring->info_ds = 0; + ring->dptrl = (uint32) c->data_buffers[i]; + ring->dptrh = 0x00; ring->die_dt = DT_EEMPTY | DIE; } } @@ -558,6 +564,9 @@ static void rswitch_gwca_chain_ts_format(struct rswitch_device *rswitch, ring->dptrh = 0x00; ring->die_dt = DT_FEMPTY | DIE; } else { + ring->info_ds = 0; + ring->dptrl = (uint32) c->data_buffers[i]; + ring->dptrh = 0x00; ring->die_dt = DT_EEMPTY | DIE; } } @@ -819,6 +828,52 @@ int rswitch_open(void) return 0; } +int rswitch_send_data(uint8 *buf, uint16 size) +{ + struct rswitch_gwca_chain *chain = &rsw_dev.gwca->tx_chain; + struct rswitch_ext_desc *desc; + uint8 *dest_buf; + + /* Temporary code: try to fit into a single packet. This can be extended + * in the future but it requires code to handle data splitting. */ + if (size > PKT_BUF_SZ) { + debug_msg("Error: transmitted buffer is too large"); + return ERR_BUFF_TOO_LARGE; + } + + /* Pick the 1st not used descriptor that can be used for transmission */ + desc = &chain->ring[chain->next_index]; + /* Check that this descriptor is REALLY free */ + if (desc->die_dt != (DT_EEMPTY | DIE)) { + debug_msg("Error: invalid descriptor selected for transmission"); + return ERR_TX_FAILURE; + } + /* Prepare the descriptor */ + desc->die_dt = DT_FSINGLE | DIE; + desc->info_ds = size & 0xFFF; + /* Copy data to be transmitted */ + dest_buf = (uint8 *) desc->dptrl; + memcpy(dest_buf, buf, size); + + /* Start transmission */ + rswitch_modify(rsw_dev.gwca->base_addr + GWTRC0, 0, BIT(chain->chain_index)); + + /* Move to the next item in the list. */ + chain->next_index++; + /* The last item is a LINKFIX and we know that, so we wrap back + * to the 1st item earlier. */ + if (chain->next_index >= chain->num_ring - 1) { + chain->next_index = 0; + } + + return 0; +} + +void rswitch_regiter_data_received_callback(rx_callback_fn func) +{ + rx_cb = func; +} + /* Determine which chain (rx or tx) generated the interrupt */ static void rswitch_get_interrupt_source_and_clear() { @@ -855,9 +910,11 @@ static void rswitch_get_interrupt_source_and_clear() ISR(gwca1_rx_tx_int) { struct rswitch_gwca_chain *chain; - struct rswitch_ext_ts_desc *desc; + struct rswitch_ext_ts_desc *ts_desc; + struct rswitch_ext_desc *desc; uint8 *data_ptr; uint16 data_len; + int i; debug_msg("%s", __func__); @@ -865,22 +922,28 @@ ISR(gwca1_rx_tx_int) if (chain->irq_triggered != 0) { /* Go through the descriptors chain to parse received data */ while (1) { - desc = &(chain->ts_ring[chain->next_index]); + ts_desc = &(chain->ts_ring[chain->next_index]); /* Stop once we get to a descriptor that was not modified */ - if (desc->die_dt == (DT_FEMPTY | DIE)) { + if (ts_desc->die_dt == (DT_FEMPTY | DIE)) { break; } /* We know that "dptrh" is always 0x0 so we ignore it intentionally */ - data_ptr = (uint8 *) desc->dptrl; - data_len = (desc->info_ds) & 0xFFF; - debug_print_buffer(data_ptr, data_len); + data_ptr = (uint8 *) ts_desc->dptrl; + data_len = (ts_desc->info_ds) & 0xFFF; + /* If the callback is present then call it, otherwise just print + * the data */ + if (rx_cb != NULL) { + rx_cb(data_ptr, data_len); + } else { + debug_print_buffer(data_ptr, data_len); + } /* Reset the data buffer */ memset(data_ptr, 0, PKT_BUF_SZ_ALIGN); /* Reset the descriptor so that it can be used again in the next round */ - memset(desc, 0, sizeof(*desc)); - desc->die_dt = (DT_FEMPTY | DIE); - desc->info_ds = PKT_BUF_SZ; - desc->dptrl = (uint32) data_ptr; + memset(ts_desc, 0, sizeof(*ts_desc)); + ts_desc->die_dt = (DT_FEMPTY | DIE); + ts_desc->info_ds = PKT_BUF_SZ; + ts_desc->dptrl = (uint32) data_ptr; /* Move to the next item in the list. */ chain->next_index++; /* The last item is a LINKFIX and we know that, so we wrap back @@ -898,7 +961,17 @@ ISR(gwca1_rx_tx_int) chain = &rsw_dev.gwca->tx_chain; if (chain->irq_triggered) { - // TODO: restore the descriptors that have been used to send the data + /* Here we reset all the descriptors and data buffers of the TX chain. + * It works only if 1 descriptor is transmitted at a time. + * TODO: improve to handle transmissions of multiple descriptors. */ + for (i = 0; i < chain->num_ring - 1; i++) { + desc = &(chain->ring[i]); + desc->die_dt = DT_EEMPTY | DIE; + desc->info_ds = 0; + desc->info1 = 0; + data_ptr = (uint8 *) desc->dptrl; + memset(data_ptr, 0, PKT_BUF_SZ_ALIGN); + } chain->irq_triggered = 0; } CallTerminateISR2(); diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h index fee6f6333..520f6e9af 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h @@ -4,4 +4,9 @@ int rswitch_init(void); int rswitch_open(void); +typedef void (*rx_callback_fn)(uint8 *buf, uint16 len); + +void rswitch_regiter_data_received_callback(rx_callback_fn func); +int rswitch_send_data(uint8 *buf, uint16 size); + #endif /* _ETH_H_ */ \ No newline at end of file From 23eed016b4f747d959d53233ab9001218fabcb6e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 5 Sep 2023 12:06:42 +0200 Subject: [PATCH 14/24] lwip: add submodule Signed-off-by: Valerio Setti --- .gitmodules | 3 +++ libraries/net/ethernet/lwip | 1 + 2 files changed, 4 insertions(+) create mode 160000 libraries/net/ethernet/lwip diff --git a/.gitmodules b/.gitmodules index e2382d003..b2960750c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "machines/riscv/pulpino/pulpino"] path = machines/riscv/pulpino/pulpino url = https://github.com/Instrumented-Pulpino/pulpino.git +[submodule "libraries/net/ethernet/lwip"] + path = libraries/net/ethernet/lwip + url = https://git.savannah.nongnu.org/git/lwip.git diff --git a/libraries/net/ethernet/lwip b/libraries/net/ethernet/lwip new file mode 160000 index 000000000..84fde1ebb --- /dev/null +++ b/libraries/net/ethernet/lwip @@ -0,0 +1 @@ +Subproject commit 84fde1ebbfe35b3125fc2d89b8a456cbacf148e9 From 23bf5a87dff2672d29f79efc5854e977186930d3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 5 Sep 2023 12:08:50 +0200 Subject: [PATCH 15/24] lwip: integrate into example project PING works in this state. Note: IP address is fixed at 192.168.1.2 Signed-off-by: Valerio Setti --- .../armv8/spider/ethernet/build_lwip.sh | 39 +++ .../cortex-a-r/armv8/spider/ethernet/eth.oil | 8 +- .../armv8/spider/ethernet/lwip-port/arch/cc.h | 32 ++ .../armv8/spider/ethernet/lwip-port/ethif.c | 144 +++++++++ .../armv8/spider/ethernet/lwip-port/ethif.h | 10 + .../spider/ethernet/lwip-port/lwipopts.h | 296 ++++++++++++++++++ .../spider/ethernet/lwip-port/sys_arch.c | 41 +++ .../spider/ethernet/lwip-port/toolchain.cmake | 19 ++ .../cortex-a-r/armv8/spider/ethernet/main.c | 89 ++---- .../cortex-a-r/armv8/spider/ethernet/printf.h | 2 +- .../armv8/spider/ethernet/rswitch.c | 2 +- .../cortex-a-r/armv8/spider/ethernet/utils.h | 4 +- 12 files changed, 608 insertions(+), 78 deletions(-) create mode 100755 examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/lwip-port/arch/cc.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/lwip-port/lwipopts.h create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/lwip-port/sys_arch.c create mode 100644 examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake diff --git a/examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh b/examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh new file mode 100755 index 000000000..502cdde52 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +#stop on errors +set -e + +function remove_items() { + ITEMS="$1" + + for ITEM in $ITEMS; do + if [ $(ls $ITEM 2>/dev/null) ]; then + echo "Removing $ITEM" + rm $ITEM + fi + done +} + +# Remove old libraries that will be replaced with the new build +remove_items "liblwipallapps.a liblwipcore.a liblwipmbedtls.a" + +# Move to LwIP folder and create the build folder +cd lwip + +if [[ -d "build" ]]; then + echo "Removing LwIP build folder" + rm -r build +fi + +mkdir build +cd build + +cmake -DCMAKE_TOOLCHAIN_FILE:PATH="../../lwip-port/toolchain.cmake" .. + +# Build only required libraries (no example) +make -j lwipcore lwipallapps lwipmbedtls + +echo "Copying LwIP static libraries to local folder" +cp liblwipcore.a ../.. +cp liblwipallapps.a ../.. +cp liblwipmbedtls.a ../.. diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil index 9422eb47e..78f48bee6 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil @@ -22,9 +22,11 @@ CPU eth { APP_SRC = "rswitch.c"; APP_SRC = "eth_gptp.c"; APP_SRC = "printf.c"; + APP_SRC = "lwip-port/sys_arch.c"; + APP_SRC = "lwip-port/ethif.c"; APP_NAME = "eth_exe.elf"; - CFLAGS = "-O0 -g -DHSCIF_1843200BPS"; - LDFLAGS = "-Map=eth_exe.map"; + CFLAGS = "-O0 -g -DHSCIF_1843200BPS -I. -Ilwip/src/include -Ilwip-port"; + LDFLAGS = "-Map=eth_exe.map -L. -llwipcore -llwipallapps"; COMPILER = "arm-none-eabi-gcc"; CPPCOMPILER = "arm-none-eabi-g++"; ASSEMBLER = "arm-none-eabi-as"; @@ -51,7 +53,7 @@ CPU eth { SCHEDULE = FULL; }; - TASK echo { + TASK monitor { PRIORITY = 1; AUTOSTART = FALSE; ACTIVATION = 1; diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/arch/cc.h b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/arch/cc.h new file mode 100644 index 000000000..6a302695f --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/arch/cc.h @@ -0,0 +1,32 @@ +#ifndef __ARCH_CC_H__ +#define __ARCH_CC_H__ + +#include "utils.h" + +#define LWIP_ERR_T int + +#define LWIP_PROVIDE_ERRNO + +/* Define (sn)printf formatters for these lwIP types */ +#define U16_F "u" +#define S16_F "d" +#define X16_F "x" +#define U32_F "u" +#define S32_F "d" +#define X32_F "x" + +/* Compiler hints for packing structures */ +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_STRUCT __attribute__((packed)) +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_END + +/* Plaform specific diagnostic output */ +#define LWIP_PLATFORM_DIAG(x) do { \ + debug_msg x; \ + } while (0) + +#define LWIP_PLATFORM_ASSERT(x) do { \ + } while (0) + +#endif /* __ARCH_CC_H__ */ diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.c b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.c new file mode 100644 index 000000000..83f5525bf --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.c @@ -0,0 +1,144 @@ +#include +#include "ethif.h" +#include "utils.h" +#include "eth_serdes.h" +#include "rswitch.h" +#include "eth_gptp.h" +#include "lwip/etharp.h" + +static struct netif *netif_ref = NULL; + +void ethif_callback(uint8 *data, uint16 len) +{ + struct pbuf *p, *q; + uint8_t *data_ptr = data; + err_t ret; + + /* move received packet into a new pbuf */ +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + if (p == NULL) { + debug_msg("Error: unable to allocate memory in %s", __func__); + return; + } + +#if ETH_PAD_SIZE + pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ +#endif + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. */ + for (q = p; q != NULL; q = q->next) { + memcpy(q->payload, data_ptr, q->len); + data_ptr += q->len; + } +#if ETH_PAD_SIZE + pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + /* pass all packets to ethernet_input, which decides what packets it supports */ + ret = netif_ref->input(p, netif_ref); + if (ret != ERR_OK) { + debug_msg("Error: netif->input returned %d\n", ret); + pbuf_free(p); + } +} + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + (void) netif; + struct pbuf *q; + int ret; + +#if ETH_PAD_SIZE + pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ +#endif + + for (q = p; q != NULL; q = q->next) { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + ret = rswitch_send_data(q->payload, q->len); + if (ret != 0) { + return ERR_IF; + } + } + +#if ETH_PAD_SIZE + pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + return ERR_OK; +} + +static err_t low_level_init(struct netif *netif) +{ + int ret; + + netif->hwaddr_len = ETHARP_HWADDR_LEN; + /* This is the same value set in "rswitch.c" */ + netif->hwaddr[0] = 0x74U; + netif->hwaddr[1] = 0x90U; + netif->hwaddr[2] = 0x50U; + netif->hwaddr[3] = 0x00U; + netif->hwaddr[4] = 0x00U; + netif->hwaddr[5] = 0x00U; + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_LINK_UP; + + // Interrupt initializazion done by Trampoline + eth_disable_fuse_ovr(); + + ret = eth_serdes_initialize(); + if (ret != 0) { + debug_msg("Error in eth_serdes_initialize"); + return ERR_IF; + } + debug_msg("SERDES initialization done"); + + ret = rswitch_init(); + if (ret != 0) { + debug_msg("Error in rswitch_init\n"); + return ERR_IF; + } + debug_msg("RSwitch initialization done"); + + debug_msg("Initialize gPTP"); + eth_gptp_init(); + + ret = rswitch_open(); + if (ret != 0) { + debug_msg("Error in rswitch_open\n"); + return ERR_IF; + } + debug_msg("RSwitch open completed"); + + rswitch_regiter_data_received_callback(ethif_callback); + + debug_msg("Initialization completed"); + + return ERR_OK; +} + +err_t ethif_init(struct netif *netif) +{ + debug_msg("%s", __func__); + + netif_ref = netif; + + netif->name[0] = 'r'; + netif->name[1] = 'n'; + netif->mtu = 1500; + + netif->state = NULL; // Set to anything, if necessary + + netif->linkoutput = low_level_output; + netif->output = etharp_output; + + return low_level_init(netif); +} \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.h b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.h new file mode 100644 index 000000000..60225bd2b --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.h @@ -0,0 +1,10 @@ +#ifndef _ETHERNET_IF_H_ +#define _ETHERNET_IF_H_ + +#include "lwip/init.h" +#include "lwip/err.h" +#include "lwip/netif.h" + +err_t ethif_init(struct netif *netif); + +#endif // _ETHERNET_IF_H_ \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/lwipopts.h b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/lwipopts.h new file mode 100644 index 000000000..c47120535 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/lwipopts.h @@ -0,0 +1,296 @@ +#define LWIP_DEBUG 1 +/* test an lwipopts.h file with default contents */ +#define NO_SYS 1 +#define NO_SYS_NO_TIMERS 1 +#define LWIP_TIMERS 1 +#define LWIP_TIMERS_CUSTOM 0 +#define LWIP_MPU_COMPATIBLE 0 +#define LWIP_TCPIP_CORE_LOCKING 1 +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#define SYS_LIGHTWEIGHT_PROT 0 +#define MEM_LIBC_MALLOC 0 +#define MEMP_MEM_MALLOC 0 +#define MEMP_MEM_INIT 0 +#define MEM_ALIGNMENT 1 +#define MEM_SIZE 1600 +#define MEMP_OVERFLOW_CHECK 0 +#define MEMP_SANITY_CHECK 0 +#define MEM_OVERFLOW_CHECK 0 +#define MEM_SANITY_CHECK 0 +#define MEM_USE_POOLS 0 +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#define MEMP_USE_CUSTOM_POOLS 0 +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +/*#define MEMP_NUM_PBUF 16 +#define MEMP_NUM_RAW_PCB 4 +#define MEMP_NUM_UDP_PCB 4 +#define MEMP_NUM_TCP_PCB 5 +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#define MEMP_NUM_TCP_SEG 16 +#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB +#define MEMP_NUM_REASSDATA 5 +#define MEMP_NUM_FRAG_PBUF 15 +#define MEMP_NUM_ARP_QUEUE 30 +#define MEMP_NUM_IGMP_GROUP 8 +#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2) +#define MEMP_NUM_NETBUF 2 +#define MEMP_NUM_NETCONN 4 +#define MEMP_NUM_SELECT_CB 4 +#define MEMP_NUM_TCPIP_MSG_API 8 +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#define MEMP_NUM_NETDB 1 +#define MEMP_NUM_LOCALHOSTLIST 1 +#define PBUF_POOL_SIZE 16 +#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/ +#define LWIP_ARP 1 +#define ARP_TABLE_SIZE 10 +#define ARP_MAXAGE 300 +#define ARP_QUEUEING 0 +#define ARP_QUEUE_LEN 3 +#define ETHARP_SUPPORT_VLAN 0 +#define LWIP_ETHERNET LWIP_ARP +#define ETH_PAD_SIZE 0 +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF +#define LWIP_IPV4 1 +#define IP_FORWARD 0 +#define IP_REASSEMBLY 1 +#define IP_FRAG 1 +#define IP_OPTIONS_ALLOWED 1 +#define IP_REASS_MAXAGE 15 +#define IP_REASS_MAX_PBUFS 10 +#define IP_DEFAULT_TTL 255 +#define IP_SOF_BROADCAST 0 +#define IP_SOF_BROADCAST_RECV 0 +#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 +#define LWIP_ICMP 1 +#define ICMP_TTL (IP_DEFAULT_TTL) +#define LWIP_BROADCAST_PING 0 +#define LWIP_MULTICAST_PING 0 +#define LWIP_RAW 0 +#define RAW_TTL (IP_DEFAULT_TTL) +#define LWIP_DHCP 1 +#define LWIP_DHCP_CHECK_LINK_UP 0 +#define LWIP_DHCP_BOOTP_FILE 0 +#define LWIP_DHCP_GET_NTP_SRV 0 +#define LWIP_DHCP_MAX_NTP_SERVERS 1 +#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS +#define LWIP_AUTOIP 0 +#define LWIP_DHCP_AUTOIP_COOP 0 +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#define LWIP_MIB2_CALLBACKS 0 +#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW)) +#define LWIP_IGMP 0 +#define LWIP_DNS 0 +#define DNS_TABLE_SIZE 4 +#define DNS_MAX_NAME_LENGTH 256 +#define DNS_MAX_SERVERS 2 +#define DNS_MAX_RETRIES 4 +#define DNS_DOES_NAME_CHECK 1 +#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) +#define DNS_LOCAL_HOSTLIST 0 +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0 +#define LWIP_UDP 1 +#define LWIP_UDPLITE 0 +#define UDP_TTL (IP_DEFAULT_TTL) +#define LWIP_NETBUF_RECVINFO 0 +#define LWIP_TCP 0 +#define TCP_TTL (IP_DEFAULT_TTL) +#define TCP_WND (4 * TCP_MSS) +#define TCP_MAXRTX 12 +#define TCP_SYNMAXRTX 6 +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#define LWIP_TCP_SACK_OUT 0 +#define LWIP_TCP_MAX_SACK_NUM 4 +#define TCP_MSS 536 +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#define TCP_SND_BUF (2 * TCP_MSS) +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#define TCP_OOSEQ_MAX_BYTES 0 +#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES +#define TCP_OOSEQ_MAX_PBUFS 0 +#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS +#define TCP_LISTEN_BACKLOG 0 +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#define TCP_OVERSIZE TCP_MSS +#define LWIP_TCP_TIMESTAMPS 0 +#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4)) +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#define LWIP_WND_SCALE 0 +#define TCP_RCV_SCALE 0 +#define LWIP_TCP_PCB_NUM_EXT_ARGS 0 +#define LWIP_ALTCP 0 +#define LWIP_ALTCP_TLS 0 +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#define PBUF_LINK_ENCAPSULATION_HLEN 0 +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) +#define LWIP_PBUF_REF_T u8_t +#define LWIP_SINGLE_NETIF 0 +#define LWIP_NETIF_HOSTNAME 0 +#define LWIP_NETIF_API 0 +#define LWIP_NETIF_STATUS_CALLBACK 0 +#define LWIP_NETIF_EXT_STATUS_CALLBACK 0 +#define LWIP_NETIF_LINK_CALLBACK 0 +#define LWIP_NETIF_REMOVE_CALLBACK 0 +#define LWIP_NETIF_HWADDRHINT 0 +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#define LWIP_NUM_NETIF_CLIENT_DATA 0 +#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF) +#define LWIP_LOOPIF_MULTICAST 0 +#define LWIP_NETIF_LOOPBACK 0 +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +/*#define TCPIP_THREAD_NAME "tcpip_thread" +#define TCPIP_THREAD_STACKSIZE 0 +#define TCPIP_THREAD_PRIO 1 +#define TCPIP_MBOX_SIZE 0 +#define LWIP_TCPIP_THREAD_ALIVE() +#define SLIPIF_THREAD_NAME "slipif_loop" +#define SLIPIF_THREAD_STACKSIZE 0 +#define SLIPIF_THREAD_PRIO 1 +#define DEFAULT_THREAD_NAME "lwIP" +#define DEFAULT_THREAD_STACKSIZE 0 +#define DEFAULT_THREAD_PRIO 1 +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#define DEFAULT_ACCEPTMBOX_SIZE 0*/ +#define LWIP_NETCONN 0 +#define LWIP_TCPIP_TIMEOUT 0 +#define LWIP_NETCONN_SEM_PER_THREAD 0 +#define LWIP_NETCONN_FULLDUPLEX 0 +#define LWIP_SOCKET 0 +#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */ +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#define LWIP_SOCKET_OFFSET 0 +#define LWIP_TCP_KEEPALIVE 0 +#define LWIP_SO_SNDTIMEO 0 +#define LWIP_SO_RCVTIMEO 0 +#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0 +#define LWIP_SO_RCVBUF 0 +#define LWIP_SO_LINGER 0 +#define RECV_BUFSIZE_DEFAULT INT_MAX +#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000 +#define SO_REUSE 0 +#define SO_REUSE_RXTOALL 0 +#define LWIP_FIONREAD_LINUXMODE 0 +#define LWIP_SOCKET_SELECT 1 +#define LWIP_SOCKET_POLL 1 +#define LWIP_STATS 1 +#define LWIP_STATS_DISPLAY 0 +#define LINK_STATS 1 +#define ETHARP_STATS (LWIP_ARP) +#define IP_STATS 1 +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#define ICMP_STATS 1 +#define IGMP_STATS (LWIP_IGMP) +#define UDP_STATS (LWIP_UDP) +#define TCP_STATS (LWIP_TCP) +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#define SYS_STATS (NO_SYS == 0) +#define IP6_STATS (LWIP_IPV6) +#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) +#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) +#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) +#define ND6_STATS (LWIP_IPV6) +#define MIB2_STATS 0 +#define LWIP_CHECKSUM_CTRL_PER_NETIF 0 +#define CHECKSUM_GEN_IP 1 +#define CHECKSUM_GEN_UDP 1 +#define CHECKSUM_GEN_TCP 1 +#define CHECKSUM_GEN_ICMP 1 +#define CHECKSUM_GEN_ICMP6 1 +#define CHECKSUM_CHECK_IP 1 +#define CHECKSUM_CHECK_UDP 1 +#define CHECKSUM_CHECK_TCP 1 +#define CHECKSUM_CHECK_ICMP 1 +#define CHECKSUM_CHECK_ICMP6 1 +#define LWIP_CHECKSUM_ON_COPY 0 +#define LWIP_IPV6 0 +#define IPV6_REASS_MAXAGE 60 +#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF) +#define LWIP_IPV6_SCOPES_DEBUG 0 +#define LWIP_IPV6_NUM_ADDRESSES 3 +#define LWIP_IPV6_FORWARD 0 +#define LWIP_IPV6_FRAG 1 +#define LWIP_IPV6_REASS (LWIP_IPV6) +#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 +#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6) +#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG) +#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 +#define LWIP_ICMP6 (LWIP_IPV6) +#define LWIP_ICMP6_DATASIZE 8 +#define LWIP_ICMP6_HL 255 +#define LWIP_IPV6_MLD (LWIP_IPV6) +#define MEMP_NUM_MLD6_GROUP 4 +#define LWIP_ND6_QUEUEING (LWIP_IPV6) +#define MEMP_NUM_ND6_QUEUE 20 +#define LWIP_ND6_NUM_NEIGHBORS 10 +#define LWIP_ND6_NUM_DESTINATIONS 10 +#define LWIP_ND6_NUM_PREFIXES 5 +#define LWIP_ND6_NUM_ROUTERS 3 +#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 +#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 +#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 +#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 +#define LWIP_ND6_REACHABLE_TIME 30000 +#define LWIP_ND6_RETRANS_TIMER 1000 +#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 +#define LWIP_ND6_ALLOW_RA_UPDATES 1 +#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 +#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0 +#define LWIP_IPV6_DHCP6 0 +#define LWIP_IPV6_DHCP6_STATEFUL 0 +#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6 +#define LWIP_DHCP6_GET_NTP_SRV 0 +#define LWIP_DHCP6_MAX_NTP_SERVERS 1 +#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS + +/* TODO: check hooks */ + +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#define ETHARP_DEBUG LWIP_DBG_ON +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_ON +#define IGMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_ON +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TIMERS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF +#define AUTOIP_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_OFF +#define IP6_DEBUG LWIP_DBG_OFF +#define DHCP6_DEBUG LWIP_DBG_OFF +#define LWIP_TESTMODE 0 + +#define LWIP_PERF 0 diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/sys_arch.c b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/sys_arch.c new file mode 100644 index 000000000..029a96e99 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/sys_arch.c @@ -0,0 +1,41 @@ +#include "lwip/sys.h" + +u32_t sys_now(void) +{ + return 0; +} + +static int hexval(char c) { + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; +} + +/* This is needed because "netif.c" uses it and without this implementation + * this would cause LIBC to be included and that's something we don't want. */ +unsigned int atoi(const unsigned char *num) { + long value = 0; + int neg = 0; + + if (num[0] == '0' && num[1] == 'x') { + // hex + num += 2; + while (*num && isxdigit(*num)) + value = value * 16 + hexval(*num++); + } else { + // decimal + if (num[0] == '-') { + neg = 1; + num++; + } + while (*num && isdigit(*num)) + value = value * 10 + *num++ - '0'; + } + if (neg) + value = -value; + return value; +} \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake new file mode 100644 index 000000000..45306551f --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake @@ -0,0 +1,19 @@ +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_C_COMPILER "arm-none-eabi-gcc") + +set(CMAKE_C_FLAGS "-std=c99 -mcpu=cortex-r52 -mfloat-abi=soft -O0 -g") +set(CMAKE_EXE_LINKER_FLAGS "-nostdlib") + +set(LWIP_COMPILER_FLAGS -std=c99 -mcpu=cortex-r52 -mfloat-abi=soft -O0 -g) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set (LWIP_INCLUDE_DIRS + "${LWIP_DIR}/src/include" + "${LWIP_DIR}/../lwip-port" + "${LWIP_DIR}/.." +) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c index 577a7c940..afb727ed6 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/main.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -1,16 +1,17 @@ #include "tpl_os.h" #include "utils.h" -#include "eth_serdes.h" -#include "rswitch.h" -#include "eth_gptp.h" #include "serial.h" #include "string.h" +#include "lwip/netif.h" +#include "lwip/ip4_addr.h" +#include "lwip/timeouts.h" +#include "lwip-port/ethif.h" #define APP_Task_sample_init_START_SEC_CODE #include "tpl_memmap.h" -uint8 tmp_buffer[1600]; -uint16 tmp_buffer_len = 0; +ip4_addr_t ip4_addr, net_mask, gateway; +struct netif ethif_netif; // Is this the right section for the main function?? FUNC(int, OS_APPL_CODE) main(void) @@ -19,91 +20,39 @@ FUNC(int, OS_APPL_CODE) main(void) return 0; } -void eth_callback(uint8 *data, uint16 len) -{ - /* Copy the data into the local buffer and then activate the Echo task */ - memcpy(tmp_buffer, data, len); - tmp_buffer_len = len; - ActivateTask(echo); -} - TASK(sample_init) { - int ret; - Serial_Init(); rswitch_enable_clock_and_reset(); port_init(); - // Interrupt initializazion done by Trampoline - eth_disable_fuse_ovr(); - ret = eth_serdes_initialize(); - if (ret != 0) { - debug_msg("Error in eth_serdes_initialize"); - goto exit; - } - debug_msg("SERDES initialization done"); + lwip_init(); - ret = rswitch_init(); - if (ret != 0) { - debug_msg("Error in rswitch_init\n"); - goto exit; - } - debug_msg("RSwitch initialization done"); + IP4_ADDR(&ip4_addr, 192, 168, 1, 2); + IP4_ADDR(&net_mask, 255, 255, 255, 0); + IP4_ADDR(&gateway, 0, 0, 0, 0); - debug_msg("Initialize gPTP"); - eth_gptp_init(); + netif_add(ðif_netif, &ip4_addr, &net_mask, &gateway, NULL, + ethif_init, netif_input); - ret = rswitch_open(); - if (ret != 0) { - debug_msg("Error in rswitch_open\n"); - goto exit; - } - debug_msg("RSwitch open completed"); + netif_set_up(ðif_netif); - rswitch_regiter_data_received_callback(eth_callback); + ActivateTask(monitor); - debug_msg("Initialization completed"); -exit: TerminateTask(); } #define APP_Task_sample_init_STOP_SEC_CODE #include "tpl_memmap.h" -#define APP_Task_echo_START_SEC_CODE +#define APP_Task_sample_init_START_SEC_CODE #include "tpl_memmap.h" -TASK(echo) -{ - int ret; - uint8 src_mac[6]; - uint8 dst_mac[6]; - - debug_msg("## Echo task ##"); - - debug_msg("Received:"); - debug_print_buffer(tmp_buffer, tmp_buffer_len); - - /* Swap MAC addresses just to play a little with the data */ - memcpy(src_mac, &tmp_buffer[0], 6); - memcpy(dst_mac, &tmp_buffer[6], 6); - memcpy(&tmp_buffer[0], dst_mac, 6); - memcpy(&tmp_buffer[6], src_mac, 6); - - ret = rswitch_send_data(tmp_buffer, tmp_buffer_len); - if (ret != 0) { - debug_msg("Send data back: FAILED"); - } else { - debug_msg("Send data back: SUCCESS"); +TASK(monitor) { + while (1) { + sys_check_timeouts(); } - - /* Clear the data for the next iteration */ - memset(tmp_buffer, 0, sizeof(tmp_buffer)); - tmp_buffer_len = 0; - - TerminateTask(); } -#define APP_Task_echo_STOP_SEC_CODE +#define APP_Task_sample_init_STOP_SEC_CODE #include "tpl_memmap.h" \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/printf.h b/examples/cortex-a-r/armv8/spider/ethernet/printf.h index c1ad80b9f..783dda2e5 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/printf.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/printf.h @@ -1,4 +1,4 @@ -#include "tpl_os.h" +#include "../../../../../../machines/virt-v7/tpl_os_std_types.h" int debug_printf(const char *format, ...); int debug_sprintf(char *out, const char *format, ...); \ No newline at end of file diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c index dc0cc9652..086972d58 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c @@ -916,7 +916,7 @@ ISR(gwca1_rx_tx_int) uint16 data_len; int i; - debug_msg("%s", __func__); + // debug_msg("%s", __func__); chain = &rsw_dev.gwca->rx_chain; if (chain->irq_triggered != 0) { diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.h b/examples/cortex-a-r/armv8/spider/ethernet/utils.h index 4eedbf8b3..de0d73aa1 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.h +++ b/examples/cortex-a-r/armv8/spider/ethernet/utils.h @@ -1,7 +1,7 @@ #ifndef _UTILS_H_ #define _UTILS_H_ -#include "tpl_os.h" +#include "../../../../../../machines/virt-v7/tpl_os_std_types.h" #include "printf.h" #define debug_msg(...) \ @@ -18,8 +18,6 @@ (((~(0UL)) - ((1UL) << (l)) + 1) & \ (~(0UL) >> (BITS_PER_LONG - 1 - (h)))) -#define __unused __attribute__((unused)) - #define CHECK_RET(f) \ ret = (f); \ if (ret != 0) { \ From 934eb5896c5b824f8b4dfcd337244d933af4ef44 Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 22 Sep 2023 11:15:02 +0200 Subject: [PATCH 16/24] spider: move lwip-port/ethernet files in driver folder for spider board --- .../armv8/spider/ethernet/build_lwip.sh | 39 ------------------- .../spider/ethernet/lwip-port/toolchain.cmake | 19 --------- .../drivers/ethernet/renesas}/err_codes.h | 0 .../drivers/ethernet/renesas}/eth_gptp.c | 0 .../drivers/ethernet/renesas}/eth_gptp.h | 0 .../drivers/ethernet/renesas}/eth_serdes.c | 0 .../drivers/ethernet/renesas}/eth_serdes.h | 0 .../drivers/ethernet/renesas}/pfcmap.h | 0 .../drivers/ethernet/renesas}/rswitch.c | 0 .../drivers/ethernet/renesas}/rswitch.h | 0 .../drivers/ethernet/renesas}/rswitch_regs.h | 0 .../drivers/ethernet/renesas}/utils.c | 2 +- .../drivers/ethernet/renesas}/utils.h | 0 .../drivers/lwip_port/renesas}/arch/cc.h | 0 .../drivers/lwip_port/renesas}/ethif.c | 0 .../drivers/lwip_port/renesas}/ethif.h | 0 .../drivers/lwip_port/renesas}/lwipopts.h | 0 .../drivers/lwip_port/renesas}/sys_arch.c | 0 .../drivers/serial/renesas}/printf.c | 2 +- .../drivers/serial/renesas}/printf.h | 0 20 files changed, 2 insertions(+), 60 deletions(-) delete mode 100755 examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh delete mode 100644 examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/err_codes.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/eth_gptp.c (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/eth_gptp.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/eth_serdes.c (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/eth_serdes.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/pfcmap.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/rswitch.c (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/rswitch.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/rswitch_regs.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/utils.c (99%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/ethernet/renesas}/utils.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet/lwip-port => libraries/drivers/lwip_port/renesas}/arch/cc.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet/lwip-port => libraries/drivers/lwip_port/renesas}/ethif.c (100%) rename {examples/cortex-a-r/armv8/spider/ethernet/lwip-port => libraries/drivers/lwip_port/renesas}/ethif.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet/lwip-port => libraries/drivers/lwip_port/renesas}/lwipopts.h (100%) rename {examples/cortex-a-r/armv8/spider/ethernet/lwip-port => libraries/drivers/lwip_port/renesas}/sys_arch.c (100%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/serial/renesas}/printf.c (99%) rename {examples/cortex-a-r/armv8/spider/ethernet => libraries/drivers/serial/renesas}/printf.h (100%) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh b/examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh deleted file mode 100755 index 502cdde52..000000000 --- a/examples/cortex-a-r/armv8/spider/ethernet/build_lwip.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -#stop on errors -set -e - -function remove_items() { - ITEMS="$1" - - for ITEM in $ITEMS; do - if [ $(ls $ITEM 2>/dev/null) ]; then - echo "Removing $ITEM" - rm $ITEM - fi - done -} - -# Remove old libraries that will be replaced with the new build -remove_items "liblwipallapps.a liblwipcore.a liblwipmbedtls.a" - -# Move to LwIP folder and create the build folder -cd lwip - -if [[ -d "build" ]]; then - echo "Removing LwIP build folder" - rm -r build -fi - -mkdir build -cd build - -cmake -DCMAKE_TOOLCHAIN_FILE:PATH="../../lwip-port/toolchain.cmake" .. - -# Build only required libraries (no example) -make -j lwipcore lwipallapps lwipmbedtls - -echo "Copying LwIP static libraries to local folder" -cp liblwipcore.a ../.. -cp liblwipallapps.a ../.. -cp liblwipmbedtls.a ../.. diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake b/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake deleted file mode 100644 index 45306551f..000000000 --- a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/toolchain.cmake +++ /dev/null @@ -1,19 +0,0 @@ -set(CMAKE_SYSTEM_NAME Generic) - -set(CMAKE_C_COMPILER "arm-none-eabi-gcc") - -set(CMAKE_C_FLAGS "-std=c99 -mcpu=cortex-r52 -mfloat-abi=soft -O0 -g") -set(CMAKE_EXE_LINKER_FLAGS "-nostdlib") - -set(LWIP_COMPILER_FLAGS -std=c99 -mcpu=cortex-r52 -mfloat-abi=soft -O0 -g) - -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set (LWIP_INCLUDE_DIRS - "${LWIP_DIR}/src/include" - "${LWIP_DIR}/../lwip-port" - "${LWIP_DIR}/.." -) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/err_codes.h b/libraries/drivers/ethernet/renesas/err_codes.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/err_codes.h rename to libraries/drivers/ethernet/renesas/err_codes.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.c b/libraries/drivers/ethernet/renesas/eth_gptp.c similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.c rename to libraries/drivers/ethernet/renesas/eth_gptp.c diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.h b/libraries/drivers/ethernet/renesas/eth_gptp.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/eth_gptp.h rename to libraries/drivers/ethernet/renesas/eth_gptp.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c b/libraries/drivers/ethernet/renesas/eth_serdes.c similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.c rename to libraries/drivers/ethernet/renesas/eth_serdes.c diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.h b/libraries/drivers/ethernet/renesas/eth_serdes.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/eth_serdes.h rename to libraries/drivers/ethernet/renesas/eth_serdes.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/pfcmap.h b/libraries/drivers/ethernet/renesas/pfcmap.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/pfcmap.h rename to libraries/drivers/ethernet/renesas/pfcmap.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.c b/libraries/drivers/ethernet/renesas/rswitch.c similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/rswitch.c rename to libraries/drivers/ethernet/renesas/rswitch.c diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch.h b/libraries/drivers/ethernet/renesas/rswitch.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/rswitch.h rename to libraries/drivers/ethernet/renesas/rswitch.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h b/libraries/drivers/ethernet/renesas/rswitch_regs.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/rswitch_regs.h rename to libraries/drivers/ethernet/renesas/rswitch_regs.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.c b/libraries/drivers/ethernet/renesas/utils.c similarity index 99% rename from examples/cortex-a-r/armv8/spider/ethernet/utils.c rename to libraries/drivers/ethernet/renesas/utils.c index f24539070..b223bc7bd 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/utils.c +++ b/libraries/drivers/ethernet/renesas/utils.c @@ -153,4 +153,4 @@ void debug_print_buffer(uint8 *buf, uint32 len) debug_printf("%02x ", buf[i]); } debug_printf("\n\r"); -} \ No newline at end of file +} diff --git a/examples/cortex-a-r/armv8/spider/ethernet/utils.h b/libraries/drivers/ethernet/renesas/utils.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/utils.h rename to libraries/drivers/ethernet/renesas/utils.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/arch/cc.h b/libraries/drivers/lwip_port/renesas/arch/cc.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/lwip-port/arch/cc.h rename to libraries/drivers/lwip_port/renesas/arch/cc.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.c b/libraries/drivers/lwip_port/renesas/ethif.c similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.c rename to libraries/drivers/lwip_port/renesas/ethif.c diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.h b/libraries/drivers/lwip_port/renesas/ethif.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/lwip-port/ethif.h rename to libraries/drivers/lwip_port/renesas/ethif.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/lwipopts.h b/libraries/drivers/lwip_port/renesas/lwipopts.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/lwip-port/lwipopts.h rename to libraries/drivers/lwip_port/renesas/lwipopts.h diff --git a/examples/cortex-a-r/armv8/spider/ethernet/lwip-port/sys_arch.c b/libraries/drivers/lwip_port/renesas/sys_arch.c similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/lwip-port/sys_arch.c rename to libraries/drivers/lwip_port/renesas/sys_arch.c diff --git a/examples/cortex-a-r/armv8/spider/ethernet/printf.c b/libraries/drivers/serial/renesas/printf.c similarity index 99% rename from examples/cortex-a-r/armv8/spider/ethernet/printf.c rename to libraries/drivers/serial/renesas/printf.c index a53e9a866..b8e3a6693 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/printf.c +++ b/libraries/drivers/serial/renesas/printf.c @@ -18,7 +18,7 @@ */ #include "printf.h" -#include "serial.h" +#include "spider_serial.h" static void printchar(char **str, int c) { diff --git a/examples/cortex-a-r/armv8/spider/ethernet/printf.h b/libraries/drivers/serial/renesas/printf.h similarity index 100% rename from examples/cortex-a-r/armv8/spider/ethernet/printf.h rename to libraries/drivers/serial/renesas/printf.h From 950a66868a5b4d1ba0e7411bf5c8fac312a864ad Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 10 Nov 2023 17:06:12 +0100 Subject: [PATCH 17/24] spider: define 'ethernet' and 'lwip' libraries --- .../config/cortex-a-r/armv8/spider/config.oil | 20 +++++++ .../drivers/ethernet/renesas/config.oil | 10 ++++ .../drivers/lwip_port/renesas/config.oil | 7 +++ .../libraries/net/ethernet/lwip/config.oil | 55 +++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 goil/templates/libraries/drivers/ethernet/renesas/config.oil create mode 100644 goil/templates/libraries/drivers/lwip_port/renesas/config.oil create mode 100755 goil/templates/libraries/net/ethernet/lwip/config.oil diff --git a/goil/templates/config/cortex-a-r/armv8/spider/config.oil b/goil/templates/config/cortex-a-r/armv8/spider/config.oil index ede076659..3f2c057e7 100755 --- a/goil/templates/config/cortex-a-r/armv8/spider/config.oil +++ b/goil/templates/config/cortex-a-r/armv8/spider/config.oil @@ -6,6 +6,8 @@ IMPLEMENTATION spider { TRUE { ENUM [ serial, + ethernet, + lwip, can ] LIBRARY[]; }, @@ -61,6 +63,24 @@ CPU spider { PATH = "drivers/serial/renesas"; }; + LIBRARY ethernet { + GLOBAL = TRUE; + PATH = "drivers/ethernet/renesas"; + NEEDS = serial; + }; + + LIBRARY lwip_port_renesas_spider { + GLOBAL = TRUE; + NEEDS = ethernet; + PATH = "drivers/lwip_port/renesas"; + }; + + LIBRARY lwip { + GLOBAL = TRUE; + NEEDS = lwip_port_renesas_spider; + PATH = "net/ethernet/lwip"; + }; + LIBRARY net_can_renesas_spider_driver { GLOBAL = TRUE; PATH = "drivers/can/renesas"; diff --git a/goil/templates/libraries/drivers/ethernet/renesas/config.oil b/goil/templates/libraries/drivers/ethernet/renesas/config.oil new file mode 100644 index 000000000..0a48f8d43 --- /dev/null +++ b/goil/templates/libraries/drivers/ethernet/renesas/config.oil @@ -0,0 +1,10 @@ +CPU drivers_ethernet_renesas_spider_files { + LIBRARY ethernet { + PATH = "drivers/ethernet/renesas"; + + CFILE = "utils.c"; + CFILE = "rswitch.c"; + CFILE = "eth_serdes.c"; + CFILE = "eth_gptp.c"; + }; +}; diff --git a/goil/templates/libraries/drivers/lwip_port/renesas/config.oil b/goil/templates/libraries/drivers/lwip_port/renesas/config.oil new file mode 100644 index 000000000..22353bf51 --- /dev/null +++ b/goil/templates/libraries/drivers/lwip_port/renesas/config.oil @@ -0,0 +1,7 @@ +CPU drivers_lwip_port_renesas_spider_files { + LIBRARY lwip_port_renesas_spider { + PATH = "drivers/lwip_port/renesas"; + CFILE = "sys_arch.c"; + CFILE = "ethif.c"; + }; +}; diff --git a/goil/templates/libraries/net/ethernet/lwip/config.oil b/goil/templates/libraries/net/ethernet/lwip/config.oil new file mode 100755 index 000000000..94e6161bf --- /dev/null +++ b/goil/templates/libraries/net/ethernet/lwip/config.oil @@ -0,0 +1,55 @@ +CPU net_ethernet_lwip_files { + LIBRARY lwip { + PATH = "net/ethernet/lwip/src/include"; + + // The minimum set of files needed for lwIP. + CFILE = "../core/init.c"; + CFILE = "../core/def.c"; + CFILE = "../core/dns.c"; + CFILE = "../core/inet_chksum.c"; + CFILE = "../core/ip.c"; + CFILE = "../core/mem.c"; + CFILE = "../core/memp.c"; + CFILE = "../core/netif.c"; + CFILE = "../core/pbuf.c"; + CFILE = "../core/raw.c"; + CFILE = "../core/stats.c"; + CFILE = "../core/sys.c"; + CFILE = "../core/altcp.c"; + CFILE = "../core/altcp_alloc.c"; + CFILE = "../core/altcp_tcp.c"; + CFILE = "../core/tcp.c"; + CFILE = "../core/tcp_in.c"; + CFILE = "../core/tcp_out.c"; + CFILE = "../core/timeouts.c"; + CFILE = "../core/udp.c"; + + // lwipcore4 + CFILE = "../core/ipv4/acd.c"; + CFILE = "../core/ipv4/autoip.c"; + CFILE = "../core/ipv4/dhcp.c"; + CFILE = "../core/ipv4/etharp.c"; + CFILE = "../core/ipv4/icmp.c"; + CFILE = "../core/ipv4/igmp.c"; + CFILE = "../core/ipv4/ip4_frag.c"; + CFILE = "../core/ipv4/ip4.c"; + CFILE = "../core/ipv4/ip4_addr.c"; + + // APIFILES: The files which implement the sequential and socket APIs. + CFILE = "../api/api_lib.c"; + CFILE = "../api/api_msg.c"; + CFILE = "../api/err.c"; + //CFILE = "../api/if_api.c"; + CFILE = "../api/netbuf.c"; + CFILE = "../api/netdb.c"; + CFILE = "../api/netifapi.c"; + //CFILE = "../api/sockets.c"; + CFILE = "../api/tcpip.c"; + + // Files implementing various generic network interface functions + CFILE = "../netif/ethernet.c"; + CFILE = "../netif/bridgeif.c"; + CFILE = "../netif/bridgeif_fdb.c"; + }; +}; + From 83e48b0350039d6d4da3f1cd7b06d08dc84851e0 Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 22 Sep 2023 11:29:41 +0200 Subject: [PATCH 18/24] spider: fix utils.h/printf.h files to use correct headers --- libraries/drivers/ethernet/renesas/utils.h | 4 ++-- libraries/drivers/serial/renesas/printf.h | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/libraries/drivers/ethernet/renesas/utils.h b/libraries/drivers/ethernet/renesas/utils.h index de0d73aa1..790177f6c 100644 --- a/libraries/drivers/ethernet/renesas/utils.h +++ b/libraries/drivers/ethernet/renesas/utils.h @@ -1,7 +1,7 @@ #ifndef _UTILS_H_ #define _UTILS_H_ -#include "../../../../../../machines/virt-v7/tpl_os_std_types.h" +#include "tpl_os_types.h" #include "printf.h" #define debug_msg(...) \ @@ -38,4 +38,4 @@ void ms_delay(uint32 value); void debug_print_buffer(uint8 *buf, uint32 len); -#endif /* _UTILS_H_ */ \ No newline at end of file +#endif /* _UTILS_H_ */ diff --git a/libraries/drivers/serial/renesas/printf.h b/libraries/drivers/serial/renesas/printf.h index 783dda2e5..aea99a835 100644 --- a/libraries/drivers/serial/renesas/printf.h +++ b/libraries/drivers/serial/renesas/printf.h @@ -1,4 +1,7 @@ -#include "../../../../../../machines/virt-v7/tpl_os_std_types.h" +#ifndef __PRINTF_H__ +#define __PRINTF_H__ int debug_printf(const char *format, ...); -int debug_sprintf(char *out, const char *format, ...); \ No newline at end of file +int debug_sprintf(char *out, const char *format, ...); + +#endif From d5df422abff30057b849226191935e95f91f6a0a Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 22 Sep 2023 11:30:29 +0200 Subject: [PATCH 19/24] spider: fix ms_delay() function --- libraries/drivers/ethernet/renesas/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/drivers/ethernet/renesas/utils.c b/libraries/drivers/ethernet/renesas/utils.c index b223bc7bd..c3941441d 100644 --- a/libraries/drivers/ethernet/renesas/utils.c +++ b/libraries/drivers/ethernet/renesas/utils.c @@ -86,7 +86,7 @@ void ms_delay(uint32 value) { uint32 start_time = get_time(); - while((get_elapsed_time(start_time) - start_time) < value); + while(get_elapsed_time(start_time) < value); } void port_init(void) From dd25bb104aa9ee007141908d955d8103b238a9a8 Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 22 Sep 2023 11:33:15 +0200 Subject: [PATCH 20/24] spider: update 'rswitch.c' to manage ISR outside of ISR() context. --- libraries/drivers/ethernet/renesas/rswitch.c | 122 +++++++++++-------- 1 file changed, 68 insertions(+), 54 deletions(-) diff --git a/libraries/drivers/ethernet/renesas/rswitch.c b/libraries/drivers/ethernet/renesas/rswitch.c index 086972d58..d8be1aec2 100644 --- a/libraries/drivers/ethernet/renesas/rswitch.c +++ b/libraries/drivers/ethernet/renesas/rswitch.c @@ -906,9 +906,16 @@ static void rswitch_get_interrupt_source_and_clear() #define APP_ISR_gwca1_rx_tx_int_START_SEC_CODE #include "tpl_memmap.h" +static int nb_int = 0; ISR(gwca1_rx_tx_int) { + nb_int++; + ActivateTask(gwca1_rx_tx_task); + CallTerminateISR2(); +} + +TASK(gwca1_rx_tx_task) { struct rswitch_gwca_chain *chain; struct rswitch_ext_ts_desc *ts_desc; struct rswitch_ext_desc *desc; @@ -917,64 +924,71 @@ ISR(gwca1_rx_tx_int) int i; // debug_msg("%s", __func__); - - chain = &rsw_dev.gwca->rx_chain; - if (chain->irq_triggered != 0) { - /* Go through the descriptors chain to parse received data */ - while (1) { - ts_desc = &(chain->ts_ring[chain->next_index]); - /* Stop once we get to a descriptor that was not modified */ - if (ts_desc->die_dt == (DT_FEMPTY | DIE)) { - break; - } - /* We know that "dptrh" is always 0x0 so we ignore it intentionally */ - data_ptr = (uint8 *) ts_desc->dptrl; - data_len = (ts_desc->info_ds) & 0xFFF; - /* If the callback is present then call it, otherwise just print - * the data */ - if (rx_cb != NULL) { - rx_cb(data_ptr, data_len); - } else { - debug_print_buffer(data_ptr, data_len); - } - /* Reset the data buffer */ - memset(data_ptr, 0, PKT_BUF_SZ_ALIGN); - /* Reset the descriptor so that it can be used again in the next round */ - memset(ts_desc, 0, sizeof(*ts_desc)); - ts_desc->die_dt = (DT_FEMPTY | DIE); - ts_desc->info_ds = PKT_BUF_SZ; - ts_desc->dptrl = (uint32) data_ptr; - /* Move to the next item in the list. */ - chain->next_index++; - /* The last item is a LINKFIX and we know that, so we wrap back - * to the 1st item earlier. */ - if (chain->next_index >= chain->num_ring - 1) { - chain->next_index = 0; + while(1) { + chain = &rsw_dev.gwca->rx_chain; + if (chain->irq_triggered != 0) { + /* Go through the descriptors chain to parse received data */ + while (1) { + ts_desc = &(chain->ts_ring[chain->next_index]); + /* Stop once we get to a descriptor that was not modified */ + if (ts_desc->die_dt == (DT_FEMPTY | DIE)) { + break; + } + /* We know that "dptrh" is always 0x0 so we ignore it intentionally */ + data_ptr = (uint8 *) ts_desc->dptrl; + data_len = (ts_desc->info_ds) & 0xFFF; + /* If the callback is present then call it, otherwise just print + * the data */ + if (rx_cb != NULL) { + rx_cb(data_ptr, data_len); + } else { + debug_print_buffer(data_ptr, data_len); + } + /* Reset the data buffer */ + memset(data_ptr, 0, PKT_BUF_SZ_ALIGN); + /* Reset the descriptor so that it can be used again in the next round */ + memset(ts_desc, 0, sizeof(*ts_desc)); + ts_desc->die_dt = (DT_FEMPTY | DIE); + ts_desc->info_ds = PKT_BUF_SZ; + ts_desc->dptrl = (uint32) data_ptr; + /* Move to the next item in the list. */ + chain->next_index++; + /* The last item is a LINKFIX and we know that, so we wrap back + * to the 1st item earlier. */ + if (chain->next_index >= chain->num_ring - 1) { + chain->next_index = 0; + } } + /* Remove the flag for the received data. + * Note = this is not the best technique because another IRQ might + * be triggered in the meanwhile (is it possible?) so we might + * miss it. Might be improved if problems appear... */ + chain->irq_triggered = 0; } - /* Remove the flag for the received data. - * Note = this is not the best technique because another IRQ might - * be triggered in the meanwhile (is it possible?) so we might - * miss it. Might be improved if problems appear... */ - chain->irq_triggered = 0; - } - chain = &rsw_dev.gwca->tx_chain; - if (chain->irq_triggered) { - /* Here we reset all the descriptors and data buffers of the TX chain. - * It works only if 1 descriptor is transmitted at a time. - * TODO: improve to handle transmissions of multiple descriptors. */ - for (i = 0; i < chain->num_ring - 1; i++) { - desc = &(chain->ring[i]); - desc->die_dt = DT_EEMPTY | DIE; - desc->info_ds = 0; - desc->info1 = 0; - data_ptr = (uint8 *) desc->dptrl; - memset(data_ptr, 0, PKT_BUF_SZ_ALIGN); + chain = &rsw_dev.gwca->tx_chain; + if (chain->irq_triggered) { + /* Here we reset all the descriptors and data buffers of the TX chain. + * It works only if 1 descriptor is transmitted at a time. + * TODO: improve to handle transmissions of multiple descriptors. */ + for (i = 0; i < chain->num_ring - 1; i++) { + desc = &(chain->ring[i]); + desc->die_dt = DT_EEMPTY | DIE; + desc->info_ds = 0; + desc->info1 = 0; + data_ptr = (uint8 *) desc->dptrl; + memset(data_ptr, 0, PKT_BUF_SZ_ALIGN); + } + chain->irq_triggered = 0; } - chain->irq_triggered = 0; + + DisableAllInterrupts(); + nb_int--; + if (nb_int==0) break; + EnableAllInterrupts(); } - CallTerminateISR2(); + + TerminateTask(); } FUNC(void, OS_CODE) GWCA1_RX_TX_INT_ClearFlag(void) @@ -1064,4 +1078,4 @@ FUNC(void, OS_CODE) ETHA0_ERR_INT_ClearFlag(void) } #define APP_ISR_etha0_err_int_STOP_SEC_CODE -#include "tpl_memmap.h" \ No newline at end of file +#include "tpl_memmap.h" From 0cfa5d5e3cd2c85e1cb5e04733c3b6e37b39e1f9 Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 22 Sep 2023 11:36:04 +0200 Subject: [PATCH 21/24] spider: update ethernet example to use 'lwip' Trampoline library --- .../cortex-a-r/armv8/spider/ethernet/eth.oil | 30 ++++++++++--------- .../cortex-a-r/armv8/spider/ethernet/main.c | 6 ++-- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil index 78f48bee6..59bb6e7a7 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/eth.oil +++ b/examples/cortex-a-r/armv8/spider/ethernet/eth.oil @@ -17,16 +17,9 @@ CPU eth { BUILD = TRUE { TRAMPOLINE_BASE_PATH = "../../../../.."; APP_SRC = "main.c"; - APP_SRC = "utils.c"; - APP_SRC = "eth_serdes.c"; - APP_SRC = "rswitch.c"; - APP_SRC = "eth_gptp.c"; - APP_SRC = "printf.c"; - APP_SRC = "lwip-port/sys_arch.c"; - APP_SRC = "lwip-port/ethif.c"; APP_NAME = "eth_exe.elf"; - CFLAGS = "-O0 -g -DHSCIF_1843200BPS -I. -Ilwip/src/include -Ilwip-port"; - LDFLAGS = "-Map=eth_exe.map -L. -llwipcore -llwipallapps"; + CFLAGS = "-O0 -g -DHSCIF_1843200BPS -DNO_SYS"; + LDFLAGS = "-Map=eth_exe.map"; COMPILER = "arm-none-eabi-gcc"; CPPCOMPILER = "arm-none-eabi-g++"; ASSEMBLER = "arm-none-eabi-as"; @@ -34,6 +27,7 @@ CPU eth { COPIER = "arm-none-eabi-objcopy"; SYSTEM = PYTHON; LIBRARY = serial; + LIBRARY = lwip; }; SYSTEM_CALL = TRUE; MEMMAP = TRUE { @@ -60,33 +54,41 @@ CPU eth { SCHEDULE = FULL; }; + /* ethernet driver needs */ + TASK gwca1_rx_tx_task { + PRIORITY = 2; + AUTOSTART = FALSE; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + ISR gwca1_rx_tx_int { CATEGORY = 2; - PRIORITY = 1; + PRIORITY = 2; SOURCE = GWCA1_RX_TX_INT; }; ISR gwca1_rx_ts_int { CATEGORY = 2; - PRIORITY = 2; + PRIORITY = 3; SOURCE = GWCA1_RX_TS_INT; }; ISR coma_err_int { CATEGORY = 2; - PRIORITY = 3; + PRIORITY = 4; SOURCE = COMA_ERR_INT; }; ISR gwca1_err_int { CATEGORY = 2; - PRIORITY = 4; + PRIORITY = 5; SOURCE = GWCA1_ERR_INT; }; ISR etha0_err_int { CATEGORY = 2; - PRIORITY = 5; + PRIORITY = 6; SOURCE = ETHA0_ERR_INT; }; }; diff --git a/examples/cortex-a-r/armv8/spider/ethernet/main.c b/examples/cortex-a-r/armv8/spider/ethernet/main.c index afb727ed6..ef475c145 100644 --- a/examples/cortex-a-r/armv8/spider/ethernet/main.c +++ b/examples/cortex-a-r/armv8/spider/ethernet/main.c @@ -1,11 +1,11 @@ #include "tpl_os.h" #include "utils.h" -#include "serial.h" +#include "spider_serial.h" #include "string.h" #include "lwip/netif.h" #include "lwip/ip4_addr.h" #include "lwip/timeouts.h" -#include "lwip-port/ethif.h" +#include "ethif.h" #define APP_Task_sample_init_START_SEC_CODE #include "tpl_memmap.h" @@ -55,4 +55,4 @@ TASK(monitor) { } #define APP_Task_sample_init_STOP_SEC_CODE -#include "tpl_memmap.h" \ No newline at end of file +#include "tpl_memmap.h" From 570ea985c27c8b2beee8316041d90af1e31522aa Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Fri, 22 Sep 2023 11:42:37 +0200 Subject: [PATCH 22/24] spider: add lwip support of Trampoline OS, without the needs to define NO_SYS=1 --- libraries/drivers/lwip_port/renesas/arch/cc.h | 10 +- .../drivers/lwip_port/renesas/arch/sys_arch.h | 42 ++ .../drivers/lwip_port/renesas/lwipopts.h | 27 +- .../drivers/lwip_port/renesas/sys_arch.c | 620 +++++++++++++++++- 4 files changed, 682 insertions(+), 17 deletions(-) create mode 100644 libraries/drivers/lwip_port/renesas/arch/sys_arch.h diff --git a/libraries/drivers/lwip_port/renesas/arch/cc.h b/libraries/drivers/lwip_port/renesas/arch/cc.h index 6a302695f..1692c833d 100644 --- a/libraries/drivers/lwip_port/renesas/arch/cc.h +++ b/libraries/drivers/lwip_port/renesas/arch/cc.h @@ -3,6 +3,11 @@ #include "utils.h" +// Hack to use our own 'atoi' function in order to prevent usage of libc one, because libc 'atoi' has many dependencies +#undef atoi +//unsigned int atoi(const unsigned char* s); +int atoi(const char *num); + #define LWIP_ERR_T int #define LWIP_PROVIDE_ERRNO @@ -15,6 +20,8 @@ #define S32_F "d" #define X32_F "x" +#define BYTE_ORDER LITTLE_ENDIAN + /* Compiler hints for packing structures */ #define PACK_STRUCT_FIELD(x) x #define PACK_STRUCT_STRUCT __attribute__((packed)) @@ -23,10 +30,11 @@ /* Plaform specific diagnostic output */ #define LWIP_PLATFORM_DIAG(x) do { \ - debug_msg x; \ + debug_msg x; \ } while (0) #define LWIP_PLATFORM_ASSERT(x) do { \ + while(1); \ } while (0) #endif /* __ARCH_CC_H__ */ diff --git a/libraries/drivers/lwip_port/renesas/arch/sys_arch.h b/libraries/drivers/lwip_port/renesas/arch/sys_arch.h new file mode 100644 index 000000000..686bc831b --- /dev/null +++ b/libraries/drivers/lwip_port/renesas/arch/sys_arch.h @@ -0,0 +1,42 @@ +#ifndef LWIP_ARCH_SYS_ARCH_H +#define LWIP_ARCH_SYS_ARCH_H + +#include "lwip/arch.h" + +#if !NO_SYS + +#define SYS_MBOX_NULL NULL +#define SYS_SEM_NULL NULL + +#define MAX_NB_MUTEX 100 +#define MAX_NB_SEM 40 +#define MAX_NB_MBOX 10 + +typedef u32_t sys_prot_t; + +struct sys_sem; +typedef struct sys_sem * sys_sem_t; +#define sys_sem_valid(sem) (((sem) != NULL) && (*(sem) != NULL)) +#define sys_sem_valid_val(sem) ((sem) != NULL) +#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; }}while(0) +#define sys_sem_set_invalid_val(sem) do { (sem) = NULL; }while(0) + +struct sys_mutex; +typedef struct sys_mutex * sys_mutex_t; +#define sys_mutex_valid(mutex) sys_sem_valid(mutex) +#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) + +struct sys_mbox; +typedef struct sys_mbox * sys_mbox_t; +#define sys_mbox_valid(mbox) sys_sem_valid(mbox) +#define sys_mbox_valid_val(mbox) sys_sem_valid_val(mbox) +#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox) +#define sys_mbox_set_invalid_val(mbox) sys_sem_set_invalid_val(mbox) + +struct sys_thread; +typedef struct sys_thread * sys_thread_t; + +#endif /* !NO_SYS */ + +#endif /* LWIP_ARCH_SYS_ARCH_H */ + diff --git a/libraries/drivers/lwip_port/renesas/lwipopts.h b/libraries/drivers/lwip_port/renesas/lwipopts.h index c47120535..582df0f84 100644 --- a/libraries/drivers/lwip_port/renesas/lwipopts.h +++ b/libraries/drivers/lwip_port/renesas/lwipopts.h @@ -1,13 +1,28 @@ -#define LWIP_DEBUG 1 +#if NO_SYS +#define SYS_LIGHTWEIGHT_PROT 0 +#define LWIP_SOCKET 0 +#else +#define SYS_LIGHTWEIGHT_PROT 1 +#define LWIP_SOCKET 1 +#endif + +#define LWIP_TCP 1 +#define LWIP_TCPIP_CORE_LOCKING 0 +#define LWIP_RAW 1 +#define SO_REUSE 1 + +#define TCPIP_MBOX_SIZE 5 +#define PBUF_POOL_SIZE 16 +#define MEMP_NUM_PBUF 30 + +//#define LWIP_DEBUG 1 + /* test an lwipopts.h file with default contents */ -#define NO_SYS 1 #define NO_SYS_NO_TIMERS 1 #define LWIP_TIMERS 1 #define LWIP_TIMERS_CUSTOM 0 #define LWIP_MPU_COMPATIBLE 0 -#define LWIP_TCPIP_CORE_LOCKING 1 #define LWIP_TCPIP_CORE_LOCKING_INPUT 0 -#define SYS_LIGHTWEIGHT_PROT 0 #define MEM_LIBC_MALLOC 0 #define MEMP_MEM_MALLOC 0 #define MEMP_MEM_INIT 0 @@ -70,7 +85,6 @@ #define ICMP_TTL (IP_DEFAULT_TTL) #define LWIP_BROADCAST_PING 0 #define LWIP_MULTICAST_PING 0 -#define LWIP_RAW 0 #define RAW_TTL (IP_DEFAULT_TTL) #define LWIP_DHCP 1 #define LWIP_DHCP_CHECK_LINK_UP 0 @@ -98,7 +112,6 @@ #define LWIP_UDPLITE 0 #define UDP_TTL (IP_DEFAULT_TTL) #define LWIP_NETBUF_RECVINFO 0 -#define LWIP_TCP 0 #define TCP_TTL (IP_DEFAULT_TTL) #define TCP_WND (4 * TCP_MSS) #define TCP_MAXRTX 12 @@ -166,7 +179,6 @@ #define LWIP_TCPIP_TIMEOUT 0 #define LWIP_NETCONN_SEM_PER_THREAD 0 #define LWIP_NETCONN_FULLDUPLEX 0 -#define LWIP_SOCKET 0 #define LWIP_COMPAT_SOCKETS 1 /* 0..2 */ #define LWIP_POSIX_SOCKETS_IO_NAMES 1 #define LWIP_SOCKET_OFFSET 0 @@ -178,7 +190,6 @@ #define LWIP_SO_LINGER 0 #define RECV_BUFSIZE_DEFAULT INT_MAX #define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000 -#define SO_REUSE 0 #define SO_REUSE_RXTOALL 0 #define LWIP_FIONREAD_LINUXMODE 0 #define LWIP_SOCKET_SELECT 1 diff --git a/libraries/drivers/lwip_port/renesas/sys_arch.c b/libraries/drivers/lwip_port/renesas/sys_arch.c index 029a96e99..0fc1f27bc 100644 --- a/libraries/drivers/lwip_port/renesas/sys_arch.c +++ b/libraries/drivers/lwip_port/renesas/sys_arch.c @@ -1,9 +1,11 @@ #include "lwip/sys.h" +#include "arch/sys_arch.h" +#include "tpl_os.h" +#include -u32_t sys_now(void) -{ - return 0; -} +#define MS_PER_TICKS 10 +extern VAR(uint32, OS_VAR) tpl_time_counter; +extern CONST(tpl_proc_id, AUTOMATIC) INVALID_TASK; static int hexval(char c) { if (c >= '0' && c <= '9') @@ -17,14 +19,14 @@ static int hexval(char c) { /* This is needed because "netif.c" uses it and without this implementation * this would cause LIBC to be included and that's something we don't want. */ -unsigned int atoi(const unsigned char *num) { +int atoi(const char *num) { long value = 0; int neg = 0; if (num[0] == '0' && num[1] == 'x') { // hex num += 2; - while (*num && isxdigit(*num)) + while (*num && isxdigit((unsigned char) *num)) value = value * 16 + hexval(*num++); } else { // decimal @@ -32,10 +34,612 @@ unsigned int atoi(const unsigned char *num) { neg = 1; num++; } - while (*num && isdigit(*num)) + while (*num && *num >= '0' && *num <= '9') value = value * 10 + *num++ - '0'; } if (neg) value = -value; return value; -} \ No newline at end of file +} + +#if !NO_SYS + +struct sys_mbox_msg { + struct sys_mbox_msg *next; + void *msg; +}; + +#define SYS_MBOX_SIZE 128 + +struct sys_mbox { + int used; + int first, last; + void *msgs[SYS_MBOX_SIZE]; + struct sys_sem *not_empty; + struct sys_sem *not_full; + struct sys_sem *mutex; + int wait_send; +}; + +struct sys_mbox sys_mbox_list[MAX_NB_MBOX]; + +#define UNLOCKED 0 +#define LOCKED 1 + +int waiting_task[TASK_COUNT]; + +struct sys_mutex { + int used; + int locked; +}; + +struct sys_mutex sys_mutex_list[MAX_NB_MUTEX]; + +struct sys_sem { + int used; + unsigned int c; + struct sys_mutex * mutex; +}; + +struct sys_sem sys_sem_list[MAX_NB_SEM]; + + +struct sys_thread { + int dummy; +}; + +static struct sys_sem *sys_sem_new_internal(u8_t count); + +/* Threads */ +int debug_printf(const char *format, ...); + +lwip_thread_fn threadPtr = NULL; + +TASK(tcpip_task) { + threadPtr(NULL); + TerminateTask(); +} + +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio) +{ + if(!strcmp(TCPIP_THREAD_NAME,name)) { + threadPtr = function; + ActivateTask(tcpip_task); + } else { + debug_printf("Task %s was not defined\n\r", name); + } + + return NULL; + } + +#if LWIP_TCPIP_CORE_LOCKING +TaskType lwip_core_lock_holder_task_id; +extern sys_mutex_t lock_tcpip_core; + +void sys_lock_tcpip_core(void) +{ + sys_mutex_lock(&lock_tcpip_core); + GetTaskID(&lwip_core_lock_holder_task_id); +} + +void sys_unlock_tcpip_core(void) +{ + lwip_core_lock_holder_task_id = INVALID_TASK; + sys_mutex_unlock(&lock_tcpip_core); +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +TaskType lwip_tcpip_task_id; +void sys_mark_tcpip_thread(void) +{ + GetTaskID(&lwip_tcpip_task_id); +} + +void sys_check_core_locking(void) +{ + /* Embedded systems should check we are NOT in an interrupt context here */ + + if (lwip_tcpip_task_id != INVALID_TASK) { + TaskType current_task_id; + GetTaskID(¤t_task_id); + +#if LWIP_TCPIP_CORE_LOCKING + LWIP_ASSERT("Function called without core lock", current_task_id == lwip_core_lock_holder_task_id); +#else /* LWIP_TCPIP_CORE_LOCKING */ +// LWIP_ASSERT("Function called from wrong task", current_task_id == lwip_tcpip_task_id); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + } +} + +/*-----------------------------------------------------------------------------------*/ +/* Mailbox */ +err_t sys_mbox_new(struct sys_mbox **mb, int size) +{ + int i; + LWIP_ASSERT("mbox != NULL", mb != NULL); + LWIP_ASSERT("size > 0", size > 0); + + if (size > SYS_MBOX_SIZE) { + return ERR_MEM; + } + + for(i=0; i< MAX_NB_MBOX; i++) { + if(!sys_mbox_list[i].used) { + break; + } + } + + if(i == MAX_NB_MBOX) { + LWIP_PLATFORM_DIAG(("no more available mbox")); + return ERR_MEM; + } + + sys_mbox_list[i].used = 1; + sys_mbox_list[i].first = sys_mbox_list[i].last = 0; + sys_mbox_list[i].not_empty = sys_sem_new_internal(0); + sys_mbox_list[i].not_full = sys_sem_new_internal(0); + sys_mbox_list[i].mutex = sys_sem_new_internal(1); + sys_mbox_list[i].wait_send = 0; + + //SYS_STATS_INC_USED(mbox); + *mb = &sys_mbox_list[i]; + return ERR_OK; +} + +void sys_mbox_free(struct sys_mbox **mb) +{ + LWIP_ASSERT("mbox != NULL", mb != NULL); + LWIP_ASSERT("*mbox != SYS_MBOX_NULL", *mb != SYS_MBOX_NULL); + + struct sys_mbox *mbox = *mb; + //SYS_STATS_DEC(mbox); + sys_arch_sem_wait(&mbox->mutex, 0); + + sys_sem_free(&mbox->not_empty); + sys_sem_free(&mbox->not_full); + sys_sem_free(&mbox->mutex); + mbox->not_empty = mbox->not_full = mbox->mutex = NULL; + + mbox->used = 0; +} + +err_t +sys_mbox_trypost(struct sys_mbox **mb, void *msg) +{ + u8_t first; + struct sys_mbox *mbox; + LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL)); + mbox = *mb; + + sys_arch_sem_wait(&mbox->mutex, 0); + + LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n", + (void *)mbox, (void *)msg)); + + if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) { + sys_sem_signal(&mbox->mutex); + return ERR_MEM; + } + + mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg; + + if (mbox->last == mbox->first) { + first = 1; + } else { + first = 0; + } + + mbox->last++; + + if (first) { + sys_sem_signal(&mbox->not_empty); + } + + sys_sem_signal(&mbox->mutex); + + return ERR_OK; +} + +err_t +sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg) +{ + return sys_mbox_trypost(q, msg); +} + +void sys_mbox_post(struct sys_mbox **mb, void *msg) +{ + u8_t first; + struct sys_mbox *mbox; + LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL)); + mbox = *mb; + + sys_arch_sem_wait(&mbox->mutex, 0); + + LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg)); + + while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) { + mbox->wait_send++; + sys_sem_signal(&mbox->mutex); + sys_arch_sem_wait(&mbox->not_full, 0); + sys_arch_sem_wait(&mbox->mutex, 0); + mbox->wait_send--; + } + + mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg; + + if (mbox->last == mbox->first) { + first = 1; + } else { + first = 0; + } + + mbox->last++; + + if (first) { + sys_sem_signal(&mbox->not_empty); + } + + sys_sem_signal(&mbox->mutex); +} + +u32_t sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg) +{ + struct sys_mbox *mbox; + LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL)); + mbox = *mb; + + sys_arch_sem_wait(&mbox->mutex, 0); + + if (mbox->first == mbox->last) { + sys_sem_signal(&mbox->mutex); + return SYS_MBOX_EMPTY; + } + + if (msg != NULL) { + LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg)); + *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE]; + } + else{ + LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox)); + } + + mbox->first++; + + if (mbox->wait_send) { + sys_sem_signal(&mbox->not_full); + } + + sys_sem_signal(&mbox->mutex); + + return 0; +} + +u32_t sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout) +{ + u32_t time_needed = 0; + struct sys_mbox *mbox; + LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL)); + mbox = *mb; + + /* The mutex lock is quick so we don't bother with the timeout + stuff here. */ + sys_arch_sem_wait(&mbox->mutex, 0); + + while (mbox->first == mbox->last) { + sys_sem_signal(&mbox->mutex); + + /* We block while waiting for a mail to arrive in the mailbox. We + must be prepared to timeout. */ + if (timeout != 0) { + time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout); + + if (time_needed == SYS_ARCH_TIMEOUT) { + return SYS_ARCH_TIMEOUT; + } + } else { + sys_arch_sem_wait(&mbox->not_empty, 0); + } + + sys_arch_sem_wait(&mbox->mutex, 0); + } + + if (msg != NULL) { + LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg)); + *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE]; + } + else{ + LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox)); + } + + mbox->first++; + + if (mbox->wait_send) { + sys_sem_signal(&mbox->not_full); + } + + sys_sem_signal(&mbox->mutex); + + return time_needed; +} + +/* + * Don't use tpl_disable_all_interrupts_service() and + * tpl_enable_all_interrupts_service() because several + * functions like 'GetTaskID()' can't be called while + * interrupt disabled + */ +void disable_interrupts() { + __asm__ volatile ("CPSID IF"); /* Disable interrupts */ + //DisableAllInterrupts(); +} + +void enable_interrupts() { + __asm__ volatile ("CPSIE IF"); /* Enable interrupts */ + //EnableAllInterrupts(); +} + +void wait_synchro(void) { + TaskType curr_task; + GetTaskID(&curr_task); + LWIP_ASSERT("invalid task id", (curr_taskmutex); + + //SYS_STATS_DEC(sem); + sem->used = 0; +} + +void sys_sem_signal(sys_sem_t *s) +{ + struct sys_sem *sem; + LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL)); + sem = *s; + + sys_mutex_lock(&(sem->mutex)); + sem->c++; + + if (sem->c > 1) { + sem->c = 1; + } + + sys_mutex_unlock(&(sem->mutex)); +} + + +u32_t sys_arch_sem_wait(sys_sem_t *s, u32_t timeout_ms) +{ + u32_t time_needed = 0; + struct sys_sem *sem; + LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL)); + sem = *s; + + sys_mutex_lock(&(sem->mutex)); + if (timeout_ms > 0) { + u32_t star_ms = sys_now(); + while ((sem->c <= 0) && (sys_now() < star_ms + timeout_ms)) { + sys_mutex_unlock(&(sem->mutex)); + sys_schedule(); + sys_mutex_lock(&(sem->mutex)); + } + + if (sem->c <= 0) { + sys_mutex_unlock(&(sem->mutex)); + return SYS_ARCH_TIMEOUT; + } + } else { + while (sem->c <= 0) { + sys_mutex_unlock(&(sem->mutex)); + sys_schedule(); + sys_mutex_lock(&(sem->mutex)); + } + } + + sem->c--; + sys_mutex_unlock(&(sem->mutex)); + return (u32_t)time_needed; +} +/*-----------------------------------------------------------------------------------*/ +/* Mutex */ +/** Create a new mutex + * @param mutex pointer to the mutex to create + * @return a new mutex */ + +err_t +sys_mutex_new(struct sys_mutex **mutex) +{ + int i; + + disable_interrupts(); + + for(i=0; i< MAX_NB_MUTEX; i++) { + if(!sys_mutex_list[i].used) { + break; + } + } + + if(i == MAX_NB_MUTEX) { + LWIP_PLATFORM_DIAG(("no more available mutex")); + enable_interrupts(); + return ERR_MEM; + } + + sys_mutex_list[i].used = 1; + sys_mutex_list[i].locked = UNLOCKED; + + *mutex = &sys_mutex_list[i]; + + enable_interrupts(); + + return ERR_OK; +} + +/** Lock a mutex + * @param mutex the mutex to lock */ +void +sys_mutex_lock(struct sys_mutex **mutex) +{ + struct sys_mutex *mtx; + + disable_interrupts(); + mtx = *mutex; + + while(mtx->locked == LOCKED) { + enable_interrupts(); + + wait_synchro(); + + disable_interrupts(); + } + + mtx->locked = LOCKED; + + enable_interrupts(); +} + +/** Unlock a mutex + * @param mutex the mutex to unlock */ +void +sys_mutex_unlock(struct sys_mutex **mutex) +{ + struct sys_mutex *mtx; + + disable_interrupts(); + mtx = *mutex; + mtx->locked = UNLOCKED; + enable_interrupts(); + + wakeup_waiting_tasks(); +} + +/** Delete a mutex + * @param mutex the mutex to delete */ +void +sys_mutex_free(struct sys_mutex **mutex) +{ + struct sys_mutex *mtx; + + disable_interrupts(); + mtx = *mutex; + mtx->used = 0; + enable_interrupts(); +} + +#endif /* !NO_SYS */ + +/* Time */ +u32_t sys_now(void) { +#if !NO_SYS + return tpl_time_counter * MS_PER_TICKS; +#else + return 0; +#endif +} + +/* Init */ +void sys_init(void) +{ +#if !NO_SYS + int i; + + for(i = 0; i < TASK_COUNT; i++) { + waiting_task[i] = 0; + } + + for(i = 0; i < MAX_NB_MUTEX; i++) { + sys_mutex_list[i].used = 0; + } + + for(i = 0; i < MAX_NB_SEM; i++) { + sys_sem_list[i].used = 0; + } + + for(i = 0; i < MAX_NB_MBOX; i++) { + sys_mbox_list[i].used = 0; + } +#endif /* !NO_SYS */ +} + +#if SYS_LIGHTWEIGHT_PROT + +sys_prot_t +sys_arch_protect(void) +{ + return 0; +} + +void +sys_arch_unprotect(sys_prot_t pval) +{ +} + +#endif /* SYS_LIGHTWEIGHT_PROT */ From 62d47e97c483445352731dba0bd30c1d56ffdcd4 Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Thu, 21 Sep 2023 17:30:45 +0200 Subject: [PATCH 23/24] spider: add lwip example with NO_SYS undefined --- .../cortex-a-r/armv8/spider/lwip/build.sh | 15 +++ examples/cortex-a-r/armv8/spider/lwip/lwip.c | 57 +++++++++ .../cortex-a-r/armv8/spider/lwip/lwip.oil | 108 ++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100755 examples/cortex-a-r/armv8/spider/lwip/build.sh create mode 100755 examples/cortex-a-r/armv8/spider/lwip/lwip.c create mode 100755 examples/cortex-a-r/armv8/spider/lwip/lwip.oil diff --git a/examples/cortex-a-r/armv8/spider/lwip/build.sh b/examples/cortex-a-r/armv8/spider/lwip/build.sh new file mode 100755 index 000000000..9d6672db6 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/lwip/build.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +#stop on errors +set -e + +if [[ ! -d "_build" ]] +then + mkdir _build +fi + +echo "*** Run Goil ***" +goil --target=cortex-a-r/armv8/spider --templates=../../../../../goil/templates/ lwip.oil + +echo "*** Run Make ***" +./make.py diff --git a/examples/cortex-a-r/armv8/spider/lwip/lwip.c b/examples/cortex-a-r/armv8/spider/lwip/lwip.c new file mode 100755 index 000000000..3d0ad3461 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/lwip/lwip.c @@ -0,0 +1,57 @@ +#include "tpl_os.h" + +#include "spider_serial.h" +#include "printf.h" +#include "utils.h" + +#include "ethif.h" + +/* lwIP core includes */ +#include "lwip/opt.h" +#include "lwip/dhcp.h" +#include "lwip/tcpip.h" + +struct netif this_netif; + +FUNC(int, OS_APPL_CODE) main(void) +{ + Serial_Init(); + StartOS(OSDEFAULTAPPMODE); + return 0; +} + +#define DHCP 0 + +TASK(lwip) +{ + debug_msg("init: call"); + struct netif this_netif; + ip4_addr_t ip4_addr, net_mask, gateway; + + debug_msg("init ethernet low level"); + rswitch_enable_clock_and_reset(); + port_init(); + + debug_msg("ethernet_init_inside_thread"); + tcpip_init(NULL,NULL); + + IP4_ADDR(&ip4_addr, 192, 168, 1, 2); + IP4_ADDR(&net_mask, 255, 255, 255, 0); + IP4_ADDR(&gateway, 192, 168, 1, 255); +#if DHCP==1 + netif_add( &this_netif, NULL, &net_mask, NULL, NULL, ethif_init, tcpip_input); +#else + netif_add( &this_netif, &ip4_addr, &net_mask, NULL, NULL, ethif_init, tcpip_input); +#endif + + netif_set_up(&this_netif); + +#if DHCP==1 + dhcp_start(&this_netif); +#endif + + debug_msg("init: done"); + + TerminateTask(); +} + diff --git a/examples/cortex-a-r/armv8/spider/lwip/lwip.oil b/examples/cortex-a-r/armv8/spider/lwip/lwip.oil new file mode 100755 index 000000000..fb66d29ab --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/lwip/lwip.oil @@ -0,0 +1,108 @@ +OIL_VERSION = "4.0"; + +IMPLEMENTATION trampoline { + + /* This fix the default STACKSIZE of tasks */ + TASK { + UINT32 STACKSIZE = 2000 ; + } ; + + /* This fix the default STACKSIZE of ISRs */ + ISR { + UINT32 STACKSIZE = 2000 ; + } ; +}; + +CPU lwip { + OS config { + STATUS = EXTENDED; + + BUILD = TRUE { + TRAMPOLINE_BASE_PATH = "../../../../.."; + APP_SRC = "lwip.c"; + + APP_NAME = "lwip_exe.elf"; + CFLAGS = "-O0 -DHSCIF_1843200BPS -ggdb"; + LDFLAGS = "-Map=lwip.map"; + COMPILER = "arm-none-eabi-gcc"; + CPPCOMPILER = "arm-none-eabi-g++"; + ASSEMBLER = "arm-none-eabi-as"; + LINKER = "arm-none-eabi-ld"; + COPIER = "arm-none-eabi-objcopy"; + SYSTEM = PYTHON; + + LIBRARY = serial; + LIBRARY = lwip; + }; + SYSTEM_CALL = TRUE; + MEMMAP = TRUE { + COMPILER = gcc; + LINKER = gnu_ld { SCRIPT = "script.ld"; }; + ASSEMBLER = gnu_as; + MEMORY_PROTECTION = FALSE; + }; + }; + + APPMODE std {}; + + TASK lwip { + PRIORITY = 1; + AUTOSTART = TRUE { APPMODE = std; }; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + /* LWIP needs */ + EVENT lwip_sync { + MASK = AUTO; + }; + + TASK tcpip_task { + PRIORITY = 1; + AUTOSTART = FALSE; + ACTIVATION = 1; + SCHEDULE = FULL; + EVENT = lwip_sync; + }; + + /* eth driver needs */ + TASK gwca1_rx_tx_task { + PRIORITY = 2; + AUTOSTART = FALSE; + ACTIVATION = 1; + SCHEDULE = FULL; + EVENT = lwip_sync; + }; + + ISR gwca1_rx_tx_int { + CATEGORY = 1; + PRIORITY = 3; + SOURCE = GWCA1_RX_TX_INT; + }; + + ISR gwca1_rx_ts_int { + CATEGORY = 1; + PRIORITY = 4; + SOURCE = GWCA1_RX_TS_INT; + }; + + ISR coma_err_int { + CATEGORY = 1; + PRIORITY = 5; + SOURCE = COMA_ERR_INT; + }; + + ISR gwca1_err_int { + CATEGORY = 1; + PRIORITY = 6; + SOURCE = GWCA1_ERR_INT; + }; + + ISR etha0_err_int { + CATEGORY = 1; + PRIORITY = 7; + SOURCE = ETHA0_ERR_INT; + }; + +}; + From 4d0063f67a573e4cb7c31315f1241bf31bbca9a5 Mon Sep 17 00:00:00 2001 From: Florian Sylvestre Date: Thu, 21 Sep 2023 17:46:07 +0200 Subject: [PATCH 24/24] spider: basic ethernet example (without lwip use) that answer to ping requests on every IP addresses --- .../armv8/spider/ethernet_basic/build.sh | 15 ++ .../armv8/spider/ethernet_basic/eth.oil | 93 +++++++++ .../armv8/spider/ethernet_basic/main.c | 182 ++++++++++++++++++ 3 files changed, 290 insertions(+) create mode 100755 examples/cortex-a-r/armv8/spider/ethernet_basic/build.sh create mode 100644 examples/cortex-a-r/armv8/spider/ethernet_basic/eth.oil create mode 100644 examples/cortex-a-r/armv8/spider/ethernet_basic/main.c diff --git a/examples/cortex-a-r/armv8/spider/ethernet_basic/build.sh b/examples/cortex-a-r/armv8/spider/ethernet_basic/build.sh new file mode 100755 index 000000000..cb0690389 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet_basic/build.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +#stop on errors +set -e + +if [[ ! -d "_build" ]] +then + mkdir _build +fi + +echo "*** Run Goil ***" +goil --target=cortex-a-r/armv8/spider --templates=../../../../../goil/templates/ eth.oil + +echo "*** Run Make ***" +./make.py diff --git a/examples/cortex-a-r/armv8/spider/ethernet_basic/eth.oil b/examples/cortex-a-r/armv8/spider/ethernet_basic/eth.oil new file mode 100644 index 000000000..51e4c81c5 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet_basic/eth.oil @@ -0,0 +1,93 @@ +OIL_VERSION = "4.0"; + +IMPLEMENTATION trampoline { + TASK { + UINT32 STACKSIZE = 2048 ; + } ; + + ISR { + UINT32 STACKSIZE = 2048 ; + } ; +}; + +CPU eth { + OS config { + STATUS = EXTENDED; + + BUILD = TRUE { + TRAMPOLINE_BASE_PATH = "../../../../.."; + APP_SRC = "main.c"; + APP_NAME = "eth_exe.elf"; + CFLAGS = "-O0 -g -DHSCIF_1843200BPS"; + LDFLAGS = "-Map=eth_exe.map"; + COMPILER = "arm-none-eabi-gcc"; + CPPCOMPILER = "arm-none-eabi-g++"; + ASSEMBLER = "arm-none-eabi-as"; + LINKER = "arm-none-eabi-ld"; + COPIER = "arm-none-eabi-objcopy"; + SYSTEM = PYTHON; + LIBRARY = serial; + LIBRARY = ethernet; + }; + SYSTEM_CALL = TRUE; + MEMMAP = TRUE { + COMPILER = gcc; + LINKER = gnu_ld { SCRIPT = "script.ld"; }; + ASSEMBLER = gnu_as; + MEMORY_PROTECTION = FALSE; + }; + }; + + APPMODE std {}; + + TASK sample_init { + PRIORITY = 1; + AUTOSTART = TRUE { APPMODE = std; }; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + TASK echo { + PRIORITY = 1; + AUTOSTART = FALSE; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + TASK gwca1_rx_tx_task { + PRIORITY = 2; + AUTOSTART = FALSE; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + ISR gwca1_rx_tx_int { + CATEGORY = 1; + PRIORITY = 3; + SOURCE = GWCA1_RX_TX_INT; + }; + + ISR gwca1_rx_ts_int { + CATEGORY = 1; + PRIORITY = 4; + SOURCE = GWCA1_RX_TS_INT; + }; + + ISR coma_err_int { + CATEGORY = 1; + PRIORITY = 5; + SOURCE = COMA_ERR_INT; + }; + + ISR gwca1_err_int { + CATEGORY = 1; + PRIORITY = 6; + SOURCE = GWCA1_ERR_INT; + }; + + ISR etha0_err_int { + CATEGORY = 1; + PRIORITY = 7; + SOURCE = ETHA0_ERR_INT; + }; +}; diff --git a/examples/cortex-a-r/armv8/spider/ethernet_basic/main.c b/examples/cortex-a-r/armv8/spider/ethernet_basic/main.c new file mode 100644 index 000000000..c49621955 --- /dev/null +++ b/examples/cortex-a-r/armv8/spider/ethernet_basic/main.c @@ -0,0 +1,182 @@ +#include "tpl_os.h" +#include "utils.h" +#include "eth_serdes.h" +#include "rswitch.h" +#include "eth_gptp.h" +#include "spider_serial.h" +#include "string.h" + +#define APP_Task_sample_init_START_SEC_CODE +#include "tpl_memmap.h" + +uint8 tmp_buffer[1600]; +uint16 tmp_buffer_len = 0; + +// Is this the right section for the main function?? +FUNC(int, OS_APPL_CODE) main(void) +{ + StartOS(OSDEFAULTAPPMODE); + return 0; +} + +void eth_callback(uint8 *data, uint16 len) +{ + /* Copy the data into the local buffer and then activate the Echo task */ + memcpy(tmp_buffer, data, len); + tmp_buffer_len = len; + ActivateTask(echo); +} + +TASK(sample_init) { + int ret; + + Serial_Init(); + + rswitch_enable_clock_and_reset(); + port_init(); + // Interrupt initializazion done by Trampoline + eth_disable_fuse_ovr(); + + ret = eth_serdes_initialize(); + if (ret != 0) { + debug_msg("Error in eth_serdes_initialize"); + goto exit; + } + debug_msg("SERDES initialization done"); + + ret = rswitch_init(); + if (ret != 0) { + debug_msg("Error in rswitch_init\n"); + goto exit; + } + debug_msg("RSwitch initialization done"); + + debug_msg("Initialize gPTP"); + eth_gptp_init(); + + ret = rswitch_open(); + if (ret != 0) { + debug_msg("Error in rswitch_open\n"); + goto exit; + } + debug_msg("RSwitch open completed"); + + rswitch_regiter_data_received_callback(eth_callback); + + debug_msg("Initialization completed"); +exit: + TerminateTask(); +} + +#define APP_Task_sample_init_STOP_SEC_CODE +#include "tpl_memmap.h" + +#define APP_Task_echo_START_SEC_CODE +#include "tpl_memmap.h" + +TASK(echo) +{ + int ret; + uint8 src_mac[6]; + uint8 dst_mac[6]; + +#if 0 /* set to 1 if debug logs are needed */ + debug_msg("## Echo task ##"); + debug_msg("Received:"); + debug_print_buffer(tmp_buffer, tmp_buffer_len); +#endif + + /* check if protocol = ARP */ + if ((tmp_buffer[12]==0x08)&&(tmp_buffer[13]==0x06)) { + /* Swap MAC addresses */ + memcpy(dst_mac, &tmp_buffer[6], 6); + memcpy(&tmp_buffer[0], dst_mac, 6); + /* Send our MAC address */ + tmp_buffer[6] = 0x2E; + tmp_buffer[7] = 0x09; + tmp_buffer[8] = 0x0A; + tmp_buffer[9] = 0x00; + tmp_buffer[10] = 0x00; + tmp_buffer[11] = 0x00; + + /* Swap MAC addresses */ + memcpy(src_mac, &tmp_buffer[22], 6); + memcpy(&tmp_buffer[32], src_mac, 6); + /* Send our MAC address */ + tmp_buffer[22] = 0x2E; + tmp_buffer[23] = 0x09; + tmp_buffer[24] = 0x0A; + tmp_buffer[25] = 0x00; + tmp_buffer[26] = 0x00; + tmp_buffer[27] = 0x00; + + /* Swap IP addresses */ + memcpy(src_mac, &tmp_buffer[28], 4); + memcpy(dst_mac, &tmp_buffer[38], 4); + memcpy(&tmp_buffer[28], dst_mac, 4); + memcpy(&tmp_buffer[38], src_mac, 4); + + /* Answer arp */ + tmp_buffer[21] = 2; + } + + /* Check if protocol = ICMP (ping) */ + if ((tmp_buffer[12]==0x08)&&(tmp_buffer[13]==0x00)&&(tmp_buffer[23]==0x01)) { + /* Switch mac addresses */ + memcpy(src_mac, &tmp_buffer[0], 6); + memcpy(dst_mac, &tmp_buffer[6], 6); + memcpy(&tmp_buffer[0], dst_mac, 6); + memcpy(&tmp_buffer[6], src_mac, 6); + + /* Switch IP addresses */ + memcpy(src_mac, &tmp_buffer[26], 4); + memcpy(dst_mac, &tmp_buffer[30], 4); + memcpy(&tmp_buffer[26], dst_mac, 4); + memcpy(&tmp_buffer[30], src_mac, 4); + + /***************************/ + /* Compute header checksum */ + /***************************/ + /* Clear checksum */ + tmp_buffer[24] = 0x0; + tmp_buffer[25] = 0x0; + /* Compute sum */ + uint32 checksum = 0x0; + for(uint8 i=0; i<10; i++) { + checksum += tmp_buffer[14+2*i] * 0x100; + checksum += tmp_buffer[15+2*i]; + } + /* Compute carry */ + while(checksum > 0xffff) { + checksum = (checksum & 0xffff) + (checksum >> 16); + } + /* Compute the ones' complement */ + checksum = 0xffff - checksum; + /* Update checksum field */ + tmp_buffer[24] = (checksum >> 8) & 0xff; + tmp_buffer[25] = checksum & 0xff; + + /* Answer ping */ + tmp_buffer[34] = 0; + + /* ICMP checksum */ + /* We only modify the ICMP type for 0x8 (ping request) to 0x0 (ping answer) */ + /* so, no need to compute the checksum, only need to add 8 to it */ + if(tmp_buffer[36]>=0xf8) tmp_buffer[37] = tmp_buffer[37]+1; + tmp_buffer[36] = tmp_buffer[36] + 8; + } + + ret = rswitch_send_data(tmp_buffer, tmp_buffer_len); + if (ret != 0) { + debug_msg("Send data back: FAILED"); + } + + /* Clear the data for the next iteration */ + memset(tmp_buffer, 0, sizeof(tmp_buffer)); + tmp_buffer_len = 0; + + TerminateTask(); +} + +#define APP_Task_echo_STOP_SEC_CODE +#include "tpl_memmap.h" \ No newline at end of file