From 65c2336313efa39f702ab57d30f5ec9bbf64a162 Mon Sep 17 00:00:00 2001 From: logicog Date: Sat, 5 Jul 2025 09:24:16 +0200 Subject: [PATCH] Use external command parser module. Add support for mirroring --- Makefile | 2 +- rtl837x_common.h | 4 + rtl837x_port.c | 14 +++- rtl837x_port.h | 2 + rtlplayground.c | 206 +---------------------------------------------- 5 files changed, 22 insertions(+), 206 deletions(-) diff --git a/Makefile b/Makefile index 43f18de..7b5c29d 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ AFLAGS= -plosgff all: rtlplayground.bin injector -SRCS= rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c +SRCS= rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c OBJS= ${SRCS:.c=.rel} clean: diff --git a/rtl837x_common.h b/rtl837x_common.h index a60d457..ea99922 100644 --- a/rtl837x_common.h +++ b/rtl837x_common.h @@ -3,7 +3,10 @@ // Headers for calls in the common code area (HOME/BANK0) +#define SBUF_SIZE 256 + void print_string(__code char *p); +void print_long(uint32_t a); void print_short(uint16_t a); void print_byte(uint8_t a); void print_sfr_data(void); @@ -21,5 +24,6 @@ void print_reg(uint16_t reg); uint8_t sfp_read_reg(uint8_t reg); void reg_bit_set(uint16_t reg_addr, char bit); void reg_bit_clear(uint16_t reg_addr, char bit); +void reset_chip(void); #endif diff --git a/rtl837x_port.c b/rtl837x_port.c index 87bfc51..b5d4958 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -47,9 +47,19 @@ __xdata uint32_t l2_head; #define RTL837x_PVID_BASE_REG 0x4e1c -void port_mirror(uint8_t port, uint16_t source_mask, uint8_t directions) __banked +void port_mirror_set(uint8_t port, uint16_t rx_pmask, uint16_t tx_pmask) __banked { - print_string("\r\nport_mirror called \r\n"); + print_string("\r\nport_mirror_set called \r\n"); + + REG_WRITE(0x604c, rx_pmask >> 8, rx_pmask, tx_pmask >> 8, tx_pmask); + REG_WRITE(0x6048, 0, 0, 0, (port << 1) | 0x1); +} + + +void port_mirror_del() +{ + print_string("\r\nport_mirror_del called \r\n"); + REG_SET(0x6048, 0); } diff --git a/rtl837x_port.h b/rtl837x_port.h index 8cbfc8e..04184b2 100644 --- a/rtl837x_port.h +++ b/rtl837x_port.h @@ -8,4 +8,6 @@ void vlan_setup(void) __banked; void port_pvid_set(uint8_t port, uint16_t pvid) __banked; void vlan_create(uint16_t vlan, uint16_t members, uint16_t tagged) __banked; void vlan_delete(uint16_t vlan) __banked; +void port_mirror_set(uint8_t port, uint16_t rx_pmask, uint16_t tx_pmask) __banked; + #endif diff --git a/rtlplayground.c b/rtlplayground.c index d48272d..1bc7947 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -10,6 +10,7 @@ #include "rtl837x_flash.h" #include "rtl837x_phy.h" #include "rtl837x_port.h" +#include "cmd_parser.h" #define SYS_TICK_HZ 100 #define SERIAL_BAUD_RATE 115200 @@ -47,11 +48,7 @@ volatile __xdata uint32_t ticks; volatile __xdata uint8_t sec_counter; volatile __xdata uint16_t sleep_ticks; -#define N_WORDS 16 -__xdata signed char cmd_words_b[N_WORDS]; - // Buffer for serial input, SBUF_SIZE must be power of 2 < 256 -#define SBUF_SIZE 32 __xdata char sbuf_ptr; __xdata uint8_t sbuf[SBUF_SIZE]; __xdata uint8_t sfr_data[4]; @@ -1497,26 +1494,6 @@ void setup_serial(void) } -uint8_t cmd_compare(uint8_t start, uint8_t * __code cmd) -{ - signed char i; - signed char j = 0; - - for (i = cmd_words_b[start]; i < cmd_words_b[start + 1] && sbuf[i] != ' '; i++) { -// print_short(i); write_char(':'); print_short(j); write_char('#'); print_string("\r\n"); -// write_char('>'); write_char(cmd[j]); write_char('-'); write_char(sbuf[i]); print_string("\r\n"); - if (!cmd[j]) - return 1; - if (sbuf[i] != cmd[j++]) - break; - } -// write_char('.'); print_short(i); write_char(':'); print_short(i); - if (i >= cmd_words_b[start + 1] || sbuf[i] == ' ') - return 1; - return 0; -} - - void setup_i2c(void) { REG_SET(0x0414, 0); @@ -1531,21 +1508,6 @@ void setup_i2c(void) } -uint8_t atoi_short(uint16_t *vlan, uint8_t idx) -{ - uint8_t err = 1; - *vlan = 0; - - while (sbuf[idx] >= '0' && sbuf[idx] <= '9') { - err = 0; - *vlan = (*vlan * 10) + sbuf[idx] - '0'; - idx++; - } - return err; -} - - - void bootloader(void) { ticks = 0; @@ -1636,171 +1598,9 @@ void bootloader(void) port_stats_print(); print_string("\r\n> "); - char l = sbuf_ptr; - char line_ptr = l; - char is_white = 1; + cmd_parser_setup(); while (1) { - while (l != sbuf_ptr) { - write_char(sbuf[l]); - // Check whether there is a full line: - if (sbuf[l] == '\n' || sbuf[l] == '\r') { -#ifdef DEBUG - print_long(ticks); -#endif - // Print line and parse command into words - is_white = 1; - uint8_t word = 0; - cmd_words_b[0] = -1; - while (line_ptr != l) { - if (is_white && sbuf[line_ptr] != ' ') { - is_white = 0; - cmd_words_b[word++] = line_ptr; - } - if (sbuf[line_ptr] == ' ') - is_white = 1; - write_char(sbuf[line_ptr++]); - line_ptr &= SBUF_SIZE - 1; - if (word >= N_WORDS - 1) { - print_string("\r\ntoo many arguments, truncated"); - line_ptr = l; // BUG: We should probably ignore the command - break; - } - } - cmd_words_b[word++] = line_ptr; - cmd_words_b[word++] = -1; - line_ptr = (l + 1) & (SBUF_SIZE - 1); - - // Identify command - signed char i = cmd_words_b[0]; - if (i >= 0 && cmd_words_b[1] >= 0) { -/* print_string("\r\n THERE may be a command: "); - print_short(i); print_string("\r\n"); - print_short(cmd_words_b[0]); print_string("\r\n"); - print_short(cmd_words_b[1]); print_string("\r\n"); - print_short(cmd_words_b[2]); print_string("\r\n"); - print_short(cmd_words_b[3]); print_string("\r\n"); -*/ - if (cmd_compare(0, "reset")) { - print_string("\r\nRESET\n\n"); - reset_chip(); - } - if (cmd_compare(0, "sfp")) { - uint8_t rate = sfp_read_reg(12); - print_string("\r\nRate: "); print_byte(rate); - print_string(" Encoding: "); print_byte(sfp_read_reg(11)); - print_string("\r\n"); - for (uint8_t i = 20; i < 60; i++) { - uint8_t c = sfp_read_reg(i); - if (c) - write_char(c); - } - } - if (cmd_compare(0, "stat")) { - port_stats_print(); - } - if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'r') { - print_string("\r\nPRINT SECURITY REGISTERS\r\n"); - // The following will only show something else then 0xff if it was programmed for a managed switch - flash_read_security(0x0001000, 40); - flash_read_security(0x0002000, 40); - flash_read_security(0x0003000, 40); - } - if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'd') { - print_string("\r\nDUMPING FLASH\r\n"); - flash_dump(0, 255); - } - if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'j') { - print_string("\r\nJEDEC ID\r\n"); - flash_read_jedecid(); - } - if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'u') { - print_string("\r\nUNIQUE ID\r\n"); - flash_read_uid(); - } - // Switch to flash 62.5 MHz mode - if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 's') { - print_string("\r\nFLASH FAST MODE\r\n"); - flash_init(1); - print_string("\r\nNow dumping flash\r\n"); - flash_dump(0, 255); - } - if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'e') { - print_string("\r\nFLASH erase\r\n"); - flash_block_erase(0x20000); - } - if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && sbuf[cmd_words_b[1]] == 'w') { - print_string("\r\nFLASH write\r\n"); - for (uint8_t i = 0; i < 20; i++) - flash_buf[i] = greeting[i]; - flash_write_bytes(0x20000, flash_buf, 20); - } - if (cmd_compare(0, "port") && cmd_words_b[1] > 0) { - print_string("\r\nPORT "); - uint8_t p = sbuf[cmd_words_b[1]] - '1'; - print_byte(p); - if (cmd_words_b[2] > 0 && cmd_compare(2, "2g5")) { - print_string(" 2.5G\r\n"); - phy_set_mode(p, PHY_SPEED_2G5, 0, 0); - } - if (cmd_words_b[2] > 0 && cmd_compare(2, "1g")) { - print_string(" 1G\r\n"); - phy_set_mode(p, PHY_SPEED_1G, 0, 0); - } - if (cmd_words_b[2] > 0 && cmd_compare(2, "auto")) { - print_string(" AUTO\r\n"); - phy_set_mode(p, PHY_SPEED_AUTO, 0, 0); - } - if (cmd_words_b[2] > 0 && cmd_compare(2, "off")) { - print_string(" OFF\r\n"); - phy_set_mode(p, PHY_OFF, 0, 0); - } - } - if (cmd_compare(0, "l2")) { - port_l2_learned(); - } - if (cmd_compare(0, "pvid") && cmd_words_b[1] > 0 && cmd_words_b[2] > 0) { - __xdata uint16_t pvid; - uint8_t port; - port = sbuf[cmd_words_b[1]] - '0'; - if (!atoi_short(&pvid, cmd_words_b[2])) - port_pvid_set(port, pvid); - } - if (cmd_compare(0, "vlan")) { - __xdata uint16_t vlan; - __xdata uint16_t members = 0; - __xdata uint16_t tagged = 0; - if (!atoi_short(&vlan, cmd_words_b[1])) { - print_short(vlan); - if (cmd_words_b[2] > 0 && sbuf[cmd_words_b[2]] == 'd') { - vlan_delete(vlan); - } else { - uint8_t w = 2; - while (cmd_words_b[w] > 0) { - uint8_t port; - if (sbuf[cmd_words_b[w]] >= '0' && sbuf[cmd_words_b[w]] <= '9') { - port = sbuf[cmd_words_b[w]] - '1'; - if (sbuf[cmd_words_b[w] + 1] >= '0' && sbuf[cmd_words_b[w] + 1] <= '9') { - port = (port + 1) * 10 + sbuf[cmd_words_b[w] + 1] - '1'; - if (sbuf[cmd_words_b[w] + 2] == 't') - tagged |= ((uint16_t)1) << port; - } else { - if (sbuf[cmd_words_b[w] + 1] == 't') - tagged |= ((uint16_t)1) << port; - } - members |= ((uint16_t)1) << port; - } - w++; - } - vlan_create(vlan, members, tagged); - } - } - } - } - print_string("\r\n> "); - } - l++; - l &= (SBUF_SIZE - 1); - } + cmd_parser(); idle(); // Enter Idle mode until interrupt occurs } }