platform: Add support for Shakti C-class SoC from IIT-M

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.

https://gitlab.com/shaktiproject/cores/c-class/blob/master/README.md

We add OpenSBI support for Shakti C-class SoC.

Signed-off-by: Vijai Kumar K <vijai@behindbytes.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
Vijai Kumar K
2020-06-17 19:25:16 +05:30
committed by Anup Patel
parent 637b348224
commit db56ef367c
10 changed files with 181 additions and 0 deletions

View File

@@ -47,6 +47,8 @@ RISC-V Platforms Using Generic Platform
* **QEMU RISC-V Virt Machine** (*[qemu_virt.md]*) * **QEMU RISC-V Virt Machine** (*[qemu_virt.md]*)
* **Spike** (*[spike.md]*) * **Spike** (*[spike.md]*)
* **Shakti C-class SoC Platform** (*[shakti_cclass.md]*)
[qemu_virt.md]: qemu_virt.md [qemu_virt.md]: qemu_virt.md
[spike.md]: spike.md [spike.md]: spike.md
[shakti_cclass.md]: shakti_cclass.md

View File

@@ -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 on ariane core. More details on this platform can be found in the file
*[fpga_openpiton.md]*. *[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 The code for these supported platforms can be used as example to implement
support for other platforms. The *platform/template* directory also provides support for other platforms. The *platform/template* directory also provides
template files for implementing support for a new platform. The *object.mk*, 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 [thead-c910.md]: thead-c910.md
[spike.md]: spike.md [spike.md]: spike.md
[fpga_openpiton.md]: fpga_openpiton.md [fpga_openpiton.md]: fpga_openpiton.md
[shakti_cclass.md]: shakti_cclass.md

View File

@@ -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>
```

View File

@@ -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_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, int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset,
struct platform_uart_data *uart); struct platform_uart_data *uart);

View File

@@ -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

View File

@@ -26,6 +26,9 @@
#define DEFAULT_SIFIVE_UART_REG_SHIFT 0 #define DEFAULT_SIFIVE_UART_REG_SHIFT 0
#define DEFAULT_SIFIVE_UART_REG_IO_WIDTH 4 #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 *fdt_match_node(void *fdt, int nodeoff,
const struct fdt_match *match_table) const struct fdt_match *match_table)
{ {
@@ -164,6 +167,40 @@ int fdt_parse_max_hart_id(void *fdt, u32 *max_hartid)
return 0; 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, &reg_addr, &reg_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, int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset,
struct platform_uart_data *uart) struct platform_uart_data *uart)
{ {

View File

@@ -15,11 +15,13 @@
extern struct fdt_serial fdt_serial_uart8250; extern struct fdt_serial fdt_serial_uart8250;
extern struct fdt_serial fdt_serial_sifive; extern struct fdt_serial fdt_serial_sifive;
extern struct fdt_serial fdt_serial_htif; extern struct fdt_serial fdt_serial_htif;
extern struct fdt_serial fdt_serial_shakti;
static struct fdt_serial *serial_drivers[] = { static struct fdt_serial *serial_drivers[] = {
&fdt_serial_uart8250, &fdt_serial_uart8250,
&fdt_serial_sifive, &fdt_serial_sifive,
&fdt_serial_htif, &fdt_serial_htif,
&fdt_serial_shakti,
}; };
static void dummy_putc(char ch) static void dummy_putc(char ch)

View File

@@ -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
};

View File

@@ -9,7 +9,9 @@
libsbiutils-objs-y += serial/fdt_serial.o libsbiutils-objs-y += serial/fdt_serial.o
libsbiutils-objs-y += serial/fdt_serial_htif.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_sifive.o
libsbiutils-objs-y += serial/fdt_serial_uart8250.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/sifive-uart.o
libsbiutils-objs-y += serial/uart8250.o libsbiutils-objs-y += serial/uart8250.o

View File

@@ -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;
}