Browse Source

surport qemu

crypto_algorithm
Huang_Yuqing 2 years ago
parent
commit
1c11b973d6
  1. 2
      Makefile
  2. 246
      board/hifive1-emulator/.defconfig
  3. 58
      board/hifive1-emulator/Kconfig
  4. 6
      board/hifive1-emulator/Makefile
  5. 76
      board/hifive1-emulator/README.md
  6. 70
      board/hifive1-emulator/board.c
  7. 82
      board/hifive1-emulator/board.h
  8. 20
      board/hifive1-emulator/config.mk
  9. BIN
      board/hifive1-emulator/img/menuconfig.png
  10. BIN
      board/hifive1-emulator/img/terminal.png
  11. 105
      board/hifive1-emulator/link.lds
  12. 73
      board/hifive1-emulator/link_userspace.lds
  13. 0
      board/hifive1-emulator/third_party_driver/Kconfig
  14. 206
      board/hifive1-emulator/third_party_driver/LICENSE
  15. 3
      board/hifive1-emulator/third_party_driver/Makefile
  16. 278
      board/hifive1-emulator/third_party_driver/connect_usart.c
  17. 102
      board/hifive1-emulator/third_party_driver/coreplexip-arty.h
  18. 1313
      board/hifive1-emulator/third_party_driver/encoding.h
  19. 252
      board/hifive1-emulator/third_party_driver/fe300prci/fe300prci_driver.c
  20. 79
      board/hifive1-emulator/third_party_driver/fe300prci/fe300prci_driver.h
  21. 81
      board/hifive1-emulator/third_party_driver/hifive1.h
  22. 36
      board/hifive1-emulator/third_party_driver/include/sifive/bits.h
  23. 18
      board/hifive1-emulator/third_party_driver/include/sifive/const.h
  24. 88
      board/hifive1-emulator/third_party_driver/include/sifive/devices/aon.h
  25. 14
      board/hifive1-emulator/third_party_driver/include/sifive/devices/clint.h
  26. 24
      board/hifive1-emulator/third_party_driver/include/sifive/devices/gpio.h
  27. 23
      board/hifive1-emulator/third_party_driver/include/sifive/devices/otp.h
  28. 31
      board/hifive1-emulator/third_party_driver/include/sifive/devices/plic.h
  29. 56
      board/hifive1-emulator/third_party_driver/include/sifive/devices/prci.h
  30. 37
      board/hifive1-emulator/third_party_driver/include/sifive/devices/pwm.h
  31. 80
      board/hifive1-emulator/third_party_driver/include/sifive/devices/spi.h
  32. 27
      board/hifive1-emulator/third_party_driver/include/sifive/devices/uart.h
  33. 17
      board/hifive1-emulator/third_party_driver/include/sifive/sections.h
  34. 65
      board/hifive1-emulator/third_party_driver/include/sifive/smp.h
  35. 263
      board/hifive1-emulator/third_party_driver/init.c
  36. 133
      board/hifive1-emulator/third_party_driver/platform.h
  37. 127
      board/hifive1-emulator/third_party_driver/plic/plic_driver.c
  38. 51
      board/hifive1-emulator/third_party_driver/plic/plic_driver.h
  39. 10
      path_kernel.mk

2
Makefile

@ -5,7 +5,7 @@ MAKEFLAGS += --no-print-directory
.PHONY:COMPILE_APP COMPILE_KERNEL
support :=kd233 stm32f407-st-discovery maix-go stm32f407zgt6 aiit-riscv64-board aiit-arm32-board hifive1-rev-B
support :=kd233 stm32f407-st-discovery maix-go stm32f407zgt6 aiit-riscv64-board aiit-arm32-board hifive1-rev-B hifive1-emulator
SRC_DIR:=
export BOARD ?=kd233

246
board/hifive1-emulator/.defconfig

