[bsp]add cv1800b (#7753)

This commit is contained in:
flyingcys 2023-06-30 00:05:55 +08:00 committed by GitHub
parent bce92ed724
commit c78f646891
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 2552 additions and 3 deletions

1041
bsp/cv1800b/.config Normal file

File diff suppressed because it is too large Load Diff

5
bsp/cv1800b/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
cv1800b_milkv_duo_sd.dtb
Image
Image.lzma
multi.its
boot.sd

45
bsp/cv1800b/Kconfig Normal file
View File

@ -0,0 +1,45 @@
mainmenu "RT-Thread Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../.."
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
source "drivers/Kconfig"
config BSP_USING_CV1800B
bool
select ARCH_RISCV64
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select RT_USING_CACHE
select ARCH_MM_MMU
default y
config C906_PLIC_PHY_ADDR
hex
default 0x70000000
config IRQ_MAX_NR
int
default 64
config TIMER_CLK_FREQ
int
default 25000000
config __STACKSIZE__
int "stack size for interrupt"
default 4096

131
bsp/cv1800b/README.md Normal file
View File

@ -0,0 +1,131 @@
**中文** | [English](README_en.md)
## 概述
CV180ZB/CV1800B/CV1801B 是面向民用消费监控 IP 摄像机、居家智能等多项产品领域而推出的高性能、低功耗芯片,集成了 H.264/H.265 视频压缩编码器和 ISP支持数字寛动态、 3D 降噪、除雾、镜头畸变校正等多种图像增强和矫正算法,为客户提供专业级的视频图像质量。
1. 处理器内核
- 主处理器 RISCV C906 @ 1.0Ghz
- 32KB I-cache, 64KB D-Cache
- 集成矢量(Vector)及浮点运算单元 (FPU) .
- 协处理器 RISCV C906 @ 700Mhz
- 集成浮点运算单元 (FPU)
2. 存储器接口
- 内建 DRAM : DDR2 16bitx1, 最高速率达 1333Mbps , 容量512Mbit (64MB)
- 支持SPI NOR flash 接口 (1.8V / 3.0V)
- 支持 1, 2, 4 线模式
- 最大支持 256MByte
- 支持 SPI Nand flash 接口 (1.8V / 3.0V)
- 支持 1KB/2KB/4KB page (对应的最大容量 16GB/32GB/64GB)
- 使用器件本身内建的 ECC 模块
3. 外设
- Up to 26 GPIO pins on the MilkV-Duo 40-pin header provide access to internal peripherals such as SDIO, I2C, PWM, SPI, J-TAG, and UART
- Up to 3x I2C
- Up to 5x UART
- Up to 1x SDIO1
- Up to 1x SPI
- Up to 2x ADC
- Up to 7x PWM
- Up to 1x RUN
- Up to 1x JTAG
- 集成 MAC PHY 支持 10/100Mbps 全双工或半双工模式
- 一个 USB Host / device 接口
## Toolchain 下载
下载 `riscv64-unknown-linux-musl-gcc` 的工具链: [https://github.com/RT-Thread/toolchains-ci/releases/download/v1.7/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2](https://github.com/RT-Thread/toolchains-ci/releases/download/v1.7/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2)
> 注:
当前 bsp 只支持 Linux 编译
正确解压后,在`rtconfig.py`中将 `riscv64-unknown-linux-musl-gcc` 工具链的本地路径加入 `EXEC_PATH` 或通过 `RTT_EXEC_PATH` 环境变量指定路径。
```shell
$ export RTT_EXEC_PATH=/opt/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin
```
## 编译
1. 依赖安装
```shell
$ sudo apt install -y device-tree-compiler
```
2. Linux平台下可以先执行
```shell
$ scons --menuconfig
```
它会自动下载env相关脚本到~/.env目录然后执行
```shell
$ source ~/.env/env.sh
$ pkgs --update
```
更新完软件包后,执行 `scons -j10``scons -j10 --verbose` 来编译这个板级支持包。或者通过 `scons --exec-path="GCC工具链路径"` 命令在指定工具链位置的同时直接编译。编译正确无误会产生rtthread.elf文件。
编译完成后脚本自动调用 `./mksdimg.sh` 脚本进行打包,并生成 `boot.sd`, 该文件即为 SD 卡启动的 kernel 文件。
## 运行
1. 将 SD 卡分为 2 个分区,第 1 个分区用于存放 bin 文件,第 2 个分区用于作为数据存储分区,分区格式为 `FAT32`
2. 将根目录下的 `fip.bin``boot.sd` 复制 SD 卡第一个分区中。后续更新固件只需要复制 `boot.sd` 文件即可。
其中:
- fip.binfsbl、 opensbi 和 uboot 打包后的 bin 文件
- boot.sdkernel 打包后的 bin 文件
更新完 `boot.sd` 后, 重新上电可以看到串口的输出信息:
```shell
U-Boot 2021.10 (Jun 26 2023 - 14:09:06 +0800)cvitek_cv180x
DRAM: 63.3 MiB
gd->relocaddr=0x82435000. offset=0x2235000
MMC: cv-sd@4310000: 0
Loading Environment from <NULL>... OK
In: serial
Out: serial
Err: serial
Net:
Warning: ethernet@4070000 (eth0) using random MAC address - 62:80:19:6c:d4:64
eth0: ethernet@4070000
Hit any key to stop autoboot: 0
Boot from SD ...
switch to partitions #0, OK
mmc0 is current device
132692 bytes read in 12 ms (10.5 MiB/s)
## Loading kernel from FIT Image at 81400000 ...
Using 'config-cv1800b_milkv_duo_sd' configuration
Trying 'kernel-1' kernel subimage
Verifying Hash Integrity ... crc32+ OK
## Loading fdt from FIT Image at 81400000 ...
Using 'config-cv1800b_milkv_duo_sd' configuration
Trying 'fdt-cv1800b_milkv_duo_sd' fdt subimage
Verifying Hash Integrity ... sha256+ OK
Booting using the fdt blob at 0x8141b590
Uncompressing Kernel Image
Decompressing 296768 bytes used 42ms
Loading Device Tree to 0000000081be5000, end 0000000081becb60 ... OK
Starting kernel ...
heap: [0x802766b0 - 0x812766b0]
\ | /
- RT - Thread Smart Operating System
/ | \ 5.0.1 build Jun 28 2023 23:44:36
2006 - 2022 Copyright by RT-Thread team
Hello RT-Smart!
msh />
```
## 驱动支持列表
| 驱动 | 支持情况 | 备注 |
| :--- | :------- | :---------------- |
| UART | 支持 | 默认波特率115200 |
## 支持开发板
- milk-v duo: [https://milkv.io/duo](https://milkv.io/duo)
## 联系人信息
维护人:[flyingcys](https://github.com/flyingcys)

130
bsp/cv1800b/README_en.md Normal file
View File

@ -0,0 +1,130 @@
[中文](README.md) | **English**
## Overview
CV180ZB/CV1800B/CV1801B are high-performance, low-power chips designed for consumer surveillance IP cameras, smart home devices, and other product areas. They integrate H.264/H.265 video compression encoders and ISPs, and support various image enhancement and correction algorithms such as digital wide dynamic range, 3D noise reduction, defogging, and lens distortion correction, providing professional-grade video image quality to customers.
1. Processor Core
- Main processor: RISCV C906 @ 1.0Ghz
- 32KB I-cache, 64KB D-Cache
- Integrated vector and floating-point units (FPU).
- Coprocessor: RISCV C906 @ 700Mhz
- Integrated floating-point unit (FPU).
2. Memory Interface
- Built-in DRAM: DDR2 16bitx1, with a maximum speed of 1333Mbps, capacity of 512Mbit (64MB).
- Support for SPI NOR flash interface (1.8V / 3.0V)
- Support for 1, 2, 4-wire modes
- Maximum support of 256MBytes
- Support for SPI Nand flash interface (1.8V / 3.0V)
- Support for 1KB/2KB/4KB page (corresponding to a maximum capacity of 16GB/32GB/64GB)
- Use the built-in ECC module of the device itself
3. Peripherals
- Up to 26 GPIO pins on the MilkV-Duo 40-pin header provide access to internal peripherals such as SDIO, I2C, PWM, SPI, J-TAG, and UART.
- Up to 3x I2C
- Up to 5x UART
- Up to 1x SDIO1
- Up to 1x SPI
- Up to 2x ADC
- Up to 7x PWM
- Up to 1x RUN
- Up to 1x JTAG
- Integrated MAC PHY supporting 10/100Mbps full-duplex or half-duplex mode
- One USB Host / device interface
## Toolchain Download
Download the `riscv64-unknown-linux-musl-gcc` toolchain from: [https://github.com/RT-Thread/toolchains-ci/releases/download/v1.7/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2](https://github.com/RT-Thread/toolchains-ci/releases/download/v1.7/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2)
> Note:
The current BSP only supports Linux compilation.
After correct extraction, add the local path of the `riscv64-unknown-linux-musl-gcc` toolchain to `EXEC_PATH` in `rtconfig.py`, or specify the path through the `RTT_EXEC_PATH` environment variable.
```shell
$ export RTT_EXEC_PATH=/opt/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin
```
## Compilation
1. Installing Dependencies
```shell
$ sudo apt install -y device-tree-compiler
```
On the Linux platform, you can execute:
```shell
$ scons --menuconfig
```
It will automatically download environment-related scripts to the ~/.env directory, and then execute
```shell
$ source ~/.env/env.sh
$ pkgs --update
```
After updating the software packages, use `scons -j10` or `scons -j10 --verbose` to compile this board support package. Alternatively, you can use the command `scons --exec-path="GCC_toolchain_path"` to specify the toolchain location for compilation. If the compilation is successful, an rtthread.elf file will be generated.
After the compilation is completed, the script automatically calls the `./mksdimg.sh` script to package and generate the `boot.sd` file, which is the kernel file for SD card boot.
## Running
1. Divide the SD card into 2 partitions, with the first partition used to store bin files and the second partition used as a data storage partition. The partition format is FAT32.
2. Copy the `fip.bin` and `boot.sd` files from the root directory to the first partition of the SD card. For subsequent firmware updates, you only need to copy the `boot.sd` file.
Where:
- fip.bin: the bin file after fsbl、opensbi and U-Boot are packaged
- boot.sd: the bin file after the kernel is packaged
After updating `boot.sd`, power on again and you will see the serial output information:
```shell
U-Boot 2021.10 (Jun 26 2023 - 14:09:06 +0800)cvitek_cv180x
DRAM: 63.3 MiB
gd->relocaddr=0x82435000. offset=0x2235000
MMC: cv-sd@4310000: 0
Loading Environment from <NULL>... OK
In: serial
Out: serial
Err: serial
Net:
Warning: ethernet@4070000 (eth0) using random MAC address - 62:80:19:6c:d4:64
eth0: ethernet@4070000
Hit any key to stop autoboot: 0
Boot from SD ...
switch to partitions #0, OK
mmc0 is current device
132692 bytes read in 12 ms (10.5 MiB/s)
## Loading kernel from FIT Image at 81400000 ...
Using 'config-cv1800b_milkv_duo_sd' configuration
Trying 'kernel-1' kernel subimage
Verifying Hash Integrity ... crc32+ OK
## Loading fdt from FIT Image at 81400000 ...
Using 'config-cv1800b_milkv_duo_sd' configuration
Trying 'fdt-cv1800b_milkv_duo_sd' fdt subimage
Verifying Hash Integrity ... sha256+ OK
Booting using the fdt blob at 0x8141b590
Uncompressing Kernel Image
Decompressing 296768 bytes used 42ms
Loading Device Tree to 0000000081be5000, end 0000000081becb60 ... OK
Starting kernel ...
heap: [0x802766b0 - 0x812766b0]
\ | /
- RT - Thread Smart Operating System
/ | \ 5.0.1 build Jun 28 2023 23:44:36
2006 - 2022 Copyright by RT-Thread team
Hello RT-Smart!
msh />
```
## Driver Support List
| Driver | Support Status | Remarks |
| :----- | :------------- | :--------------------- |
| UART | Supported | Default baud rate 115200 |
## Supported Development Boards
- milk-v duo: [https://milkv.io/duo](https://milkv.io/duo)
## Contact information
Maintenance person[flyingcys](https://github.com/flyingcys)

14
bsp/cv1800b/SConscript Normal file
View File

@ -0,0 +1,14 @@
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

38
bsp/cv1800b/SConstruct Normal file
View File

@ -0,0 +1,38 @@
import os
import sys
import rtconfig
from rtconfig import RTT_ROOT
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env['ASCOM'] = env['ASPPCOM']
Export('RTT_ROOT')
Export('rtconfig')
rtconfig.CPU='virt64'
rtconfig.ARCH='risc-v'
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
stack_size = 4096
stack_lds = open('link_stacksize.lds', 'w')
if GetDepend('__STACKSIZE__'): stack_size = GetDepend('__STACKSIZE__')
stack_lds.write('__STACKSIZE__ = %d;\n' % stack_size)
stack_lds.close()
# make a building
DoBuilding(TARGET, objs)

View File

@ -0,0 +1,9 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023/06/25 flyingcys first version
*/
#include <rtthread.h>
#include <stdio.h>
int main(void)
{
rt_kprintf("Hello RT-Smart!\n");
return 0;
}

Binary file not shown.

31
bsp/cv1800b/drivers/Kconfig Executable file
View File

@ -0,0 +1,31 @@
menu "General Drivers Configuration"
menuconfig BSP_USING_UART
bool "Using UART"
select RT_USING_SERIAL
default y
if BSP_USING_UART
config RT_USING_UART0
bool "Enable UART 0"
default y
config RT_USING_UART1
bool "Enable UART 1"
default n
config RT_USING_UART2
bool "Enable UART 2"
default n
config RT_USING_UART3
bool "Enable UART 3"
default n
config RT_USING_UART4
bool "Enable UART 4"
default n
endif
endmenu

9
bsp/cv1800b/drivers/SConscript Executable file
View File

@ -0,0 +1,9 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
CPPPATH = [cwd]
group = DefineGroup('Driver', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

122
bsp/cv1800b/drivers/board.c Normal file
View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023/06/25 flyingcys first version
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "sbi.h"
#ifdef RT_USING_SMART
#include "riscv_mmu.h"
#include "mmu.h"
#include "page.h"
#include "lwp_arch.h"
rt_region_t init_page_region = {(rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END};
extern size_t MMUTable[];
struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, (rt_size_t)RT_HW_PAGE_END - 1, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM},
{0x1000, ((KERNEL_VADDR_START - 1) & 0xfffff000) - 1, (rt_size_t)ARCH_MAP_FAILED, DEVICE_MEM},
};
#define NUM_MEM_DESC (sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]))
#endif /* RT_USING_SMART */
void init_bss(void)
{
unsigned int *dst;
dst = &__bss_start;
while (dst < &__bss_end)
{
*dst++ = 0;
}
}
static void __rt_assert_handler(const char *ex_string, const char *func, rt_size_t line)
{
rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex_string, func, line);
asm volatile("ebreak" ::
: "memory");
}
void primary_cpu_entry(void)
{
extern void entry(void);
/* disable global interrupt */
rt_hw_interrupt_disable();
rt_assert_set_hook(__rt_assert_handler);
entry();
}
#define IOREMAP_SIZE (1ul << 30)
#ifndef ARCH_KERNEL_IN_HIGH_VA
#define IOREMAP_VEND USER_VADDR_START
#else
#define IOREMAP_VEND 0ul
#endif
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
/* init data structure */
rt_hw_mmu_map_init(&rt_kernel_space, (void *)(IOREMAP_VEND - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, PV_OFFSET);
/* init page allocator */
rt_page_init(init_page_region);
/* setup region, and enable MMU */
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, NUM_MEM_DESC);
#endif
/* initialize memory system */
#ifdef RT_USING_HEAP
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
#endif
/* initalize interrupt */
rt_hw_interrupt_init();
/* init rtthread hardware */
rt_hw_tick_init();
#ifdef RT_USING_SERIAL
rt_hw_uart_init();
#endif
#ifdef RT_USING_CONSOLE
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif /* RT_USING_CONSOLE */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_HEAP
rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t)RT_HW_HEAP_BEGIN, (rt_ubase_t)RT_HW_HEAP_END);
#endif /* RT_USING_HEAP */
}
void rt_hw_cpu_reset(void)
{
sbi_shutdown();
while (1)
;
}
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);

32
bsp/cv1800b/drivers/board.h Executable file
View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023/06/25 flyingcys first version
*/
#ifndef BOARD_H__
#define BOARD_H__
#include <rtconfig.h>
#include "drv_uart.h"
#include "tick.h"
extern unsigned int __bss_start;
extern unsigned int __bss_end;
#ifndef RT_USING_SMART
#define KERNEL_VADDR_START 0x0
#endif
#define RT_HW_HEAP_BEGIN ((void *)&__bss_end)
#define RT_HW_HEAP_END ((void *)(RT_HW_HEAP_BEGIN + 16 * 1024 * 1024))
#define RT_HW_PAGE_START RT_HW_HEAP_END
#define RT_HW_PAGE_END ((void *)(KERNEL_VADDR_START + 32 * 1024 * 1024))
void rt_hw_board_init(void);
#endif

View File

@ -0,0 +1,296 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023/06/25 flyingcys first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "drv_uart.h"
#define DBG_TAG "DRV.UART"
#define DBG_LVL DBG_WARNING
#include <rtdbg.h>
/*
* The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
* LCR is written whilst busy. If it is, then a busy detect interrupt is
* raised, the LCR needs to be rewritten and the uart status register read.
*/
#define UART_RX 0 /* In: Receive buffer */
#define UART_TX 0 /* Out: Transmit buffer */
#define UART_DLL 0 /* Out: Divisor Latch Low */
#define UART_DLM 1 /* Out: Divisor Latch High */
#define UART_IER 1 /* Out: Interrupt Enable Register */
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
#define UART_SSR 0x22 /* In: Software Reset Register */
#define UART_USR 0x1f /* UART Status Register */
#define UART_LCR 3 /* Out: Line Control Register */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_SPAR 0x20 /* Stick parity (?) */
#define UART_LCR_PARITY 0x8 /* Parity Enable */
#define UART_LCR_STOP 0x4 /* Stop bits: 0=1 bit, 1=2 bits */
#define UART_LCR_WLEN8 0x3 /* Wordlength: 8 bits */
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_LSR 5 /* In: Line Status Register */
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
#define UART_IIR 2 /* In: Interrupt ID Register */
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */
#define UART_IIR_RX_TIMEOUT 0x0c /* OMAP RX Timeout interrupt */
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_FCR_EN_FIFO 0x01 /* Enable the FIFO */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
struct hw_uart_device
{
rt_ubase_t hw_base;
rt_uint32_t irqno;
};
#define BSP_DEFINE_UART_DEVICE(no) \
static struct hw_uart_device _uart##no##_device = \
{ \
UART##no##_BASE, \
UART##no##_IRQ \
}; \
static struct rt_serial_device _serial##no;
#ifdef RT_USING_UART0
BSP_DEFINE_UART_DEVICE(0);
#endif
#ifdef RT_USING_UART1
BSP_DEFINE_UART_DEVICE(1);
#endif
#ifdef RT_USING_UART2
BSP_DEFINE_UART_DEVICE(2);
#endif
#ifdef RT_USING_UART3
BSP_DEFINE_UART_DEVICE(3);
#endif
rt_inline rt_uint32_t dw8250_read32(rt_ubase_t addr, rt_ubase_t offset)
{
return *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT)));
}
rt_inline void dw8250_write32(rt_ubase_t addr, rt_ubase_t offset, rt_uint32_t value)
{
*((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))) = value;
if (offset == UART_LCR)
{
int tries = 1000;
/* Make sure LCR write wasn't ignored */
while (tries--)
{
unsigned int lcr = dw8250_read32(addr, UART_LCR);
if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
{
return;
}
dw8250_write32(addr, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
dw8250_read32(addr, UART_RX);
*((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))) = value;
}
}
}
static rt_err_t dw8250_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
rt_base_t base, rate;
struct hw_uart_device *uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
base = uart->hw_base;
/* Resset UART */
dw8250_write32(base, UART_SSR, 1);
dw8250_write32(base, UART_SSR, 0);
dw8250_write32(base, UART_IER, !UART_IER_RDI);
dw8250_write32(base, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
/* Disable flow ctrl */
dw8250_write32(base, UART_MCR, 0);
/* Clear RTS */
dw8250_write32(base, UART_MCR, dw8250_read32(base, UART_MCR) | UART_MCR_RTS);
rate = UART_INPUT_CLK / 16 / serial->config.baud_rate;
/* Enable access DLL & DLH */
dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) | UART_LCR_DLAB);
dw8250_write32(base, UART_DLL, (rate & 0xff));
dw8250_write32(base, UART_DLM, (rate & 0xff00) >> 8);
/* Clear DLAB bit */
dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_DLAB));
dw8250_write32(base, UART_LCR, (dw8250_read32(base, UART_LCR) & (~UART_LCR_WLEN8)) | UART_LCR_WLEN8);
dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_STOP));
dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_PARITY));
dw8250_write32(base, UART_IER, UART_IER_RDI);
return RT_EOK;
}
static rt_err_t dw8250_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
struct hw_uart_device *uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* Disable rx irq */
dw8250_write32(uart->hw_base, UART_IER, !UART_IER_RDI);
rt_hw_interrupt_mask(uart->irqno);
break;
case RT_DEVICE_CTRL_SET_INT:
/* Enable rx irq */
dw8250_write32(uart->hw_base, UART_IER, UART_IER_RDI);
rt_hw_interrupt_umask(uart->irqno);
break;
}
return RT_EOK;
}
static int dw8250_uart_putc(struct rt_serial_device *serial, char c)
{
rt_base_t base;
struct hw_uart_device *uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
base = uart->hw_base;
while ((dw8250_read32(base, UART_USR) & 0x2) == 0)
{
}
dw8250_write32(base, UART_TX, c);
return 1;
}
static int dw8250_uart_getc(struct rt_serial_device *serial)
{
int ch = -1;
rt_base_t base;
struct hw_uart_device *uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
base = uart->hw_base;
if ((dw8250_read32(base, UART_LSR) & 0x1))
{
ch = dw8250_read32(base, UART_RX) & 0xff;
}
return ch;
}
static const struct rt_uart_ops _uart_ops =
{
dw8250_uart_configure,
dw8250_uart_control,
dw8250_uart_putc,
dw8250_uart_getc,
};
static void rt_hw_uart_isr(int irqno, void *param)
{
unsigned int iir, status;
struct rt_serial_device *serial = (struct rt_serial_device *)param;
struct hw_uart_device *uart = (struct hw_uart_device *)serial->parent.user_data;
iir = dw8250_read32(uart->hw_base, UART_IIR);
/* If don't do this in non-DMA mode then the "RX TIMEOUT" interrupt will fire forever. */
if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)
{
status = dw8250_read32(uart->hw_base, UART_LSR);
if (!(status & (UART_LSR_DR | UART_LSR_BI)))
{
dw8250_read32(uart->hw_base, UART_RX);
}
}
if (!(iir & UART_IIR_NO_INT))
{
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
}
if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY)
{
/* Clear the USR */
dw8250_read32(uart->hw_base, UART_USR);
return;
}
}
int rt_hw_uart_init(void)
{
struct hw_uart_device* uart;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
config.baud_rate = 115200;
#define BSP_INSTALL_UART_DEVICE(no) \
uart = &_uart##no##_device; \
_serial##no.ops = &_uart_ops; \
_serial##no.config = config; \
rt_hw_serial_register(&_serial##no, "uart" #no, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); \
rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial##no, "uart" #no);
#ifdef RT_USING_UART0
BSP_INSTALL_UART_DEVICE(0);
#endif
#ifdef RT_USING_UART1
BSP_INSTALL_UART_DEVICE(1);
#endif
#ifdef RT_USING_UART2
BSP_INSTALL_UART_DEVICE(2);
#endif
#ifdef RT_USING_UART3
BSP_INSTALL_UART_DEVICE(3);
#endif
return 0;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023/06/25 flyingcys first version
*/
#ifndef __DRV_USART_H__
#define __DRV_USART_H__
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#define UART_REG_SHIFT 0x2 /* Register Shift*/
#define UART_INPUT_CLK 25000000
#define UART0_BASE 0x04140000
#define UART1_BASE 0x04150000
#define UART2_BASE 0x04160000
#define UART3_BASE 0x04170000
#define UART4_BASE 0x041C0000
#define UART_IRQ_BASE (44)
#define UART0_IRQ (UART_IRQ_BASE + 0)
#define UART1_IRQ (UART_IRQ_BASE + 1)
#define UART2_IRQ (UART_IRQ_BASE + 2)
#define UART3_IRQ (UART_IRQ_BASE + 3)
#define UART4_IRQ (UART_IRQ_BASE + 4)
int rt_hw_uart_init(void);
#endif /* __DRV_USART_H__ */

BIN
bsp/cv1800b/fip.bin Executable file

Binary file not shown.

197
bsp/cv1800b/link.lds Normal file
View File

@ -0,0 +1,197 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020/12/12 bernard The first version
*/
INCLUDE "link_stacksize.lds"
OUTPUT_ARCH( "riscv" )
/*
* Memory layout:
* 0x10200000 - 0x10201000: Bootloader
* 0x10201000 - 0x10A00000: Kernel
* 0x10A00000 - 0x11200000: Heap
*/
MEMORY
{
SRAM : ORIGIN = 0x80200000, LENGTH = 32M
}
ENTRY(_start)
SECTIONS
{
. = 0x80200000 ;
/* __STACKSIZE__ = 4096; */
__text_start = .;
.start :
{
*(.start);
} > SRAM
. = ALIGN(8);
.text :
{
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(8);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(8);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(8);
/* section information for initial. */
. = ALIGN(8);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(8);
__rt_utest_tc_tab_start = .;
KEEP(*(UtestTcTab))
__rt_utest_tc_tab_end = .;
. = ALIGN(8);
_etext = .;
} > SRAM
.eh_frame_hdr :
{
*(.eh_frame_hdr)
*(.eh_frame_entry)
} > SRAM
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > SRAM
. = ALIGN(8);
__text_end = .;
__text_size = __text_end - __text_start;
.data :
{
*(.data)
*(.data.*)
*(.data1)
*(.data1.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata)
*(.sdata.*)
} > SRAM
. = ALIGN(8);
.ctors :
{
PROVIDE(__ctors_start__ = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE(__ctors_end__ = .);
} > SRAM
.dtors :
{
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE(__dtors_end__ = .);
} > SRAM
/* stack for dual core */
.stack :
{
. = ALIGN(64);
__stack_start__ = .;
. += __STACKSIZE__;
__stack_cpu0 = .;
. += __STACKSIZE__;
__stack_cpu1 = .;
} > SRAM
. = ALIGN(8);
.osdebug :
{
_osdebug_start = .;
. += 87K;
_osdebug_end = .;
} > SRAM
. = ALIGN(8);
.sbss :
{
__bss_start = .;
*(.sbss)
*(.sbss.*)
*(.dynsbss)
*(.scommon)
} > SRAM
.bss :
{
*(.bss)
*(.bss.*)
*(.dynbss)
*(COMMON)
__bss_end = .;
} > SRAM
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View File

@ -0,0 +1 @@
__STACKSIZE__ = 4096;

BIN
bsp/cv1800b/mkimage Executable file

Binary file not shown.

7
bsp/cv1800b/mksdimg.sh Executable file
View File

@ -0,0 +1,7 @@
#/bin/sh
set -e
echo "start compress kernel..."
lzma -c -9 -f -k Image > Image.lzma
./mkimage -f multi.its -r boot.sd

56
bsp/cv1800b/multi.its Executable file
View File

@ -0,0 +1,56 @@
/*
* U-Boot uImage source file with multiple kernels, ramdisks and FDT blobs
*/
/dts-v1/;
/ {
description = "Various kernels, ramdisks and FDT blobs";
#address-cells = <2>;
images {
kernel-1 {
description = "cvitek kernel";
data = /incbin/("./Image.lzma");
type = "kernel";
arch = "riscv";
os = "linux";
compression = "lzma";
load = <0x0 0x80200000>;
entry = <0x0 0x80200000>;
hash-2 {
algo = "crc32";
};
};
/*FDT*/
fdt-cv1800b_milkv_duo_sd {
description = "cvitek device tree - cv1800b_milkv_duo_sd";
data = /incbin/("./cv1800b_milkv_duo_sd.dtb");
type = "flat_dt";
arch = "riscv";
compression = "none";
hash-1 {
algo = "sha256";
};
};
};
/*CFG*/
configurations {
config-cv1800b_milkv_duo_sd {
description = "boot cvitek system with board cv1800b_milkv_duo_sd";
kernel = "kernel-1";
fdt = "fdt-cv1800b_milkv_duo_sd";
};
};
};

271
bsp/cv1800b/rtconfig.h Normal file
View File

@ -0,0 +1,271 @@
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
/* Automatically generated file; DO NOT EDIT. */
/* RT-Thread Project Configuration */
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_USING_SMART
#define RT_ALIGN_SIZE 8
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 1000
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_HOOK_USING_FUNC_PTR
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 1024
#define RT_USING_TIMER_SOFT
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 2048
/* kservice optimization */
#define RT_KSERVICE_USING_STDLIB
#define RT_KPRINTF_USING_LONGLONG
#define RT_DEBUG
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_EVENT
#define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE
/* Memory Management */
#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_HEAP
/* Kernel Device Object */
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 256
#define RT_CONSOLE_DEVICE_NAME "uart0"
#define RT_VER_NUM 0x50001
#define ARCH_CPU_64BIT
#define RT_USING_CACHE
#define ARCH_MM_MMU
#define KERNEL_VADDR_START 0x80000000
#define ARCH_RISCV
#define ARCH_RISCV64
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 6144
#define RT_MAIN_THREAD_PRIORITY 10
#define RT_USING_MSH
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_THREAD_NAME "tshell"
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 4096
#define FINSH_USING_HISTORY
#define FINSH_HISTORY_LINES 5
#define FINSH_USING_SYMTAB
#define FINSH_CMD_SIZE 80
#define MSH_USING_BUILT_IN_COMMANDS
#define FINSH_USING_DESCRIPTION
#define FINSH_ARG_MAX 10
/* DFS: device virtual file system */
#define RT_USING_DFS
#define DFS_USING_POSIX
#define DFS_USING_WORKDIR
#define DFS_FD_MAX 16
#define RT_USING_DFS_V1
#define DFS_FILESYSTEMS_MAX 4
#define DFS_FILESYSTEM_TYPES_MAX 4
#define RT_USING_DFS_DEVFS
#define RT_USING_LWP
#define RT_LWP_MAX_NR 30
#define LWP_TASK_STACK_SIZE 16384
#define RT_CH_MSG_MAX_NR 1024
#define LWP_CONSOLE_INPUT_BUFFER_SIZE 1024
#define LWP_TID_MAX_NR 64
#define RT_LWP_SHM_MAX_NR 64
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_UNAMED_PIPE_NUMBER 64
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V1
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_TTY
#define RT_USING_PIN
#define RT_USING_NULL
#define RT_USING_ZERO
#define RT_USING_RANDOM
#define RT_USING_RTC
/* Using USB */
/* C/C++ and POSIX layer */
#define RT_LIBC_DEFAULT_TIMEZONE 8
/* POSIX (Portable Operating System Interface) layer */
#define RT_USING_POSIX_FS
#define RT_USING_POSIX_DEVIO
#define RT_USING_POSIX_STDIO
#define RT_USING_POSIX_TERMIOS
#define RT_USING_POSIX_DELAY
#define RT_USING_POSIX_CLOCK
#define RT_USING_POSIX_TIMER
/* Interprocess Communication (IPC) */
/* Socket is in the 'Network' category */
/* Network */
/* Utilities */
#define RT_USING_ADT
#define RT_USING_RESOURCE_ID
/* RT-Thread Utestcases */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* Wiced WiFi */
/* IoT Cloud */
/* security packages */
/* language packages */
/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* XML: Extensible Markup Language */
/* multimedia packages */
/* LVGL: powerful and easy-to-use embedded GUI library */
/* u8g2: a monochrome graphic library */
/* tools packages */
/* system packages */
/* enhanced kernel services */
/* acceleration: Assembly language or algorithmic acceleration packages */
/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* Micrium: Micrium software products porting for RT-Thread */
/* peripheral libraries and drivers */
/* sensors drivers */
/* touch drivers */
/* Kendryte SDK */
/* AI packages */
/* Signal Processing and Control Algorithm Packages */
/* miscellaneous packages */
/* project laboratory */
/* samples: kernel and components samples */
/* entertainment: terminal games and other interesting software packages */
/* Arduino libraries */
/* Projects */
/* Sensors */
/* Display */
/* Timing */
/* Data Processing */
/* Data Storage */
/* Communication */
/* Device Control */
/* Other */
/* Signal IO */
/* Uncategorized */
/* General Drivers Configuration */
#define BSP_USING_UART
#define RT_USING_UART0
#define BSP_USING_CV1800B
#define C906_PLIC_PHY_ADDR 0x70000000
#define IRQ_MAX_NR 64
#define TIMER_CLK_FREQ 25000000
#define __STACKSIZE__ 4096
#endif

59
bsp/cv1800b/rtconfig.py Normal file
View File

@ -0,0 +1,59 @@
import os
# toolchains options
ARCH ='risc-v'
VENDOR ='t-head'
CPU ='c906'
CROSS_TOOL ='gcc'
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = r'../..'
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'/opt/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin'
else:
print('Please make sure your toolchains is GNU GCC!')
exit(0)
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug'
if PLATFORM == 'gcc':
# toolchains
#PREFIX = 'riscv64-unknown-elf-'
PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-linux-musl-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcmodel=medany -march=rv64imafdc -mabi=lp64'
CFLAGS = DEVICE + ' -Wno-cpp -fvar-tracking -ffreestanding -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -D_POSIX_SOURCE '
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + ' -lsupc++ -lgcc -static'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -ggdb'
AFLAGS += ' -ggdb'
else:
CFLAGS += ' -O2 -Os'
CXXFLAGS = CFLAGS
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtthread.asm\n'
POST_ACTION = OBJCPY + ' -O binary $TARGET Image\n' + SIZE + ' $TARGET \n' + './mksdimg.sh\n'

View File

@ -18,6 +18,7 @@
#include "rt_interrupt.h"
#include "io.h"
#include "encoding.h"
#include "ioremap.h"
static void *c906_plic_regs = RT_NULL;
extern struct rt_irq_desc isr_table[];
@ -43,7 +44,7 @@ rt_inline void plic_irq_toggle(int hwirq, int enable)
#ifdef RT_USING_SMART
if (c906_irq_priority[hwirq] == RT_NULL)
{
c906_irq_priority[hwirq] = rt_ioremap(priority_addr, 0x1000);
c906_irq_priority[hwirq] = (void *)rt_ioremap(priority_addr, 0x1000);
}
priority_addr = c906_irq_priority[hwirq];
#endif
@ -202,8 +203,8 @@ void plic_init(void)
handler->hart_base = (void *)((rt_size_t)c906_plic_regs + CONTEXT_BASE + i * CONTEXT_PER_HART);
handler->enable_base = (void *)((rt_size_t)c906_plic_regs + ENABLE_BASE + i * ENABLE_PER_HART);
#ifdef RT_USING_SMART
handler->hart_base = rt_ioremap(handler->hart_base, 0x1000);
handler->enable_base = rt_ioremap(handler->enable_base, 0x1000);
handler->hart_base = (void *)rt_ioremap(handler->hart_base, 0x1000);
handler->enable_base = (void *)rt_ioremap(handler->enable_base, 0x1000);
#endif
done:
/* priority must be > threshold to trigger an interrupt */