soc: riscv: add initial support of andes_v5 soc series

Add andes_v5 SoC series and andes_ae350 SoC. It includes
soc initialization code, linker script, and custom CSR encoding.

Signed-off-by: Jim Shu <cwshu@andestech.com>
This commit is contained in:
Jim Shu 2021-07-29 10:48:41 +08:00 committed by Anas Nashif
commit 62a30eba86
11 changed files with 691 additions and 0 deletions

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_include_directories(${CONFIG_SOC})
zephyr_sources(
start.S
)

View file

@ -0,0 +1,21 @@
# Copyright (c) 2021 Andes Technology Corporation
# SPDX-License-Identifier: Apache-2.0
if SOC_RISCV_ANDES_AE350
config SOC
default "ae350"
config SYS_CLOCK_TICKS_PER_SEC
default 100 if !CACHE_ENABLE
config MAIN_STACK_SIZE
default 2048
config IDLE_STACK_SIZE
default 1536
config TEST_EXTRA_STACKSIZE
default 1024
endif # SOC_RISCV_ANDES_AE350

View file

@ -0,0 +1,44 @@
# Copyright (c) 2021 Andes Technology Corporation
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_RISCV_ANDES_V5
# Kconfig picks the first default with a satisfied condition.
# SoC defaults should be parsed before SoC Series defaults, because SoCs usually
# overrides SoC Series values.
source "soc/riscv/riscv-privilege/andes_v5/Kconfig.defconfig.ae*"
config SOC_SERIES
default "andes_v5"
config SYS_CLOCK_HW_CYCLES_PER_SEC
default 60000000
config KERNEL_ENTRY
default "entry"
config RISCV_SOC_INTERRUPT_INIT
default y
config RISCV_HAS_CPU_IDLE
default y
config RISCV_HAS_PLIC
default y
config RISCV_GP
default y
config 2ND_LVL_ISR_TBL_OFFSET
default 12
config 2ND_LVL_INTR_00_OFFSET
default 11
config MAX_IRQ_PER_AGGREGATOR
default 52
config NUM_IRQS
default 64
endif # SOC_SERIES_RISCV_ANDES_V5

View file

@ -0,0 +1,9 @@
# Copyright (c) 2021 Andes Technology Corporation
# SPDX-License-Identifier: Apache-2.0
config SOC_SERIES_RISCV_ANDES_V5
bool "Andes V5 SoC Series Implementation"
select RISCV
select SOC_FAMILY_RISCV_PRIVILEGE
help
Enable support for Andes V5 SoC Series

View file

@ -0,0 +1,50 @@
# Copyright (c) 2021 Andes Technology Corporation
# SPDX-License-Identifier: Apache-2.0
choice
prompt "Andes V5 SoC Selection"
depends on SOC_SERIES_RISCV_ANDES_V5
config SOC_RISCV_ANDES_AE350
bool "Andes AE350 SoC implementation"
select ATOMIC_OPERATIONS_BUILTIN
endchoice
if SOC_SERIES_RISCV_ANDES_V5
choice
prompt "Base CPU ISA options"
default RV32I_CPU
config RV32I_CPU
bool "RISCV32 CPU ISA"
config RV64I_CPU
bool "RISCV64 CPU ISA"
select 64BIT
endchoice
choice
prompt "FPU options"
default NO_FPU
config NO_FPU
bool "No FPU"
config SINGLE_PRECISION_FPU
bool "Single precision FPU"
select CPU_HAS_FPU
config DOUBLE_PRECISION_FPU
bool "Double precision FPU"
select CPU_HAS_FPU_DOUBLE_PRECISION
endchoice
config CACHE_ENABLE
bool "Enable cache"
default n
endif # SOC_SERIES_RISCV_ANDES_V5

View file