@ -0,0 +1,246 @@
#
# Automatically generated file; DO NOT EDIT.
# XiUOS Project Configuration
#
CONFIG_BOARD_FE310_EVB=y
CONFIG_KERNEL_CONSOLE_DEVICE_NAME="uart0"
#CONFIG_LED0=24
#CONFIG_LED1=25
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_RISCV32=y
CONFIG_ARCH_CPU_32BIT=y
#
# hifive1 emulator feature
#
# CONFIG_BSP_USING_AUDIO is not set
# CONFIG_BSP_USING_CAMERA is not set
# CONFIG_BSP_USING_SDIO is not set
# CONFIG_BSP_USING_DMA is not set
CONFIG_BSP_USING_GPIO=y
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_I2S is not set
# CONFIG_BSP_USING_LCD is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_SECURITY is not set
# CONFIG_BSP_USING_SPI is not set
CONFIG_BSP_USING_UART=y
# CONFIG_BSP_USING_UART_HS is not set
# CONFIG_BSP_USING_VIDEO is not set
# CONFIG_BSP_USING_WDT is not set
#
# General Purpose UARTs
#
CONFIG___STACKSIZE__=1024
#
# Hardware feature
#
CONFIG_RESOURCES_SERIAL=y
# CONFIG_SERIAL_USING_DMA=y
CONFIG_SERIAL_RB_BUFSZ=64
CONFIG_FS_VFS=n
# CONFIG_RESOURCES_HWTIMER is not set
# CONFIG_RESOURCES_I2C is not set
# CONFIG_RESOURCES_LCD is not set
# CONFIG_RESOURCES_SDIO is not set
# CONFIG_RESOURCES_TOUCH is not set
# CONFIG_RESOURCES_PIN=y
# CONFIG_RESOURCES_RTC is not set
# CONFIG_RESOURCES_SPI is not set
#CONFIG_RESOURCES_SPI_SD is not set
#CONFIG_RESOURCES_SPI_SFUD is not set
# SFUD_USING_SFDP is not set
# SFUD_USING_FLASH_INFO_TABLE is not set
# SFUD_DEBUG_LOG is not set
# CONFIG_RESOURCES_WDT is not set
# CONFIG_RESOURCES_USB is not set
# CONFIG_RESOURCES_USB_HOST is not set
# CONFIG_UDISK_MOUNTPOINT is not set
# CONFIG_USBH_MSTORAGE is not set
# CONFIG_RESOURCES_USB_DEVICE is not set
# CONFIG_USBD_THREAD_STACK_SZ is not set
#
# Kernel feature
#
#
# Kernel Device Object
#
CONFIG_KERNEL_DEVICE=y
CONFIG_KERNEL_CONSOLE=y
CONFIG_KERNEL_CONSOLEBUF_SIZE=128
#
# Task feature
#
CONFIG_SCHED_POLICY_RR_REMAINSLICE=y
# CONFIG_SCHED_POLICY_RR is not set
# CONFIG_SCHED_POLICY_FIFO is not set
#
# Memory Management
#
# CONFIG_KERNEL_MEMBLOCK is not set
CONFIG_MEM_ALIGN_SIZE=4
CONFIG_MM_PAGE_SIZE=1024
#
# Using small memory allocator
#
# CONFIG_KERNEL_SMALL_MEM_ALLOC is not set
#
# Inter-Task communication
#
# CONFIG_KERNEL_SEMAPHORE=y
# CONFIG_KERNEL_MUTEX=y
CONFIG_KERNEL_EVENT=n
CONFIG_KERNEL_MESSAGEQUEUE=n
CONFIG_KTASK_PRIORITY_8=y
CONFIG_KTASK_PRIORITY_MAX=8
CONFIG_TICK_PER_SECOND=100
# CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y
CONFIG_KERNEL_BANNER=y
# CONFIG_KERNEL_HOOK is not set
# CONFIG_KERNEL_SOFTTIMER=y
# CONFIG_KERNEL_IDLE_HOOK=y
# CONFIG_IDEL_HOOK_LIST_SIZE=4
CONFIG_IDLE_KTASK_STACKSIZE=512
CONFIG_ZOMBIE_KTASK_STACKSIZE=512
# CONFIG_KERNEL_TASK_ISOLATION is not set
#
# Memory Management
#
# CONFIG_KERNEL_MEMBLOCK is not set
#
# Command shell
#
CONFIG_TOOL_SHELL=y
CONFIG_SHELL_TASK_PRIORITY=4
CONFIG_SHELL_TASK_STACK_SIZE=2048
#
# User Control
#
CONFIG_SHELL_DEFAULT_USER="letter"
CONFIG_SHELL_DEFAULT_USER_PASSWORD=""
CONFIG_SHELL_LOCK_TIMEOUT=10000
CONFIG_SHELL_ENTER_CR_AND_LF=y
# CONFIG_SHELL_ENTER_CRLF is not set
CONFIG_SHELL_ENTER_CR=y
CONFIG_SHELL_ENTER_LF=y
CONFIG_SHELL_MAX_NUMBER=5
CONFIG_SHELL_PARAMETER_MAX_NUMBER=8
CONFIG_SHELL_HISTORY_MAX_NUMBER=5
CONFIG_SHELL_PRINT_BUFFER=128
CONFIG_SHELL_USING_CMD_EXPORT=y
# CONFIG_SHELL_HELP_LIST_USER is not set
CONFIG_SHELL_HELP_SHOW_PERMISSION=y
# CONFIG_SHELL_HELP_LIST_VAR is not set
# CONFIG_SHELL_HELP_LIST_KEY is not set
#CONFIG_KERNEL_QUEUEMANAGE=y
# CONFIG_KERNEL_WORKQUEUE is not set
CONFIG_WORKQUEUE_KTASK_STACKSIZE=256
CONFIG_WORKQUEUE_KTASK_PRIORITY=2
CONFIG_QUEUE_MAX=2
CONFIG_KERNEL_WAITQUEUE=y
CONFIG_KERNEL_DATAQUEUE=y
# CONFIG_KERNEL_CIRCULAR_AREA is not set
# CONFIG_KERNEL_AVL_TREE is not set
CONFIG_NAME_MAX=32
CONFIG_ALIGN_SIZE=8
CONFIG_KERNEL_COMPONENTS_INIT=n
CONFIG_KERNEL_USER_MAIN=y
CONFIG_MAIN_KTASK_STACK_SIZE=1500
CONFIG_ENV_INIT_KTASK_STACK_SIZE=1024
CONFIG_MAIN_KTASK_PRIORITY=3
# CONFIG_USER_TEST is not set
# CONFIG_TOOL_TEST_SEM is not set
# CONFIG_TOOL_TEST_MUTEX is not set
# CONFIG_TOOL_TEST_EVENT is not set
# CONFIG_TOOL_TEST_MSG is not set
# CONFIG_TOOL_TEST_AVLTREE is not set
# CONFIG_TEST_CRICULAR_AREA is not set
# CONFIG_TOOL_TEST_MEM is not set
# CONFIG_TOOL_TEST_TIMER is not set
# CONFIG_TOOL_TEST_IWG is not set
# CONFIG_TOOL_TEST_REALTIME is not set
# CONFIG_TOOL_TEST_DBG is not set
# CONFIG_TOOL_TEST_SCHED is not set
# CONFIG_KERNEL_DEBUG is not set
#CONFIG_DEBUG_INIT_CONFIG=y
#CONFIG_DBG_INIT=1
#CONFIG_ARCH_SMP=y
#CONFIG_CPUS_NR=2
#
# hash table config
#
CONFIG_ID_HTABLE_SIZE=4
CONFIG_ID_NUM_MAX=16
#
# File system
#
CONFIG_FS_DFS=n
#CONFIG_DFS_USING_WORKDIR=y
#CONFIG_FS_DFS_DEVFS=y
#
# Fat filesystem
#
#
# IOT-Device File system
#
#
# Lwext4 filesystem
#
#
# APP Framework
#
#
# Perception
#
# CONFIG_PERCEPTION_SENSORDEVICE is not set
#
# connection
#
# CONFIG_CONNECTION_AT is not set
# CONFIG_CONNECTION_MQTT is not set
#
# medium communication
#
#
# Intelligence
#
#
# Control
#
#
# Lib
#
CONFIG_LIB=y
CONFIG_LIB_POSIX=y
CONFIG_LIB_NEWLIB=y
# CONFIG_LITTLEVGL2RTT_USING_DEMO=y
#
# Security
#

