diff options
-rw-r--r-- | docs/platform/generic.md | 2 | ||||
-rw-r--r-- | docs/platform/platform.md | 5 | ||||
-rw-r--r-- | docs/platform/shakti_cclass.md | 33 | ||||
-rw-r--r-- | include/sbi_utils/fdt/fdt_helper.h | 3 | ||||
-rw-r--r-- | include/sbi_utils/serial/shakti-uart.h | 18 | ||||
-rw-r--r-- | lib/utils/fdt/fdt_helper.c | 37 | ||||
-rw-r--r-- | lib/utils/serial/fdt_serial.c | 2 | ||||
-rw-r--r-- | lib/utils/serial/fdt_serial_shakti.c | 35 | ||||
-rw-r--r-- | lib/utils/serial/objects.mk | 2 | ||||
-rw-r--r-- | lib/utils/serial/shakti-uart.c | 44 |
10 files changed, 181 insertions, 0 deletions
diff --git a/docs/platform/generic.md b/docs/platform/generic.md index 60916c7..f1f7f64 100644 --- a/docs/platform/generic.md +++ b/docs/platform/generic.md @@ -47,6 +47,8 @@ RISC-V Platforms Using Generic Platform * **QEMU RISC-V Virt Machine** (*[qemu_virt.md]*) * **Spike** (*[spike.md]*) +* **Shakti C-class SoC Platform** (*[shakti_cclass.md]*) [qemu_virt.md]: qemu_virt.md [spike.md]: spike.md +[shakti_cclass.md]: shakti_cclass.md diff --git a/docs/platform/platform.md b/docs/platform/platform.md index 3e0dc39..7f47068 100644 --- a/docs/platform/platform.md +++ b/docs/platform/platform.md @@ -38,6 +38,10 @@ OpenSBI currently supports the following virtual and hardware platforms: on ariane core. More details on this platform can be found in the file *[fpga_openpiton.md]*. +* **Shakti C-class SoC Platform**: Platform support for Shakti C-class + processor based SOCs. More details on this platform can be found in the + file *[shakti_cclass.md]*. + The code for these supported platforms can be used as example to implement support for other platforms. The *platform/template* directory also provides template files for implementing support for a new platform. The *object.mk*, @@ -52,3 +56,4 @@ facilitate the implementation. [thead-c910.md]: thead-c910.md [spike.md]: spike.md [fpga_openpiton.md]: fpga_openpiton.md +[shakti_cclass.md]: shakti_cclass.md diff --git a/docs/platform/shakti_cclass.md b/docs/platform/shakti_cclass.md new file mode 100644 index 0000000..2f4a699 --- /dev/null +++ b/docs/platform/shakti_cclass.md @@ -0,0 +1,33 @@ +Shakti C-class SoC Platform +=========================== +C-Class is a member of the SHAKTI family of processors from +Indian Institute of Technology - Madras (IIT-M). + +It is an extremely configurable and commercial-grade 5-stage +in-order core supporting the standard RV64GCSUN ISA extensions. + +For more details, refer: +* https://gitlab.com/shaktiproject/cores/c-class/blob/master/README.md +* https://c-class.readthedocs.io/en/latest +* https://shakti.org.in + +Platform Options +---------------- + +The *Shakti C-class SoC* platform does not have any platform-specific +options. + +Building Shakti C-class Platform +-------------------------------- + +**Linux Kernel Payload** + +``` +make PLATFORM=generic FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_PAYLOAD_FDT_PATH=<shakti.dtb path> +``` + +**Test Payload** + +``` +make PLATFORM=generic FW_PAYLOAD_FDT_PATH=<shakti.dtb path> +``` diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h index 1b780fb..f5222de 100644 --- a/include/sbi_utils/fdt/fdt_helper.h +++ b/include/sbi_utils/fdt/fdt_helper.h @@ -39,6 +39,9 @@ int fdt_parse_hart_id(void *fdt, int cpu_offset, u32 *hartid); int fdt_parse_max_hart_id(void *fdt, u32 *max_hartid); +int fdt_parse_shakti_uart_node(void *fdt, int nodeoffset, + struct platform_uart_data *uart); + int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset, struct platform_uart_data *uart); diff --git a/include/sbi_utils/serial/shakti-uart.h b/include/sbi_utils/serial/shakti-uart.h new file mode 100644 index 0000000..08043be --- /dev/null +++ b/include/sbi_utils/serial/shakti-uart.h @@ -0,0 +1,18 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Vijai Kumar K <vijai@behindbytes.com> + */ + +#ifndef __SERIAL_SHAKTI_UART_H__ +#define __SERIAL_SHAKTI_UART_H__ + +#include <sbi/sbi_types.h> + +void shakti_uart_putc(char ch); + +int shakti_uart_getc(void); + +int shakti_uart_init(unsigned long base, u32 in_freq, u32 baudrate); + +#endif diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c index 887d6ed..78077f7 100644 --- a/lib/utils/fdt/fdt_helper.c +++ b/lib/utils/fdt/fdt_helper.c @@ -26,6 +26,9 @@ #define DEFAULT_SIFIVE_UART_REG_SHIFT 0 #define DEFAULT_SIFIVE_UART_REG_IO_WIDTH 4 +#define DEFAULT_SHAKTI_UART_FREQ 50000000 +#define DEFAULT_SHAKTI_UART_BAUD 115200 + const struct fdt_match *fdt_match_node(void *fdt, int nodeoff, const struct fdt_match *match_table) { @@ -164,6 +167,40 @@ int fdt_parse_max_hart_id(void *fdt, u32 *max_hartid) return 0; } +int fdt_parse_shakti_uart_node(void *fdt, int nodeoffset, + struct platform_uart_data *uart) +{ + int len, rc; + const fdt32_t *val; + unsigned long reg_addr, reg_size; + + if (nodeoffset < 0 || !uart || !fdt) + return SBI_ENODEV; + + rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size); + if (rc < 0 || !reg_addr || !reg_size) + return SBI_ENODEV; + uart->addr = reg_addr; + + /** + * UART address is mandaotry. clock-frequency and current-speed + * may not be present. Don't return error. + */ + val = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "clock-frequency", &len); + if (len > 0 && val) + uart->freq = fdt32_to_cpu(*val); + else + uart->freq = DEFAULT_SHAKTI_UART_FREQ; + + val = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "current-speed", &len); + if (len > 0 && val) + uart->baud = fdt32_to_cpu(*val); + else + uart->baud = DEFAULT_SHAKTI_UART_BAUD; + + return 0; +} + int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset, struct platform_uart_data *uart) { diff --git a/lib/utils/serial/fdt_serial.c b/lib/utils/serial/fdt_serial.c index fa6c478..b9ce67e 100644 --- a/lib/utils/serial/fdt_serial.c +++ b/lib/utils/serial/fdt_serial.c @@ -15,11 +15,13 @@ extern struct fdt_serial fdt_serial_uart8250; extern struct fdt_serial fdt_serial_sifive; extern struct fdt_serial fdt_serial_htif; +extern struct fdt_serial fdt_serial_shakti; static struct fdt_serial *serial_drivers[] = { &fdt_serial_uart8250, &fdt_serial_sifive, &fdt_serial_htif, + &fdt_serial_shakti, }; static void dummy_putc(char ch) diff --git a/lib/utils/serial/fdt_serial_shakti.c b/lib/utils/serial/fdt_serial_shakti.c new file mode 100644 index 0000000..c6385a5 --- /dev/null +++ b/lib/utils/serial/fdt_serial_shakti.c @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Vijai Kumar K <vijai@behindbytes.com> + * + */ + +#include <sbi_utils/fdt/fdt_helper.h> +#include <sbi_utils/serial/fdt_serial.h> +#include <sbi_utils/serial/shakti-uart.h> + +static int serial_shakti_init(void *fdt, int nodeoff, + const struct fdt_match *match) +{ + int rc; + struct platform_uart_data uart; + + rc = fdt_parse_shakti_uart_node(fdt, nodeoff, &uart); + if (rc) + return rc; + + return shakti_uart_init(uart.addr, uart.freq, uart.baud); +} + +static const struct fdt_match serial_shakti_match[] = { + { .compatible = "shakti,uart0" }, + { }, +}; + +struct fdt_serial fdt_serial_shakti = { + .match_table = serial_shakti_match, + .init = serial_shakti_init, + .getc = shakti_uart_getc, + .putc = shakti_uart_putc +}; diff --git a/lib/utils/serial/objects.mk b/lib/utils/serial/objects.mk index d81663b..c0746f0 100644 --- a/lib/utils/serial/objects.mk +++ b/lib/utils/serial/objects.mk @@ -9,7 +9,9 @@ libsbiutils-objs-y += serial/fdt_serial.o libsbiutils-objs-y += serial/fdt_serial_htif.o +libsbiutils-objs-y += serial/fdt_serial_shakti.o libsbiutils-objs-y += serial/fdt_serial_sifive.o libsbiutils-objs-y += serial/fdt_serial_uart8250.o +libsbiutils-objs-y += serial/shakti-uart.o libsbiutils-objs-y += serial/sifive-uart.o libsbiutils-objs-y += serial/uart8250.o diff --git a/lib/utils/serial/shakti-uart.c b/lib/utils/serial/shakti-uart.c new file mode 100644 index 0000000..493edcf --- /dev/null +++ b/lib/utils/serial/shakti-uart.c @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Vijai Kumar K <vijai@behindbytes.com> + */ + +#include <sbi/riscv_io.h> +#include <sbi/sbi_console.h> +#include <sbi_utils/serial/shakti-uart.h> + +#define REG_BAUD 0x00 +#define REG_TX 0x04 +#define REG_RX 0x08 +#define REG_STATUS 0x0C +#define REG_DELAY 0x10 +#define REG_CONTROL 0x14 +#define REG_INT_EN 0x18 +#define REG_IQ_CYCLES 0x1C +#define REG_RX_THRES 0x20 + +static volatile void *uart_base; + +void shakti_uart_putc(char ch) +{ + while((readw(uart_base + REG_STATUS) & 0x2) == 0); + writeb(ch, uart_base + REG_TX); +} + +int shakti_uart_getc(void) +{ + u16 status = readw(uart_base + REG_STATUS); + if (status & 0x8) + return readb(uart_base + REG_RX); + return -1; +} + +int shakti_uart_init(unsigned long base, u32 in_freq, u32 baudrate) +{ + uart_base = (volatile void *)base; + u16 baud = (u16)(in_freq/(16 * baudrate)); + writew(baud, uart_base + REG_BAUD); + + return 0; +} |