@ -0,0 +1,358 @@
/*
* Copyright (c) 2016-2017 Jean-Paul Etienne <fractalclone@gmail.com>
* Copyright (c) 2021 Andes Technology Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the ae350 platform
*/
#include <soc.h>
#include <devicetree.h>
#include <autoconf.h>
#include <linker/sections.h>
#include <linker/devicetree_regions.h>
#include <linker/linker-defs.h>
#include <linker/linker-tool.h>
#ifdef CONFIG_XIP
#define ROMABLE_REGION ROM
#else
#define ROMABLE_REGION RAM
#endif
#define RAMABLE_REGION RAM
#define _VECTOR_SECTION_NAME vector
#define _EXCEPTION_SECTION_NAME exceptions
#define _RESET_SECTION_NAME reset
#ifdef CONFIG_XIP
#if DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), soc_nv_flash, okay)
#ifdef CONFIG_FLASH_LOAD_OFFSET
#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + \
CONFIG_FLASH_LOAD_OFFSET)
#else /* !CONFIG_FLASH_LOAD_OFFSET */
#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash))
#endif /* CONFIG_FLASH_LOAD_OFFSET */
#define ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash))
#elif DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), jedec_spi_nor, okay)
/* For jedec,spi-nor we expect the spi controller to memory map the flash
* and for that mapping to be the second register property of the spi
* controller.
*/
#define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash))
#define ROM_BASE DT_REG_ADDR_BY_IDX(SPI_CTRL, 1)
#define ROM_SIZE DT_REG_SIZE_BY_IDX(SPI_CTRL, 1)
#endif
#else /* CONFIG_XIP */
#define ROM_BASE CONFIG_SRAM_BASE_ADDRESS
#define ROM_SIZE KB(CONFIG_SRAM_SIZE)
#endif /* CONFIG_XIP */
#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS
#define RAM_SIZE KB(CONFIG_SRAM_SIZE)
MEMORY
{
#ifdef CONFIG_XIP
ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
#endif
RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE
/* Data & Instruction Tightly Coupled Memory */
LINKER_DT_REGION_FROM_NODE(ITCM, rw, DT_CHOSEN(zephyr_itcm))
LINKER_DT_REGION_FROM_NODE(DTCM, rw, DT_CHOSEN(zephyr_dtcm))
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
}
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
#include <linker/rel-sections.ld>
/*
* The .plt and .iplt are here according to
* 'riscv32-zephyr-elf-ld --verbose', before text section.
*/
SECTION_PROLOGUE(.plt,,)
{
*(.plt)
}
SECTION_PROLOGUE(.iplt,,)
{
*(.iplt)
}
GROUP_START(ROMABLE_REGION)
_image_rom_start = ROM_BASE;
SECTION_PROLOGUE(_VECTOR_SECTION_NAME,,)
{
/* In XIP mode, the .init section must be at the start of ROM */
. = ALIGN(4);
KEEP(*(.init.*))
. = ALIGN(4);
KEEP(*(.vectors.*))
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_PROLOGUE(rom_start,,)
{
. = ALIGN(16);
/* Located in generated directory. This file is populated by calling
* zephyr_linker_sources(ROM_START ...).
*/
#include <snippets-rom-start.ld>
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_PROLOGUE(_RESET_SECTION_NAME,,)
{
KEEP(*(.reset.*))
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_PROLOGUE(_EXCEPTION_SECTION_NAME,,)
{
KEEP(*(".exception.entry.*"))
*(".exception.other.*")
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
{
. = ALIGN(4);
KEEP(*(.openocd_debug))
KEEP(*(".openocd_debug.*"))
_image_text_start = .;
*(.text)
*(".text.*")
*(.gnu.linkonce.t.*)
#include <linker/kobject-text.ld>
#ifdef CONFIG_SOC_FLASH_RAMCODE_SECTION
. = ALIGN(0x1000);
_ram_code_start = .;
KEEP(*(.__ram_code))
__ram_code_size = . - _ram_code_start;
ASSERT((__ram_code_size <= 0x1000),
"__ram_code_size <= 4k bytes");
#endif
} GROUP_LINK_IN(ROMABLE_REGION)
_image_text_end = .;
_image_rodata_start = .;
#include <linker/common-rom.ld>
#include <linker/thread-local-storage.ld>
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
{
. = ALIGN(4);
*(.srodata)
*(".srodata.*")
*(.rodata)
*(".rodata.*")
*(.gnu.linkonce.r.*)
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#include <linker/kobject-rom.ld>
. = ALIGN(4);
} GROUP_LINK_IN(ROMABLE_REGION)
#include <linker/cplusplus-rom.ld>
_image_rodata_end = .;
MPU_ALIGN(_image_rodata_end - _image_rom_start);
GROUP_END(ROMABLE_REGION)
GROUP_START(RAMABLE_REGION)
#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN
#define SMEM_PARTITION_ALIGN MPU_ALIGN
#include <app_smem.ld>
_image_ram_start = _app_smem_start;
_app_smem_size = _app_smem_end - _app_smem_start;
_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
#endif /* CONFIG_USERSPACE */
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
MPU_MIN_SIZE_ALIGN
/*
* For performance, BSS section is assumed to be 4 byte aligned and
* a multiple of 4 bytes
*/
. = ALIGN(4);
__bss_start = .;
_image_ram_start = .;
__kernel_ram_start = .;
*(.sbss)
*(".sbss.*")
*(.bss)
*(".bss.*")
COMMON_SYMBOLS
/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
*/
__bss_end = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
#include <linker/common-noinit.ld>
#include <linker/cplusplus-ram.ld>
SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
{
. = ALIGN(4);
/* _image_ram_start = .; */
__data_ram_start = .;
*(.data)
*(".data.*")
#ifdef CONFIG_RISCV_GP
/*
* RISC-V architecture has 12-bit signed immediate offsets in the
* instructions. If we can put the most commonly accessed globals
* in a special 4K span of memory addressed by the GP register, then
* we can access those values in a single instruction, saving both
* codespace and runtime.
*
* Since these immediate offsets are signed, place gp 0x800 past the
* beginning of .sdata so that we can use both positive and negative
* offsets.
*/
. = ALIGN(8);
PROVIDE (__global_pointer$ = . + 0x800);
#endif
*(.sdata .sdata.* .gnu.linkonce.s.*)
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
__data_rom_start = LOADADDR(_DATA_SECTION_NAME);
#include <linker/common-ram.ld>
#include <linker/kobject-data.ld>
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-data-sections.ld>
__data_ram_end = .;
MPU_MIN_SIZE_ALIGN
_image_ram_end = .;
_end = .; /* end of image */
__kernel_ram_end = .;
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
GROUP_START(ITCM)
SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(8))
{
__itcm_start = .;
*(.itcm)
*(".itcm.*")
__itcm_end = .;
} GROUP_LINK_IN(ITCM AT> ROMABLE_REGION)
__itcm_size = __itcm_end - __itcm_start;
__itcm_rom_start = LOADADDR(_ITCM_SECTION_NAME);
GROUP_END(ITCM)
#endif
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
GROUP_START(DTCM)
SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(8))
{
__dtcm_start = .;
__dtcm_bss_start = .;
*(.dtcm_bss)
*(".dtcm_bss.*")
__dtcm_bss_end = .;
} GROUP_LINK_IN(DTCM)
SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(8))
{
__dtcm_noinit_start = .;
*(.dtcm_noinit)
*(".dtcm_noinit.*")
__dtcm_noinit_end = .;
} GROUP_LINK_IN(DTCM)
SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(8))
{
__dtcm_data_start = .;
*(.dtcm_data)
*(".dtcm_data.*")
__dtcm_data_end = .;
} GROUP_LINK_IN(DTCM AT> ROMABLE_REGION)
__dtcm_end = .;
__dtcm_data_rom_start = LOADADDR(_DTCM_DATA_SECTION_NAME);
GROUP_END(DTCM)
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>
GROUP_END(RAMABLE_REGION)
#include <linker/debug-sections.ld>
/DISCARD/ : { *(.note.GNU-stack) }
SECTION_PROLOGUE(.riscv.attributes, 0,)
{
KEEP(*(.riscv.attributes))
KEEP(*(.gnu.attributes))
}
/* Must be last in romable region */
SECTION_PROLOGUE(.last_section,(NOLOAD),)
{
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
* calculate this value here. */
_image_rom_end = LOADADDR(.last_section);
_image_rom_size = _image_rom_end - _image_rom_start;
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Andes Technology Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief Macros for the Andes AE350 platform
*/
#ifndef __RISCV_ANDES_AE350_SOC_H_
#define __RISCV_ANDES_AE350_SOC_H_
#include <soc_common.h>
#include <devicetree.h>
/* Machine timer memory-mapped registers */
#define RISCV_MTIME_BASE 0xE6000000
#define RISCV_MTIMECMP_BASE 0xE6000008
/* lib-c hooks required RAM defined variables */
#define RISCV_RAM_BASE CONFIG_SRAM_BASE_ADDRESS
#define RISCV_RAM_SIZE KB(CONFIG_SRAM_SIZE)
/* Include CSRs available for Andes V5 SoCs */
#include "soc_v5.h"
/* Include platform peripherals */
#include "smu.h"
#endif /* __RISCV_ANDES_AE350_SOC_H_ */

View file

@ -0,0 +1,18 @@
/*
* Copyright (c) 2021 Andes Technology Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* linker script for andes_v5 SoC Series
*/
#include <autoconf.h>
#if defined(CONFIG_SOC_RISCV_ANDES_AE350)
# include <ae350/linker.ld>
#endif

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 Andes Technology Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief Macros for the Andes ATCSMU
*/
#ifndef SOC_RISCV_ANDES_V5_SMU_H_
#define SOC_RISCV_ANDES_V5_SMU_H_
/*
* SMU Register Base Address
*/
#if DT_NODE_EXISTS(DT_INST(0, andestech_atcsmu100))
#define SMU_BASE DT_REG_ADDR(DT_INST(0, andestech_atcsmu100))
#endif /* DT_NODE_EXISTS(DT_INST(0, andestech_atcsmu100)) */
/*
* SMU register offset
*/
/* Basic */
#define SMU_SYSTEMVER 0x00
#define SMU_BOARDVER 0x04
#define SMU_SYSTEMCFG 0x08
#define SMU_SMUVER 0x0C
/* Reset vectors */
#define SMU_HARTn_RESET_VECTOR(n) (0x50 + 0x8 * (n))
/* Power control slot */
#define SMU_PCSn_CFG(n) (0x80 + 0x20 * (n))
#define SMU_PCSn_SCRATCH(n) (0x80 + 0x20 * (n))
#define SMU_PCSn_MISC(n) (0x80 + 0x20 * (n))
#define SMU_PCSn_MISC2(n) (0x80 + 0x20 * (n))
#define SMU_PCSn_WE(n) (0x80 + 0x20 * (n))
#define SMU_PCSn_CTL(n) (0x80 + 0x20 * (n))
#define SMU_PCSn_STATUS(n) (0x80 + 0x20 * (n))
/* Pinmux */
#define SMU_PINMUX_CTRL0 0x1000
#define SMU_PINMUX_CTRL1 0x1004
/*
* SMU helper constant
*/
#define SMU_SYSTEMCFG_CORENUM_MASK 0xFF
#define SMU_SYSTEMCFG_L2C BIT(8)
#define SMU_SYSTEMCFG_DFS BIT(9)
#define SMU_SYSTEMCFG_DC_COHEN BIT(10)
#endif /* SOC_RISCV_ANDES_V5_SMU_H_ */

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Andes Technology Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __RISCV_ANDES_V5_SOC_V5_H_
#define __RISCV_ANDES_V5_SOC_V5_H_
/* Control and Status Registers (CSRs) available for Andes V5 SoCs */
#define NDS_MMISC_CTL 0x7D0
#define NDS_MCACHE_CTL 0x7CA
#define NDS_MMSC_CFG 0xFC2
#define NDS_MXSTATUS 0x7C4
#define NDS_UCODE 0x801
/* Control and Status Registers (CSRs) available for Andes V5 PMA */
#define NDS_PMACFG0 0xBC0
#define NDS_PMACFG1 0xBC1
#define NDS_PMACFG2 0xBC2
#define NDS_PMACFG3 0xBC3
#define NDS_PMAADDR0 0xBD0
#define NDS_PMAADDR1 0xBD1
#define NDS_PMAADDR2 0xBD2
#define NDS_PMAADDR3 0xBD3
#define NDS_PMAADDR4 0xBD4
#define NDS_PMAADDR5 0xBD5
#define NDS_PMAADDR6 0xBD6
#define NDS_PMAADDR7 0xBD7
#define NDS_PMAADDR8 0xBD8
#define NDS_PMAADDR9 0xBD9
#define NDS_PMAADDR10 0xBDA
#define NDS_PMAADDR11 0xBDB
#define NDS_PMAADDR12 0xBDC
#define NDS_PMAADDR13 0xBDD
#define NDS_PMAADDR14 0xBDE
#define NDS_PMAADDR15 0xBDF
#endif /* __RISCV_ANDES_V5_SOC_V5_H_ */

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 Andes Technology Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <toolchain.h>
#include <soc.h>
/* exports */
GTEXT(entry)
SECTION_FUNC(init, entry)
/* Disable linker relaxation before GP register initialization. */
.option push
.option norelax
#ifdef __nds_execit
/* Initialize EXECIT table */
la t0, _ITB_BASE_
csrw uitb, t0
#endif
#ifdef CONFIG_CACHE_ENABLE
/*
* Enable I/D cache with HW prefetcher,
* D-cache write-around (threshold: 4 cache lines),
* and CM (Coherence Manager).
*/
li t0, (0x3 << 13)
csrc NDS_MCACHE_CTL, t0
li t0, (1 << 19) | (1 << 13) | (1 << 10) | (1 << 9) | (0x3)
csrs NDS_MCACHE_CTL, t0
/* Check if CPU support CM or not. */
csrr t0, NDS_MCACHE_CTL
li t1, (1 << 19)
and t0, t0, t1
beqz t0, cache_enable_finish
/* If CPU support CM, check if CM is enabled. */
li t1, (1 << 20)
check_cm_enabled:
csrr t0, NDS_MCACHE_CTL
and t0, t0, t1
beqz t0, check_cm_enabled
cache_enable_finish:
#endif
/* Enable misaligned access and non-blocking load */
li t0, (1 << 8) | (1 << 6)
csrs NDS_MMISC_CTL, t0
j __start
.option pop