58
board/hifive1-emulator/Kconfig

@ -0,0 +1,58 @@
mainmenu "XiUOS Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config KERNEL_DIR
string
option env="KERNEL_ROOT"
default "../.."
config BOARD_FE310_EVB
bool
select ARCH_RISCV
select ARCH_RISCV32
select ARCH_CPU_32BIT
default y
config KERNEL_CONSOLE_DEVICE_NAME
string
default "uart0"
source "$KERNEL_DIR/arch/Kconfig"
menu "hifive1-emulator feature"
source "$BSP_DIR/third_party_driver/Kconfig"
menu "config default board resources"
menu "config board app name"
config BOARD_APP_NAME
string "config board app name"
default "/XiUOS_hifive1-emulator_app.bin"
endmenu
menu "config board service table"
config SERVICE_TABLE_ADDRESS
hex "board service table address"
default 0x2007F0000
endmenu
endmenu
config __STACKSIZE__
int "stack size for interrupt"
default 4096
endmenu
menu "Hardware feature"
source "$KERNEL_DIR/resources/Kconfig"
endmenu
source "$KERNEL_DIR/Kconfig"

6
board/hifive1-emulator/Makefile

@ -0,0 +1,6 @@
SRC_FILES := board.c
SRC_DIR := third_party_driver
include $(KERNEL_ROOT)/compiler.mk

76
board/hifive1-emulator/README.md

@ -0,0 +1,76 @@
# hifive1 emulator README
## 1. 简介
Q‎EMU 是一个通用的开源模拟器和虚拟化工具。‎从5.0版本开始,Q‎EMU已经可以较完整的支持RISC-V架构,同时支持SiFive的E系列核心。目前XiUOS同样支持运行在Q‎EMU上。
| 硬件 | 描述 |
| -- | -- |
|芯片型号| Hifive1-FE310 |
|架构| RV32IMAC |
|主频| NA |
|片内SRAM| 16KB |
| 外设支持 | UART |
XiUOS板级当前支持使用UART。
## 2. 编译说明
编译环境:Ubuntu18.04
编译工具链:[riscv-none-embed-gcc](https://github.com/ilg-archived/riscv-none-gcc/releases)
编译步骤:
>1.将编译工具链的路径添加到board/hifive1-emulator/config.mk文件当中,例如将gnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.1-20190425-1021-centos64.tgz解压到/opt/下时添加:
```
export CROSS_COMPILE ?=/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-
```
>2.在代码根目录下执行以下命令,生成配置文件
```
make BOARD=hifive1-emulator menuconfig
```
>3.在menuconfig界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后选择Exit保存并退出
![hifive1-Rev-B](img/menuconfig.png)
>4.继续执行以下命令,进行编译
```
make BOARD=hifive1-emulator
```
>5.如果编译正确无误,会在build目录下产生XiUOS_hifive1-emulator.elf、XiUOS_hifive1-emulator.bin文件。
>注:最后可以执行以下命令,清除配置文件和编译生成的文件
```
make BOARD=hifive1-emulator distclean
```
## 3. 运行
### 3.1 编译并安装Q‎EMU
官网下载Q‎EMU源码编译安装,推荐使用[Q‎EMU v5.2.0](https://download.qemu.org/qemu-5.2.0.tar.xz)版本,如果官网下载速度慢,也可从下面链接下载Q‎EMU v5.2.0源码压缩包[下载地址](https://download.qemu.org/qemu-5.2.0.tar.xz)
```
wget https://download.qemu.org/qemu-5.2.0.tar.xz
tar -xvf qemu-5.2.0.tar.xz
cd qemu-5.2.0
./configure --target-list=riscv32-softmmu
make
sudo make install
```
### 3.2 运行结果
通过以下命令启动Q‎EMU并加载XiUOS ELF文件
```
qemu-system-riscv32 -nographic -machine sifive_e -kernel build/XiUOS_hifive1-emulator.elf
```
QEMU运行起来后将会在终端上看到信息打印输出
![terminal](img/terminal.png)
### 3.3 调试
利用Q‎EMU可以方便的对XiUOS进行调试,首先通过以下命令启动Q‎EMU
```
qemu-system-riscv32 -nographic -machine sifive_e -kernel build/XiUOS_hifive1-emulator.elf -s -S
```
然后在另一个终端,执行riscv-none-embed-gdb命令
```
riscv-none-embed-gdb build/XiUOS_hifive1-emulator.elf -ex "target remote localhost:1234"
```

70
board/hifive1-emulator/board.c

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file board.c
* @brief support hifive1-rev-B-board init configure and start-up
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#include <board.h>
#include <platform.h>
#include <encoding.h>
#include <arch_interrupt.h>
#include <xiuos.h>
#include <device.h>
#include <plic_driver.h>
extern void use_default_clocks(void);
extern void use_pll(int refsel, int bypass, int r, int f, int q);
plic_instance_t g_plic = {0} ;
void InitBoardHardware(void)
{
/* initialize the system clock */
use_default_clocks();
use_pll(0, 0, 1, 31, 1);
/* initialize hardware interrupt */
asm volatile(
"la t0, save_hw_context\n"
"csrw mtvec, t0"
);
PLIC_init(&g_plic,
PLIC_CTRL_ADDR,
PLIC_NUM_INTERRUPTS,
PLIC_NUM_PRIORITIES);
SET_CSR(mie, MIP_MEIP);
/* initialize timer*/
CLINT_MTIMECMP_ADDR = CLINT_MTIME_ADDR + TICK;
SET_CSR(mie, MIP_MTIP);
extern int InitHwUart(void);
InitHwUart();
InstallConsole(SERIAL_BUS_NAME, SERIAL_DRV_NAME, SERIAL_DEVICE_NAME);
KPrintf("\nconsole init completed.\n");
KPrintf("board initialization......\n");
KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, MEMORY_SIZE);
/* initialize memory system */
InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS);
return;
}

82
board/hifive1-emulator/board.h

@ -0,0 +1,82 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file board.h
* @brief define hifive1-rev-B-board init configure and start-up function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <xsconfig.h>
#include <stdint.h>
#define TICK (RTC_FREQ / TICK_PER_SECOND)
#define CLINT_MTIME_ADDR (*((volatile uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIME)))
#define CLINT_MTIMECMP_ADDR (*((volatile uint64_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP)))
#define SERIAL_BUS_NAME "uart0"
#define SERIAL_DRV_NAME "uart0_drv"
#define SERIAL_DEVICE_NAME "uart0_dev0"
#define SURPORT_PMP
#ifdef SEPARATE_COMPILE
#define MEMORY_SIZE 12
#else
#define MEMORY_SIZE 16
#endif
extern void *_end;
extern void *_heap_end;
extern void *__stack_end__;
extern unsigned int g_service_table_start;
extern unsigned int g_service_table_end;
#define MEMORY_START_ADDRESS (void *)&__stack_end__
#define MEMORY_END_ADDRESS (void *)( 0x80000000 + MEMORY_SIZE * 1024 )
#ifdef SEPARATE_COMPILE
typedef int (*main_t)(int argc, char *argv[]);
typedef void (*exit_t)(void);
struct UserSpaceS
{
main_t us_entrypoint;
exit_t us_taskquit;
uintptr_t us_textstart;
uintptr_t us_textend;
uintptr_t us_datasource;
uintptr_t us_datastart;
uintptr_t us_dataend;
uintptr_t us_bssstart;
uintptr_t us_bssend;
uintptr_t us_heapend;
};
#define USERSPACE (( struct UserSpaceS *)(0x20080000))
#ifndef SERVICE_TABLE_ADDRESS
#define SERVICE_TABLE_ADDRESS (0x2007F0000) //in flash
#endif
#define USER_SRAM_SIZE 4
#define USER_MEMORY_START_ADDRESS (USERSPACE->us_bssend)
#define USER_MEMORY_END_ADDRESS (0x80003000 + USER_SRAM_SIZE * 1024)
#endif
#endif

20
board/hifive1-emulator/config.mk

@ -0,0 +1,20 @@
export CFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb -fgnu89-inline
export AFLAGS := -c -mcmodel=medany -march=rv32imac -mabi=ilp32 -x assembler-with-cpp -ggdb
export LFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiUOS.map,-cref,-u,_start -T $(BSP_ROOT)/link.lds
export APPLFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiUOS_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
export CXXFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb
export CROSS_COMPILE ?=/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-
export DEFINES := -DHAVE_CCONFIG_H -DHAVE_SIGINFO
export ARCH = risc-v
export MCU = FE310
# export HAVE_SIGINFO=1
# export USING_LORA = 1

BIN
board/hifive1-emulator/img/menuconfig.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
board/hifive1-emulator/img/terminal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

105
board/hifive1-emulator/link.lds

@ -0,0 +1,105 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
OUTPUT_ARCH( "riscv" )
__STACKSIZE__ = 1024;
ENTRY( _begin )
MEMORY
{
flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 4096K
sram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K
}
SECTIONS
{
.start :
{
*(.init);
} > flash
.text :
{
*(.text .text.*)
*(.rodata .rodata*)
/* section information for shell */
. = ALIGN(8);
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
. = ALIGN(8);
/* the work i did */
PROVIDE(__ctors_start__ = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE(__ctors_end__ = .);
. = ALIGN(4);
__isrtbl_idx_start = .;
KEEP(*(.isrtbl.idx))
__isrtbl_start = .;
KEEP(*(.isrtbl))
__isrtbl_end = .;
. = ALIGN(8);
PROVIDE(g_service_table_start = ABSOLUTE(.));
KEEP(*(.g_service_table))
PROVIDE(g_service_table_end = ABSOLUTE(.));
} > flash
PROVIDE (_etext = .);
. = ALIGN(4);
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash
.data :
{
. = ALIGN(4);
PROVIDE( _data = . );
*(.data .data.*)
. = ALIGN(4);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
} >sram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.bss .bss.*)
*(.scommon)
. = ALIGN(4);
} > sram
. = ALIGN(8);
PROVIDE( _end = . );
.stack :
{
. = ALIGN(4);
/* cpu0 stack top site */
. = . + __STACKSIZE__;
_sp = . ;
PROVIDE(_sp = ABSOLUTE(.));
PROVIDE( __stack_end__ = ABSOLUTE(.) );
} > sram
}

73
board/hifive1-emulator/link_userspace.lds

@ -0,0 +1,73 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
OUTPUT_ARCH("riscv")
MEMORY
{
uflash (rx) : ORIGIN = 0x20080000, LENGTH = 512k /* 512KB uflash */
usram (rw) : ORIGIN = 0x80003000, LENGTH = 4k /* 4K usram */
}
SECTIONS
{
.userspace :
{
. = ALIGN(4);
KEEP(*(.userspace))
} > uflash
.text :
{
_ustext = ABSOLUTE(.);
*(.text .text.*)
*(.rodata .rodata*)
*(.glue_7)
*(.glue_7t)
PROVIDE(_uetext = ABSOLUTE(.));
} > uflash
.init_section : {
_sinit = ABSOLUTE(.);
KEEP(*(.init_array .init_array.*))
_einit = ABSOLUTE(.);
} > uflash
__uexidx_start = ABSOLUTE(.);
.ARM.exidx :
{
PROVIDE(__uexidx_start = ABSOLUTE(.));
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
PROVIDE(__uexidx_end = ABSOLUTE(.));
} > uflash
_ueronly = ABSOLUTE(.);
.data : AT(_ueronly)
{
_usdata = ABSOLUTE(.);
*(.data .data.*)
. = ALIGN(4);
_uedata = ABSOLUTE(.);
} > usram
.bss : {
. = ALIGN(4);
_usbss = ABSOLUTE(.);
*(.bss .bss.*)
*(.sbss .sbss.*)
. = ALIGN(4);
_uebss = ABSOLUTE(.);
} > usram
}

0
board/hifive1-emulator/third_party_driver/Kconfig

206
board/hifive1-emulator/third_party_driver/LICENSE

@ -0,0 +1,206 @@
This software, except as otherwise noted in subrepositories,
is licensed under the Apache 2 license, quoted below.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 SiFive, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

3
board/hifive1-emulator/third_party_driver/Makefile

@ -0,0 +1,3 @@
SRC_FILES := connect_usart.c plic/plic_driver.c fe300prci/fe300prci_driver.c init.c
include $(KERNEL_ROOT)/compiler.mk

278
board/hifive1-emulator/third_party_driver/connect_usart.c

@ -0,0 +1,278 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_usart.c
* @brief support aiit-arm32-board usart function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#include <xiuos.h>
#include <device.h>
#include <encoding.h>
#include <platform.h>
#include <arch_interrupt.h>
#include <uart.h>
#include <board.h>
static void SerialCfgParamCheck(struct SerialCfgParam *serial_cfg_default, struct SerialCfgParam *serial_cfg_new)
{
struct SerialDataCfg *data_cfg_default = &serial_cfg_default->data_cfg;
struct SerialDataCfg *data_cfg_new = &serial_cfg_new->data_cfg;
if((data_cfg_default->serial_baud_rate != data_cfg_new->serial_baud_rate) && (data_cfg_new->serial_baud_rate))
{
data_cfg_default->serial_baud_rate = data_cfg_new->serial_baud_rate;
}
if((data_cfg_default->serial_bit_order != data_cfg_new->serial_bit_order) && (data_cfg_new->serial_bit_order))
{
data_cfg_default->serial_bit_order = data_cfg_new->serial_bit_order;
}
if((data_cfg_default->serial_buffer_size != data_cfg_new->serial_buffer_size) && (data_cfg_new->serial_buffer_size))
{
data_cfg_default->serial_buffer_size = data_cfg_new->serial_buffer_size;
}
if((data_cfg_default->serial_data_bits != data_cfg_new->serial_data_bits) && (data_cfg_new->serial_data_bits))
{
data_cfg_default->serial_data_bits = data_cfg_new->serial_data_bits;
}
if((data_cfg_default->serial_invert_mode != data_cfg_new->serial_invert_mode) && (data_cfg_new->serial_invert_mode))
{
data_cfg_default->serial_invert_mode = data_cfg_new->serial_invert_mode;
}
if((data_cfg_default->serial_parity_mode != data_cfg_new->serial_parity_mode) && (data_cfg_new->serial_parity_mode))
{
data_cfg_default->serial_parity_mode = data_cfg_new->serial_parity_mode;
}
if((data_cfg_default->serial_stop_bits != data_cfg_new->serial_stop_bits) && (data_cfg_new->serial_stop_bits))
{
data_cfg_default->serial_stop_bits = data_cfg_new->serial_stop_bits;
}
}
static void usart_handler(int vector, void *param)
{
struct SerialBus *serial_bus = (struct SerialBus *)param;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_bus->bus.owner_haldev;
SerialSetIsr(serial_dev, SERIAL_EVENT_RX_IND);
}
static uint32 SerialInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(serial_drv);
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
if(configure_info->private_data)
{
struct SerialCfgParam *serial_cfg_new = (struct SerialCfgParam *)configure_info->private_data;
SerialCfgParamCheck(serial_cfg, serial_cfg_new);
}
GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK;
GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK;
UART0_REG(UART_REG_DIV) = get_cpu_freq() / serial_cfg->data_cfg.serial_baud_rate - 1;
UART0_REG(UART_REG_TXCTRL) |= UART_TXEN;
UART0_REG(UART_REG_RXCTRL) |= UART_RXEN;
UART0_REG(UART_REG_IE) = UART_IP_RXWM;
return EOK;
}
static uint32 SerialConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd)
{
NULL_PARAM_CHECK(serial_drv);
return EOK;
}
static uint32 SerialDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
int serial_operation_cmd;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = SerialInit(serial_drv, configure_info);
break;
case OPE_CFG:
serial_operation_cmd = *(int *)configure_info->private_data;
ret = SerialConfigure(serial_drv, serial_operation_cmd);
break;
default:
break;
}
return ret;
}
static int SerialPutChar(struct SerialHardwareDevice *serial_dev, char c)
{
while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ;
UART0_REG(UART_REG_TXFIFO) = c;
return 0;
}
static int SerialGetChar(struct SerialHardwareDevice *serial_dev)
{
int32_t val = UART0_REG(UART_REG_RXFIFO);
if (val > 0)
return (uint8_t)val;
else
return -1;
}
static const struct SerialDataCfg data_cfg_init =
{
.serial_baud_rate = BAUD_RATE_115200,
.serial_data_bits = DATA_BITS_8,
.serial_stop_bits = STOP_BITS_1,
.serial_parity_mode = PARITY_NONE,
.serial_bit_order = BIT_ORDER_LSB,
.serial_invert_mode = NRZ_NORMAL,
.serial_buffer_size = SERIAL_RB_BUFSZ,
};
/*manage the serial device operations*/
static const struct SerialDrvDone drv_done =
{
.init = SerialInit,
.configure = SerialConfigure,
};
/*manage the serial device hal operations*/
static struct SerialHwDevDone hwdev_done =
{
.put_char = SerialPutChar,
.get_char = SerialGetChar,
};
static int BoardSerialBusInit(struct SerialBus *serial_bus, struct SerialDriver *serial_driver, const char *bus_name, const char *drv_name)
{
x_err_t ret = EOK;
/*Init the serial bus */
ret = SerialBusInit(serial_bus, bus_name);
if(EOK != ret)
{
KPrintf("InitHwUart SerialBusInit error %d\n", ret);
return ERROR;
}
/*Init the serial driver*/
ret = SerialDriverInit(serial_driver, drv_name);
if(EOK != ret)
{
KPrintf("InitHwUart SerialDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the serial driver to the serial bus*/
ret = SerialDriverAttachToBus(drv_name, bus_name);
if(EOK != ret)
{
KPrintf("InitHwUart SerialDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the serial device to the serial bus*/
static int BoardSerialDevBend(struct SerialHardwareDevice *serial_device, void *serial_param, const char *bus_name, const char *dev_name)
{
x_err_t ret = EOK;
ret = SerialDeviceRegister(serial_device, serial_param, dev_name);
if(EOK != ret)
{
KPrintf("InitHwUart SerialDeviceInit device %s error %d\n", dev_name, ret);
return ERROR;
}
ret = SerialDeviceAttachToBus(dev_name, bus_name);
if(EOK != ret)
{
KPrintf("InitHwUart SerialDeviceAttachToBus device %s error %d\n", dev_name, ret);
return ERROR;
}
return ret;
}
int InitHwUart(void)
{
x_err_t ret = EOK;
static struct SerialBus serial_bus;
memset(&serial_bus, 0, sizeof(struct SerialBus));
static struct SerialDriver serial_driver;
memset(&serial_driver, 0, sizeof(struct SerialDriver));
static struct SerialHardwareDevice serial_device;
memset(&serial_device, 0, sizeof(struct SerialHardwareDevice));
static struct SerialCfgParam serial_cfg;
memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
static struct SerialDevParam serial_dev_param;
memset(&serial_dev_param, 0, sizeof(struct SerialDevParam));
serial_driver.drv_done = &drv_done;
serial_driver.configure = &SerialDrvConfigure;
serial_device.hwdev_done = &hwdev_done;
serial_cfg.data_cfg = data_cfg_init;
serial_cfg.hw_cfg.serial_register_base = UART0_CTRL_ADDR;
serial_cfg.hw_cfg.serial_irq_interrupt = INT_UART0_BASE;
serial_driver.private_data = (void *)&serial_cfg;
serial_dev_param.serial_work_mode = SIGN_OPER_INT_RX;
serial_device.haldev.private_data = (void *)&serial_dev_param;
ret = BoardSerialBusInit(&serial_bus, &serial_driver, SERIAL_BUS_NAME, SERIAL_DRV_NAME);
if(EOK != ret)
{
KPrintf("InitHwUart uarths error ret %u\n", ret);
return ERROR;
}
ret = BoardSerialDevBend(&serial_device, (void *)&serial_cfg, SERIAL_BUS_NAME, SERIAL_DEVICE_NAME);
if(EOK != ret)
{
KPrintf("InitHwUart uarths error ret %u\n", ret);
return ERROR;
}
isrManager.done->registerIrq(serial_cfg.hw_cfg.serial_irq_interrupt, usart_handler, &serial_bus);
isrManager.done->enableIrq(serial_cfg.hw_cfg.serial_irq_interrupt);
return ret;
}

102
board/hifive1-emulator/third_party_driver/coreplexip-arty.h

@ -0,0 +1,102 @@
// See LICENSE for license details.
#ifndef _SIFIVE_COREPLEXIP_ARTY_H
#define _SIFIVE_COREPLEXIP_ARTY_H
#include <stdint.h>
/****************************************************************************
* GPIO Connections
*****************************************************************************/
// These are the GPIO bit offsets for the directly driven
// RGB LEDs on the Freedom Exx Coreplex IP Evaluation Arty FPGA Dev Kit.
// Additional RGB LEDs are driven by the 3 PWM outputs.
#define RED_LED_OFFSET 0
#define GREEN_LED_OFFSET 1
#define BLUE_LED_OFFSET 2
// Switch 3 is used as a GPIO input. (Switch 0 is used to set
// the reset vector, the other switches are unused).
#define SW_3_OFFSET 3
// These are the buttons which are mapped as inputs.
#define HAS_BOARD_BUTTONS
#define BUTTON_0_OFFSET 4
#define BUTTON_1_OFFSET 5
#define BUTTON_2_OFFSET 6
#define BUTTON_3_OFFSET 7
// These are the bit offsets for the different GPIO pins
// mapped onto the PMOD A header.
#define JA_0_OFFSET 8
#define JA_1_OFFSET 9
#define JA_2_OFFSET 10
#define JA_3_OFFSET 11
#define JA_4_OFFSET 12
#define JA_5_OFFSET 13
#define JA_6_OFFSET 14
#define JA_7_OFFSET 15
// The below gives a mapping between global interrupt
// sources and their number. Note that on the coreplex
// deliverable, the io_global_interrupts go directly into
// the PLIC. The evaluation image on the FPGA mimics a
// system with peripheral devices which are driving the
// global interrupt lines.
// So, on this image, in order to get an interrupt from
// e.g. pressing BUTTON_0:
// 1) Steps which are external to the delivery coreplex:
// a) The corresponding GPIO pin must be configured as in input
// b) The "interrupt on fall" bit must be set for the GPIO pin
// 2) Steps which would also need to be performed for the delivery coreplex:
// a) The corresponding global interrupt, priority, and threshold must be configured in the PLIC.
// b) The external interrupt bit must be enabled in MSTATUS
// c) Interrupts must be enabled globally in the core.
// Any of the above GPIO pins can be used as global interrupt
// sources by adding their offset to the INT_GPIO_BASE.
// For example, the buttons are shown here:
#define INT_DEVICE_BUTTON_0 (GPIO_INT_BASE + BUTTON_0_OFFSET)
#define INT_DEVICE_BUTTON_1 (GPIO_INT_BASE + BUTTON_1_OFFSET)
#define INT_DEVICE_BUTTON_2 (GPIO_INT_BASE + BUTTON_2_OFFSET)
#define INT_DEVICE_BUTTON_3 (GPIO_INT_BASE + BUTTON_3_OFFSET)
// In addition, the Switches are mapped directly to
// the PLIC (without going through the GPIO Peripheral).
#define INT_EXT_DEVICE_SW_0 (EXTERNAL_INT_BASE + 0)
#define INT_EXT_DEVICE_SW_1 (EXTERNAL_INT_BASE + 1)
#define INT_EXT_DEVICE_SW_2 (EXTERNAL_INT_BASE + 2)
#define INT_EXT_DEVICE_SW_3 (EXTERNAL_INT_BASE + 3)
// This gives the mapping from inputs to LOCAL interrupts.
#define LOCAL_INT_SW_0 0
#define LOCAL_INT_SW_1 1
#define LOCAL_INT_SW_2 2
#define LOCAL_INT_SW_3 3
#define LOCAL_INT_BTN_0 4
#define LOCAL_INT_BTN_1 5
#define LOCAL_INT_BTN_2 6
#define LOCAL_INT_BTN_3 7
#define LOCAL_INT_JA_0 8
#define LOCAL_INT_JA_1 9
#define LOCAL_INT_JA_2 10
#define LOCAL_INT_JA_3 11
#define LOCAL_INT_JA_4 12
#define LOCAL_INT_JA_5 13
#define LOCAL_INT_JA_6 14
#define LOCAL_INT_JA_7 15
#define RTC_FREQ 32768
void write_hex(int fd, unsigned long int hex);
#endif /* _SIFIVE_COREPLEXIP_ARTY_H */

1313
board/hifive1-emulator/third_party_driver/encoding.h

File diff suppressed because it is too large

252
board/hifive1-emulator/third_party_driver/fe300prci/fe300prci_driver.c

@ -0,0 +1,252 @@
// See LICENSE file for license details
#include "platform.h"
#ifdef PRCI_CTRL_ADDR
#include "fe300prci/fe300prci_driver.h"
#include <unistd.h>
#define rdmcycle(x) { \
uint32_t lo, hi, hi2; \
__asm__ __volatile__ ("1:\n\t" \
"csrr %0, mcycleh\n\t" \
"csrr %1, mcycle\n\t" \
"csrr %2, mcycleh\n\t" \
"bne %0, %2, 1b\n\t" \
: "=r" (hi), "=r" (lo), "=r" (hi2)) ; \
*(x) = lo | ((uint64_t) hi << 32); \
}
uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq)
{
uint32_t start_mtime = CLINT_REG(CLINT_MTIME);
uint32_t end_mtime = start_mtime + mtime_ticks + 1;
// Make sure we won't get rollover.
while (end_mtime < start_mtime){
start_mtime = CLINT_REG(CLINT_MTIME);
end_mtime = start_mtime + mtime_ticks + 1;
}
// Don't start measuring until mtime edge.
uint32_t tmp = start_mtime;
do {
start_mtime = CLINT_REG(CLINT_MTIME);
} while (start_mtime == tmp);
uint64_t start_mcycle;
rdmcycle(&start_mcycle);
while (CLINT_REG(CLINT_MTIME) < end_mtime) ;
uint64_t end_mcycle;
rdmcycle(&end_mcycle);
uint32_t difference = (uint32_t) (end_mcycle - start_mcycle);
uint64_t freq = ((uint64_t) difference * mtime_freq) / mtime_ticks;
return (uint32_t) freq & 0xFFFFFFFF;
}
void PRCI_use_hfrosc(int div, int trim)
{
// Make sure the HFROSC is running at its default setting
// It is OK to change this even if we are running off of it.
PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1));
while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0);
PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1);
}
void PRCI_use_pll(int refsel, int bypass,
int r, int f, int q, int finaldiv,
int hfroscdiv, int hfrosctrim)
{
// Ensure that we aren't running off the PLL before we mess with it.
if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) {
// Make sure the HFROSC is running at its default setting
PRCI_use_hfrosc(4, 16);
}
// Set PLL Source to be HFXOSC if desired.
uint32_t config_value = 0;
config_value |= PLL_REFSEL(refsel);
if (bypass) {
// Bypass
config_value |= PLL_BYPASS(1);
PRCI_REG(PRCI_PLLCFG) = config_value;
// If we don't have an HFXTAL, this doesn't really matter.
// Set our Final output divide to divide-by-1:
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
} else {
// To overclock, use the hfrosc
if (hfrosctrim >= 0 && hfroscdiv >= 0) {
PRCI_use_hfrosc(hfroscdiv, hfrosctrim);
}
// Set DIV Settings for PLL
// (Legal values of f_REF are 6-48MHz)
// Set DIVR to divide-by-2 to get 8MHz frequency
// (legal values of f_R are 6-12 MHz)
config_value |= PLL_BYPASS(1);
config_value |= PLL_R(r);
// Set DIVF to get 512Mhz frequncy
// There is an implied multiply-by-2, 16Mhz.
// So need to write 32-1
// (legal values of f_F are 384-768 MHz)
config_value |= PLL_F(f);
// Set DIVQ to divide-by-2 to get 256 MHz frequency
// (legal values of f_Q are 50-400Mhz)
config_value |= PLL_Q(q);
// Set our Final output divide to divide-by-1:
if (finaldiv == 1){
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
} else {
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV(finaldiv-1));
}
PRCI_REG(PRCI_PLLCFG) = config_value;
// Un-Bypass the PLL.
PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
// Wait for PLL Lock
// Note that the Lock signal can be glitchy.
// Need to wait 100 us
// RTC is running at 32kHz.
// So wait 4 ticks of RTC.
uint32_t now = CLINT_REG(CLINT_MTIME);
while (CLINT_REG(CLINT_MTIME) - now < 4) ;
// Now it is safe to check for PLL Lock
while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0);
}
// Switch over to PLL Clock source
PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1);
// If we're running off HFXOSC, turn off the HFROSC to
// save power.
if (refsel) {
PRCI_REG(PRCI_HFROSCCFG) &= ~ROSC_EN(1);
}
}
void PRCI_use_default_clocks()
{
// Turn off the LFROSC
AON_REG(AON_LFROSC) &= ~ROSC_EN(1);
// Use HFROSC
PRCI_use_hfrosc(4, 16);
}
void PRCI_use_hfxosc(uint32_t finaldiv)
{
PRCI_use_pll(1, // Use HFXTAL
1, // Bypass = 1
0, // PLL settings don't matter
0, // PLL settings don't matter
0, // PLL settings don't matter
finaldiv,
-1,
-1);
}
// This is a generic function, which
// doesn't span the entire range of HFROSC settings.
// It only adjusts the trim, which can span a hundred MHz or so.
// This function does not check the legality of the PLL settings
// at all, and it is quite possible to configure invalid PLL settings
// this way.
// It returns the actual measured CPU frequency.
uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu, PRCI_freq_target target )
{
uint32_t hfrosctrim = 0;
uint32_t hfroscdiv = 4;
uint32_t prev_trim = 0;
// In this function we use PLL settings which
// will give us a 32x multiplier from the output
// of the HFROSC source to the output of the
// PLL. We first measure our HFROSC to get the
// right trim, then finally use it as the PLL source.
// We should really check here that the f_cpu
// requested is something in the limit of the PLL. For
// now that is up to the user.
// This will undershoot for frequencies not divisible by 16.
uint32_t desired_hfrosc_freq = (f_cpu/ 16);
PRCI_use_hfrosc(hfroscdiv, hfrosctrim);
// Ignore the first run (for icache reasons)
uint32_t cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ);
cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ);
uint32_t prev_freq = cpu_freq;
while ((cpu_freq < desired_hfrosc_freq) && (hfrosctrim < 0x1F)){
prev_trim = hfrosctrim;
prev_freq = cpu_freq;
hfrosctrim ++;
PRCI_use_hfrosc(hfroscdiv, hfrosctrim);
cpu_freq = PRCI_measure_mcycle_freq(3000, RTC_FREQ);
}
// We couldn't go low enough
if (prev_freq > desired_hfrosc_freq){
PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim);
cpu_freq = PRCI_measure_mcycle_freq(1000, RTC_FREQ);
return cpu_freq;
}
// We couldn't go high enough
if (cpu_freq < desired_hfrosc_freq){
PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim);
cpu_freq = PRCI_measure_mcycle_freq(1000, RTC_FREQ);
return cpu_freq;
}
// Check for over/undershoot
switch(target) {
case(PRCI_FREQ_CLOSEST):
if ((desired_hfrosc_freq - prev_freq) < (cpu_freq - desired_hfrosc_freq)) {
PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim);
} else {
PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, hfrosctrim);
}
break;
case(PRCI_FREQ_UNDERSHOOT):
PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, prev_trim);
break;
default:
PRCI_use_pll(0, 0, 1, 31, 1, 1, hfroscdiv, hfrosctrim);
}
cpu_freq = PRCI_measure_mcycle_freq(1000, RTC_FREQ);
return cpu_freq;
}
#endif

79
board/hifive1-emulator/third_party_driver/fe300prci/fe300prci_driver.h

@ -0,0 +1,79 @@
// See LICENSE file for license details
#ifndef _FE300PRCI_DRIVER_H_
#define _FE300PRCI_DRIVER_H_
//__BEGIN_DECLS
#include <unistd.h>
typedef enum prci_freq_target {
PRCI_FREQ_OVERSHOOT,
PRCI_FREQ_CLOSEST,
PRCI_FREQ_UNDERSHOOT
} PRCI_freq_target;
/* Measure and return the approximate frequency of the
* CPU, as given by measuring the mcycle counter against
* the mtime ticks.
*/
uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq);
/* Safely switch over to the HFROSC using the given div
* and trim settings.
*/
void PRCI_use_hfrosc(int div, int trim);
/* Safely switch over to the 16MHz HFXOSC,
* applying the finaldiv clock divider (1 is the lowest
* legal value).
*/
void PRCI_use_hfxosc(uint32_t finaldiv);
/* Safely switch over to the PLL using the given
* settings.
*
* Note that not all combinations of the inputs are actually
* legal, and this function does not check for their
* legality ("safely" means that this function won't turn off
* or glitch the clock the CPU is actually running off, but
* doesn't protect against you making it too fast or slow.)
*/
void PRCI_use_pll(int refsel, int bypass,
int r, int f, int q, int finaldiv,
int hfroscdiv, int hfrosctrim);
/* Use the default clocks configured at reset.
* This is ~16Mhz HFROSC and turns off the LFROSC
* (on the current FE310 Dev Platforms, an external LFROSC is
* used as it is more power efficient).
*/
void PRCI_use_default_clocks();
/* This routine will adjust the HFROSC trim
* while using HFROSC as the clock source,
* measure the resulting frequency, then
* use it as the PLL clock source,
* in an attempt to get over, under, or close to the
* requested frequency. It returns the actual measured
* frequency.
*
* Note that the requested frequency must be within the
* range supported by the PLL so not all values are
* achievable with this function, and not all
* are guaranteed to actually work. The PLL
* is rated higher than the hardware.
*
* There is no check on the desired f_cpu frequency, it
* is up to the user to specify something reasonable.
*/
uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu, PRCI_freq_target target);
//__END_DECLS
#endif

81
board/hifive1-emulator/third_party_driver/hifive1.h

@ -0,0 +1,81 @@
// See LICENSE for license details.
#ifndef _SIFIVE_HIFIVE1_H
#define _SIFIVE_HIFIVE1_H
#include <stdint.h>
/****************************************************************************
* GPIO Connections
*****************************************************************************/
// These are the GPIO bit offsets for the RGB LED on HiFive1 Board.
// These are also mapped to RGB LEDs on the Freedom E300 Arty
// FPGA
// Dev Kit.
#define RED_LED_OFFSET 22
#define GREEN_LED_OFFSET 19
#define BLUE_LED_OFFSET 21
// These are the GPIO bit offsets for the differen digital pins
// on the headers for both the HiFive1 Board and the Freedom E300 Arty FPGA Dev Kit.
#define PIN_0_OFFSET 16
#define PIN_1_OFFSET 17
#define PIN_2_OFFSET 18
#define PIN_3_OFFSET 19
#define PIN_4_OFFSET 20
#define PIN_5_OFFSET 21
#define PIN_6_OFFSET 22
#define PIN_7_OFFSET 23
#define PIN_8_OFFSET 0
#define PIN_9_OFFSET 1
#define PIN_10_OFFSET 2
#define PIN_11_OFFSET 3
#define PIN_12_OFFSET 4
#define PIN_13_OFFSET 5
//#define PIN_14_OFFSET 8 //This pin is not connected on either board.
#define PIN_15_OFFSET 9
#define PIN_16_OFFSET 10
#define PIN_17_OFFSET 11