[bsp]增加超睿DP1000 bsp支持

This commit is contained in:
ZhangJing 2025-05-30 13:32:58 +08:00 committed by Rbb666
parent 93cc80e461
commit 97893c004c
35 changed files with 4488 additions and 2 deletions

View File

@ -389,7 +389,8 @@
"RTT_TOOL_CHAIN": "sourcery-riscv64-unknown-elf",
"SUB_RTT_BSP": [
"bluetrum/ab32vg1-ab-prougen",
"qemu-virt64-riscv"
"qemu-virt64-riscv",
"ultrarisc/ur_dp1000_evb"
]
},
{

View File

@ -82,3 +82,7 @@ owners: supper thomas(supperthomas)<78900636@qq.com>, Bingru Zhang(Rbb666)<75106
tag: gd32470z-lckfb-lcd
path: bsp/gd32/arm/gd32470z-lckfb/board/ports
owners: Wu Ying Xiang(godmial)<2633967641@qq.com>
tag: bsp_ultrarisc
path: bsp/ultrarisc/ur_dp1000_evb
owners: Zhang Jing(zhangjing0303)<zhangjing@ultrarisc.com>

View File

@ -0,0 +1,12 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
group = DefineGroup('arch', src, depend = [''], CPPPATH = CPPPATH)
objs = [group]
Return('objs')

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-29 lizhirui first version
* 2025-05-29 Zhang Jing remove redundant code
*/
#include <rthw.h>
#include <rtdef.h>
#include <board.h>
#include <riscv.h>
#include <cache.h>
void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
{
if (ops == RT_HW_CACHE_INVALIDATE)
{
rt_hw_cpu_icache_invalidate(addr, size);
}
return;
}
void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
{
if (ops == RT_HW_CACHE_FLUSH)
{
rt_hw_cpu_dcache_clean(addr, size);
}
else
{
rt_hw_cpu_dcache_invalidate(addr, size);
}
return;
}
void rt_hw_sync_cache_local(void *addr, int size)
{
rt_hw_cpu_dcache_clean_local(addr, size);
rt_hw_cpu_icache_invalidate_local(addr, size);
return;
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-09 RT-Thread The first version
*/
#ifndef __CACHE_H__
#define __CACHE_H__
#include <rtdef.h>
/**
* @brief These APIs may not be supported by a specified architecture
* But we have to include to all the cases to be 'general purpose'
*/
rt_always_inline void rt_hw_cpu_dcache_clean_local(void *addr, int size)
{
RT_UNUSED(addr);
RT_UNUSED(size);
}
rt_always_inline void rt_hw_cpu_dcache_invalidate_local(void *addr, int size)
{
RT_UNUSED(addr);
RT_UNUSED(size);
}
rt_always_inline void rt_hw_cpu_dcache_clean_and_invalidate_local(void *addr, int size)
{
RT_UNUSED(addr);
RT_UNUSED(size);
}
rt_always_inline void rt_hw_cpu_dcache_clean_all_local(void)
{
}
rt_always_inline void rt_hw_cpu_dcache_invalidate_all_local(void)
{
}
rt_always_inline void rt_hw_cpu_dcache_clean_and_invalidate_all_local(void)
{
}
/*use fence.i to invalidate all icache*/
rt_always_inline void rt_hw_cpu_icache_invalidate_local(void *addr, int size)
{
__asm__ __volatile__("fence.i" ::: "memory");
}
/*use fence.i to invalidate all icache*/
rt_always_inline void rt_hw_cpu_icache_invalidate_all_local(void)
{
__asm__ __volatile__("fence.i" ::: "memory");
}
/**
* @brief Multi-core
*/
#define rt_hw_cpu_dcache_clean rt_hw_cpu_dcache_clean_local
#define rt_hw_cpu_dcache_invalidate rt_hw_cpu_dcache_invalidate_local
#define rt_hw_cpu_dcache_clean_and_invalidate rt_hw_cpu_dcache_clean_and_invalidate_local
#define rt_hw_cpu_dcache_clean_all rt_hw_cpu_dcache_clean_all_local
#define rt_hw_cpu_dcache_invalidate_all rt_hw_cpu_dcache_invalidate_all_local
#define rt_hw_cpu_dcache_clean_and_invalidate_all rt_hw_cpu_dcache_clean_and_invalidate_all_local
#define rt_hw_cpu_icache_invalidate rt_hw_cpu_icache_invalidate_local
#define rt_hw_cpu_icache_invalidate_all rt_hw_cpu_icache_invalidate_all_local
#define rt_hw_icache_invalidate_all rt_hw_cpu_icache_invalidate_all
/** instruction barrier */
static inline void rt_hw_cpu_sync(void)
{
__asm__ __volatile__("fence.i" ::: "memory");
}
/**
* @brief local cpu icahce & dcache synchronization
*
* @param addr
* @param size
*/
void rt_hw_sync_cache_local(void *addr, int size);
#endif /* __CACHE_H__ */

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/01 Bernard The first version
* 2018/12/27 Jesven Change irq enable/disable to cpu0
*/
#include <plic.h>
#include "encoding.h"
#include "riscv.h"
#include "interrupt.h"
struct rt_irq_desc irq_desc[MAX_HANDLERS];
static rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
{
rt_kprintf("UN-handled interrupt %d occurred!!!\n", vector);
return RT_NULL;
}
int rt_hw_plic_irq_enable(int irq_number)
{
plic_irq_enable(irq_number);
return 0;
}
int rt_hw_plic_irq_disable(int irq_number)
{
plic_irq_disable(irq_number);
return 0;
}
/**
* This function will un-mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_umask(int vector)
{
plic_set_priority(vector, 1);
rt_hw_plic_irq_enable(vector);
}
/**
* This function will install a interrupt service routine to a interrupt.
* @param vector the interrupt number
* @param new_handler the interrupt service routine to be installed
* @param old_handler the old interrupt service routine
*/
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void *param, const char *name)
{
rt_isr_handler_t old_handler = RT_NULL;
if (vector < MAX_HANDLERS)
{
old_handler = irq_desc[vector].handler;
if (handler != RT_NULL)
{
irq_desc[vector].handler = (rt_isr_handler_t)handler;
irq_desc[vector].param = param;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
irq_desc[vector].counter = 0;
#endif
}
}
return old_handler;
}
void rt_hw_interrupt_init()
{
/* Enable machine external interrupts. */
/* set_csr(sie, SIP_SEIP); */
int idx = 0;
/* init exceptions table */
for (idx = 0; idx < MAX_HANDLERS; idx++)
{
irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
irq_desc[idx].param = RT_NULL;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
irq_desc[idx].counter = 0;
#endif
}
/*init plic*/
plic_init();
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-05-20 bigmagic The first version
*/
#ifndef INTERRUPT_H__
#define INTERRUPT_H__
#define MAX_HANDLERS 128
#include <rthw.h>
#include "stack.h"
enum
{
EP_INSTRUCTION_ADDRESS_MISALIGNED = 0,
EP_INSTRUCTION_ACCESS_FAULT,
EP_ILLEGAL_INSTRUCTION,
EP_BREAKPOINT,
EP_LOAD_ADDRESS_MISALIGNED,
EP_LOAD_ACCESS_FAULT,
EP_STORE_ADDRESS_MISALIGNED,
EP_STORE_ACCESS_FAULT,
EP_ENVIRONMENT_CALL_U_MODE,
EP_ENVIRONMENT_CALL_S_MODE,
EP_RESERVED10,
EP_ENVIRONMENT_CALL_M_MODE,
EP_INSTRUCTION_PAGE_FAULT, /* page attr */
EP_LOAD_PAGE_FAULT, /* read data */
EP_RESERVED14,
EP_STORE_PAGE_FAULT, /* write data */
};
int rt_hw_plic_irq_enable(int irq_number);
int rt_hw_plic_irq_disable(int irq_number);
void rt_hw_interrupt_init(void);
void rt_hw_interrupt_mask(int vector);
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name);
void handle_trap(rt_size_t xcause, rt_size_t xtval, rt_size_t xepc, struct rt_hw_stack_frame *sp);
#endif

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-09 Shell Add portable asm support
*/
#ifndef __OPCODE_H__
#define __OPCODE_H__
/**
* @brief binary opcode pseudo operations
* Used to bypass toolchain restriction on extension ISA
*
*/
/**
* @brief RISC-V instruction formats
*/
/**
* R type: .insn r opcode6, func3, func7, rd, rs1, rs2
*
* +-------+-----+-----+-------+----+---------+
* | func7 | rs2 | rs1 | func3 | rd | opcode6 |
* +-------+-----+-----+-------+----+---------+
* 31 25 20 15 12 7 0
*/
#define __OPC_INSN_FORMAT_R(opcode, func3, func7, rd, rs1, rs2) \
".insn r "RT_STRINGIFY(opcode)","RT_STRINGIFY(func3)","RT_STRINGIFY(func7)","RT_STRINGIFY(rd)","RT_STRINGIFY(rs1)","RT_STRINGIFY(rs2)
#ifdef _TOOLCHAIN_SUPP_ZIFENCEI_ISA_
#define OPC_FENCE_I "fence.i"
#else /* !_TOOLCHAIN_SUPP_ZIFENCEI_ISA_ */
#define OPC_FENCE_I ".long 0x0000100F"
#endif /* _TOOLCHAIN_SUPP_ZIFENCEI_ISA_ */
#endif /* __OPCODE_H__ */

View File

@ -0,0 +1,255 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Support for RISC-V Platform-Level Interrupt Controller(PLIC)
* Specification Version 1.0.0, which is currently(3/12/2023) the
* lastest draft.
*
* Change Logs:
* Date Author Notes
* 2021-05-20 bigmagic first version
* 2022-09-16 WangXiaoyao Porting to rv64
* 2025-01-26 ZhangJing Porting to ultrarisc cp100
*/
#include <rthw.h>
#include <rtthread.h>
#include <stdint.h>
#include "plic.h"
#include <io.h>
#include "encoding.h"
#include <interrupt.h>
#include <riscv_io.h>
#include <riscv.h>
#include <string.h>
#include <stdlib.h>
#ifdef RT_USING_SMART
#include <ioremap.h>
#else
#define rt_ioremap(addr, ...) (addr)
#endif
/* plic_base should be initialized in the bsp*/
size_t plic_base = 0 ;
/*
* Each PLIC interrupt source can be assigned a priority by writing
* to its 32-bit memory-mapped priority register.
* Maximum priority is 7.
* A priority value of 0 is reserved to mean "never interrupt" and
* effectively disables the interrupt.
* Ties between global interrupts of the same priority are broken by
* the Interrupt ID; interrupts with the lowest ID have the highest
* effective priority.
*/
void plic_set_priority(int irq, int priority)
{
writel(priority, (void *)PLIC_PRIORITY(irq));
}
/*
* Each global interrupt can be enabled by setting the corresponding
* bit in the enables registers.
*/
void plic_irq_enable(int irq)
{
int hart = __raw_hartid();
void *enable = (void *)PLIC_ENABLE(hart) + (irq / 32) * sizeof(uint32_t);
rt_uint32_t val = readl(enable);
val |= (1 << (irq % 32));
writel(val, enable);
return;
}
/*
* Each global interrupt can be disabled by clearing the corresponding
* bit in the enables registers.
*/
void plic_irq_disable(int irq)
{
int hart = __raw_hartid();
void *enable = (void *)PLIC_ENABLE(hart) + (irq / 32) * sizeof(uint32_t);
rt_uint32_t val = readl(enable);
val &= ~(1 << (irq % 32));
writel(val, enable);
return;
}
/*
* PLIC will mask all interrupts of a priority less than or equal to threshold.
* Maximum threshold is 7.
* For example, a threshold value of zero permits all interrupts with
* non-zero priority, whereas a value of 7 masks all interrupts.
* Notice, the threshold is global for PLIC, not for each interrupt source.
*/
void plic_set_threshold(int threshold)
{
int hart = __raw_hartid();
writel(threshold, (void *)PLIC_THRESHOLD(hart));
return;
}
/*
* DESCRIPTION:
* Query the PLIC what interrupt we should serve.
* Perform an interrupt claim by reading the claim register, which
* returns the ID of the highest-priority pending interrupt or zero if there
* is no pending interrupt.
* A successful claim also atomically clears the corresponding pending bit
* on the interrupt source.
* RETURN VALUE:
* the ID of the highest-priority pending interrupt or zero if there
* is no pending interrupt.
*/
rt_uint32_t plic_claim(void)
{
int hart = __raw_hartid();
void *claim = (void *)PLIC_CLAIM(hart);
return readl(claim);
}
/*
* DESCRIPTION:
* Writing the interrupt ID it received from the claim (irq) to the
* complete register would signal the PLIC we've served this IRQ.
* The PLIC does not check whether the completion ID is the same as the
* last claim ID for that target. If the completion ID does not match an
* interrupt source that is currently enabled for the target, the completion
* is silently ignored.
* RETURN VALUE: none
*/
void plic_complete(int irq)
{
int hart = __raw_hartid();
void *complete = (void *)PLIC_COMPLETE(hart);
writel(irq, complete);
return;
}
void plic_init()
{
if (!plic_base)
{
return;
}
/* PLIC takes up 64 MB space */
plic_base = (size_t)rt_ioremap((void *)plic_base, 64 * 1024 * 1024);
plic_set_threshold(0);
/*set the same priority for all the irqs*/
for (int i = 1; i < CONFIG_IRQ_NR; i++)
{
plic_set_priority(i, 1);
}
/*disable all interrupts*/
for (int i = 1; i < CONFIG_IRQ_NR; i++)
{
plic_irq_disable(i);
}
set_csr(sie, read_csr(sie) | MIP_SEIP);
return;
}
extern struct rt_irq_desc irq_desc[MAX_HANDLERS];
#ifdef BOARD_UR_DP1000
int find_first_bit(rt_uint32_t *addr, int size)
{
int i;
for (i = 0; i < size; i++)
{
if (*addr & (1 << i))
return i;
}
return -1;
}
static rt_bool_t is_irqs_pending(rt_uint32_t ie[])
{
int hartid = __raw_hartid();
int nr_irqs = CONFIG_IRQ_NR;
int nr_irq_groups = (nr_irqs + 31) / 32;
rt_bool_t is_pending = RT_FALSE;
void *pending_base = (void *)PLIC_PENDING(0);
void *enable_base = (void *)PLIC_ENABLE(hartid);
int i, j;
for (i = 0; i < nr_irq_groups; i++)
ie[i] = readl(enable_base + i * sizeof(rt_uint32_t));
for (i = 0; i < nr_irq_groups; i++)
{
rt_uint32_t pending_irqs = readl(pending_base + i * sizeof(rt_uint32_t)) & ie[i];
if (pending_irqs)
{
int nbit = find_first_bit(&pending_irqs, 32);
for (j = 0; j < nr_irq_groups; j++)
writel((i == j) ? (1 << nbit) : 0, enable_base + j * sizeof(rt_uint32_t));
is_pending = RT_TRUE;
break;
}
}
return is_pending;
}
static void restore_irqs_enable(rt_uint32_t ie[])
{
int hartid = __raw_hartid();
int nr_irqs = CONFIG_IRQ_NR;
int nr_irq_groups = (nr_irqs + 31) / 32;
void *enable_base = (void *)PLIC_ENABLE(hartid);
int i;
for (i = 0; i < nr_irq_groups; i++)
writel(ie[i], enable_base + i * sizeof(rt_uint32_t));
return;
}
#endif
/*
* Handling an interrupt is a two-step process: first you claim the interrupt
* by reading the claim register, then you complete the interrupt by writing
* that source ID back to the same claim register. This automatically enables
* and disables the interrupt, so there's nothing else to do.
*/
void plic_handle_irq(void)
{
rt_uint32_t plic_irq;
#ifdef BOARD_UR_DP1000
/* TODO: if not only one interrupt, we need to continue to check the interrupt source */
unsigned int ie[32] = {0};
plic_irq = is_irqs_pending(ie) ? plic_claim() : 0;
restore_irqs_enable(ie);
if (plic_irq > CONFIG_IRQ_NR)
{
/*spurious interrupt, return directly*/
rt_kprintf("spurious interrupt, irq = %d\n", plic_irq);
return;
}
plic_complete(plic_irq);
irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
#else
plic_irq = plic_claim();
plic_complete(plic_irq);
if (plic_irq > CONFIG_IRQ_NR)
{
/*spurious interrupt, return directly*/
rt_kprintf("spurious interrupt, irq = %d\n", plic_irq);
return;
}
irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
#endif
return;
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-05-20 bigmagic first version
* 2021-10-20 bernard fix s-mode issue
* 2025-01-26 ZhangJing Porting to ultrarisc cp100
*/
#ifndef __PLIC_H__
#define __PLIC_H__
#include <rtconfig.h>
#include <rthw.h>
#define PLIC_PRIORITY_BASE 0x0
#define PLIC_PENDING_BASE 0x1000
#define PLIC_ENABLE_BASE 0x2000
#define PLIC_CONTEXT_BASE 0x200000
extern size_t plic_base;
#define PLIC_BASE (plic_base)
#define PLIC_PRIORITY_OFFSET (0x0)
#define PLIC_PENDING_OFFSET (0x1000)
#define PLIC_ENABLE_STRIDE 0x80
#define PLIC_CONTEXT_STRIDE 0x1000
#define RISCV_S_MODE
#ifndef RISCV_S_MODE
/*using context 0*/
#define PLIC_MENABLE_OFFSET (0x2000)
#define PLIC_MTHRESHOLD_OFFSET (0x200000)
#define PLIC_MCLAIM_OFFSET (0x200004)
#define PLIC_MCOMPLETE_OFFSET (0x200004)
#define PLIC_ENABLE(hart) (PLIC_BASE + PLIC_MENABLE_OFFSET + (hart * 3) * PLIC_ENABLE_STRIDE)
#define PLIC_THRESHOLD(hart) (PLIC_BASE + PLIC_MTHRESHOLD_OFFSET + (hart * 3) * PLIC_CONTEXT_STRIDE)
#define PLIC_CLAIM(hart) (PLIC_BASE + PLIC_MCLAIM_OFFSET + (hart * 3) * PLIC_CONTEXT_STRIDE)
#define PLIC_COMPLETE(hart) (PLIC_BASE + PLIC_MCOMPLETE_OFFSET + (hart * 3) * PLIC_CONTEXT_STRIDE)
#else
/*using context 1*/
#define PLIC_SENABLE_OFFSET (0x2000 + PLIC_ENABLE_STRIDE)
#define PLIC_STHRESHOLD_OFFSET (0x200000 + PLIC_CONTEXT_STRIDE)
#define PLIC_SCLAIM_OFFSET (0x200004 + PLIC_CONTEXT_STRIDE)
#define PLIC_SCOMPLETE_OFFSET (0x200004 + PLIC_CONTEXT_STRIDE)
#define PLIC_ENABLE(hart) (PLIC_BASE + PLIC_SENABLE_OFFSET + (hart * 3) * PLIC_ENABLE_STRIDE)
#define PLIC_THRESHOLD(hart) (PLIC_BASE + PLIC_STHRESHOLD_OFFSET + (hart * 3) * PLIC_CONTEXT_STRIDE)
#define PLIC_CLAIM(hart) (PLIC_BASE + PLIC_SCLAIM_OFFSET + (hart * 3) * PLIC_CONTEXT_STRIDE)
#define PLIC_COMPLETE(hart) (PLIC_BASE + PLIC_SCOMPLETE_OFFSET + (hart * 3) * PLIC_CONTEXT_STRIDE)
#endif
#define PLIC_PRIORITY(id) (PLIC_BASE + PLIC_PRIORITY_OFFSET + (id) * 4)
#define PLIC_PENDING(id) (PLIC_BASE + PLIC_PENDING_OFFSET + ((id) / 32))
#define WORD_CNT_BYTE (1024 / 8)
#define CONFIG_IRQ_NR (32)
#define CONFIG_IRQ_WORD (CONFIG_IRQ_NR / 32)
void plic_set_priority(int irq, int priority);
void plic_irq_enable(int irq);
void plic_irq_disable(int irq);
void plic_set_threshold(int mthreshold);
rt_uint32_t plic_claim(void);
void plic_complete(int irq);
void plic_set_thresh(rt_uint32_t val);
void plic_set_ie(rt_uint32_t word_index, rt_uint32_t val);
void plic_init();
void plic_handle_irq(void);
#endif

View File

@ -0,0 +1,195 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-30 lizhirui first version
* 2023-10-12 Shell Add permission control API
* 2025-01-22 ZhangJing Add pte default attribute for ur-cp100
*/
#ifndef __RISCV_MMU_H__
#define __RISCV_MMU_H__
#include <rtthread.h>
#include <rthw.h>
#include "riscv.h"
#undef PAGE_SIZE
#define PAGE_OFFSET_SHIFT 0
#define PAGE_OFFSET_BIT 12
#define PAGE_SIZE __SIZE(PAGE_OFFSET_BIT)
#define PAGE_OFFSET_MASK __MASK(PAGE_OFFSET_BIT)
#define VPN0_SHIFT (PAGE_OFFSET_SHIFT + PAGE_OFFSET_BIT)
#define VPN0_BIT 9
#define VPN1_SHIFT (VPN0_SHIFT + VPN0_BIT)
#define VPN1_BIT 9
#define VPN2_SHIFT (VPN1_SHIFT + VPN1_BIT)
#define VPN2_BIT 9
#define PPN0_SHIFT (PAGE_OFFSET_SHIFT + PAGE_OFFSET_BIT)
#define PPN0_BIT 9
#define PPN1_SHIFT (PPN0_SHIFT + PPN0_BIT)
#define PPN1_BIT 9
#define PPN2_SHIFT (PPN1_SHIFT + PPN1_BIT)
#define PPN2_BIT 26
#define PPN_BITS (PPN0_BIT + PPN1_BIT + PPN2_BIT)
#define L1_PAGE_SIZE __SIZE(PAGE_OFFSET_BIT + VPN0_BIT + VPN1_BIT)
#define L2_PAGE_SIZE __SIZE(PAGE_OFFSET_BIT + VPN0_BIT)
#define L3_PAGE_SIZE __SIZE(PAGE_OFFSET_BIT)
#define ARCH_ADDRESS_WIDTH_BITS 64
#define PHYSICAL_ADDRESS_WIDTH_BITS 56
#define PAGE_ATTR_BASE (PTE_A | PTE_D)
#define PAGE_ATTR_NEXT_LEVEL (0)
#define PAGE_ATTR_RWX (PTE_X | PTE_W | PTE_R)
#define PAGE_ATTR_READONLY (PTE_R)
#define PAGE_ATTR_READEXECUTE (PTE_X | PTE_R)
#define PAGE_ATTR_USER (PTE_U)
#define PAGE_ATTR_SYSTEM (0)
#define PAGE_DEFAULT_ATTR_LEAF (PAGE_ATTR_RWX | PAGE_ATTR_USER | PTE_V | PTE_G | PAGE_ATTR_BASE )
#define PAGE_DEFAULT_ATTR_NEXT (PAGE_ATTR_NEXT_LEVEL | PTE_V | PTE_G)
#define PAGE_IS_LEAF(pte) __MASKVALUE(pte, PAGE_ATTR_RWX)
#define PTE_USED(pte) __MASKVALUE(pte, PTE_V)
/**
* encoding of SATP (Supervisor Address Translation and Protection register)
*/
#define SATP_MODE_OFFSET 60
#define SATP_MODE_BARE 0
#define SATP_MODE_SV39 8
#define SATP_MODE_SV48 9
#define SATP_MODE_SV57 10
#define SATP_MODE_SV64 11
#define ARCH_VADDR_WIDTH 39
#define SATP_MODE SATP_MODE_SV39
#define MMU_MAP_K_DEVICE (PTE_G | PTE_W | PTE_R | PTE_V | PAGE_ATTR_BASE)
#define MMU_MAP_K_RWCB (PTE_G | PTE_X | PTE_W | PTE_R | PTE_V | PAGE_ATTR_BASE)
#define MMU_MAP_K_RW (PTE_G | PTE_X | PTE_W | PTE_R | PTE_V | PAGE_ATTR_BASE)
#define MMU_MAP_U_RWCB (PTE_U | PTE_X | PTE_W | PTE_R | PTE_V | PAGE_ATTR_BASE)
#define MMU_MAP_U_RWCB_XN (PTE_U | PTE_W | PTE_R | PTE_V | PAGE_ATTR_BASE)
#define MMU_MAP_U_RW (PTE_U | PTE_X | PTE_W | PTE_R | PTE_V | PAGE_ATTR_BASE)
#define MMU_MAP_EARLY (PAGE_ATTR_RWX | PTE_G | PTE_V | PAGE_ATTR_BASE)
#define PTE_XWR_MASK 0xe
#define ARCH_PAGE_SIZE PAGE_SIZE
#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1)
#define ARCH_PAGE_SHIFT PAGE_OFFSET_BIT
#define ARCH_INDEX_WIDTH 9
#define ARCH_INDEX_SIZE (1ul << ARCH_INDEX_WIDTH)
#define ARCH_INDEX_MASK (ARCH_INDEX_SIZE - 1)
#define DRAM_SIZE (0x400000000) /* 16GB */
#define MMIO_SIZE (0x80000000)
#define MAP_COUNT ((DRAM_SIZE + MMIO_SIZE) >> VPN2_SHIFT)
#define ARCH_MAP_FAILED ((void *)0x8000000000000000)
void mmu_set_pagetable(rt_ubase_t addr);
void mmu_enable_user_page_access(void);
void mmu_disable_user_page_access(void);
#define RT_HW_MMU_PROT_READ 1
#define RT_HW_MMU_PROT_WRITE 2
#define RT_HW_MMU_PROT_EXECUTE 4
#define RT_HW_MMU_PROT_KERNEL 8
#define RT_HW_MMU_PROT_USER 16
#define RT_HW_MMU_PROT_CACHE 32
void rt_hw_asid_init(void);
struct rt_aspace;
void rt_hw_asid_switch_pgtbl(struct rt_aspace *aspace, rt_ubase_t pgtbl);
/**
* @brief Remove permission from attribution
*
* @param attr architecture specified mmu attribution
* @param prot protect that will be removed
* @return size_t returned attribution
*/
rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot)
{
switch (prot)
{
/* remove write permission for user */
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
attr &= ~PTE_W;
break;
/* remove write permission for kernel */
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_KERNEL:
attr &= ~PTE_W;
break;
default:
RT_ASSERT(0);
}
return attr;
}
/**
* @brief Add permission from attribution
*
* @param attr architecture specified mmu attribution
* @param prot protect that will be added
* @return size_t returned attribution
*/
rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot)
{
switch (prot)
{
/* add write permission for user */
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
attr |= (PTE_R | PTE_W | PTE_U);
break;
default:
RT_ASSERT(0);
}
return attr;
}
/**
* @brief Test permission from attribution
*
* @param attr architecture specified mmu attribution
* @param prot protect that will be test
* @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE
*/
rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot)
{
rt_bool_t rc = 0;
switch (prot & ~RT_HW_MMU_PROT_USER)
{
/* test write permission for user */
case RT_HW_MMU_PROT_WRITE:
rc = ((attr & PTE_W) && (attr & PTE_R));
break;
case RT_HW_MMU_PROT_READ:
rc = !!(attr & PTE_R);
break;
case RT_HW_MMU_PROT_EXECUTE:
rc = !!(attr & PTE_X);
break;
default:
RT_ASSERT(0);
}
if (rc && (prot & RT_HW_MMU_PROT_USER))
{
rc = !!(attr & PTE_U);
}
return rc;
}
#endif

View File

@ -0,0 +1,16 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
if not GetDepend('BSP_USING_DW_SPI'):
SrcRemove(src, ['drv_dw_spi.c'])
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
objs = [group]
Return('objs')

View File

@ -0,0 +1,390 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* spi driver for synopsys dw apb spi
*
* Change Logs:
* Date Author Notes
* 2025-01-03 ZhangJing first version
*/
#include <rtconfig.h>
#ifdef BSP_USING_DW_SPI
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_dw_spi.h"
#include <rtdbg.h>
#include <io.h>
#ifdef RT_USING_SMART
#include <ioremap.h>
#endif
#define SPI0_BUS_NAME "spi0"
#define SPI0_BUS_DEVICE0_NAME "spi00"
static struct dw_spi dw_spi_device =
{
.device_name = "spi0",
.irq = DW_SPI_IRQ_BASE,
.max_freq = DW_SPI_MAX_FREQ,
.bits_per_word = 8,
.cs = 0,
.fifo_len = 0,
.type = DW_SPI_CTRLR0_FRF_MOT,
};
static rt_uint32_t update_control_reg_16(struct dw_spi *dw_spi_dev)
{
return ((dw_spi_dev->bits_per_word - 1) << CTRLR0_DFS_SHIFT) |
(dw_spi_dev->type << DW_SPI_CTRLR0_FRF_SHIFT) |
(dw_spi_dev->mode << DW_SPI_CTRLR0_MODE_SHIFT) |
(dw_spi_dev->tmode << DW_SPI_CTRLR0_TMOD_SHIFT);
}
static rt_uint32_t update_control_reg_32(struct dw_spi *dw_spi_dev)
{
return ((dw_spi_dev->bits_per_word - 1) << CTRLR0_DFS_32_SHIFT) |
(dw_spi_dev->type << DW_SPI_CTRLR0_FRF_SHIFT) |
(dw_spi_dev->mode << DW_SPI_CTRLR0_MODE_SHIFT) |
(dw_spi_dev->tmode << DW_SPI_CTRLR0_TMOD_SHIFT);
}
static rt_err_t _dw_drv_spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *config)
{
struct dw_spi *dw_spi_dev = (struct dw_spi *)(device->bus->parent.user_data);
if (!dw_spi_dev)
{
LOG_E("SPI device is null");
return -RT_ERROR;
}
struct dw_spi_regs *regs = dw_spi_dev->reg;
writel(0, &regs->ssienr);
writel(0, &regs->ser);
writel(0, &regs->imr);
writel(0, &regs->dmacr);
rt_uint32_t ctrl = 0;
switch (config->mode & (RT_SPI_CPHA | RT_SPI_CPOL))
{
case RT_SPI_MODE_0:
ctrl |= 0;
break;
case RT_SPI_MODE_1:
ctrl |= DW_SPI_CTRLR0_SCPH;
break;
case RT_SPI_MODE_2:
ctrl |= DW_SPI_CTRLR0_SCPOL;
break;
case RT_SPI_MODE_3:
ctrl |= DW_SPI_CTRLR0_SCPH | DW_SPI_CTRLR0_SCPOL;
break;
}
dw_spi_dev->mode = ctrl;
/* div = dw_spi_dev->max_freq / configuration->max_hz;*/
rt_uint32_t div = 0;
div = dw_spi_dev->max_freq / 15625000;
if (div % 2)
div++;
/* TODO: */
/* write clock divider register */
writel(div, &regs->baudr);
/* write TX threshold register */
writel(0, &regs->txflr);
/* write RX threshold register */
writel(0, &regs->rxflr);
/* enable spi */
writel(1, &regs->ssienr);
return RT_EOK;
}
static rt_uint32_t min3(rt_uint32_t a, rt_uint32_t b, rt_uint32_t c)
{
return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
}
static inline rt_uint32_t tx_max(struct dw_spi *dw_spi_dev)
{
rt_uint32_t tx_left, tx_room, rxtx_gap;
struct dw_spi_regs *regs = dw_spi_dev->reg;
tx_left = dw_spi_dev->tx_len;
tx_room = dw_spi_dev->fifo_len - (rt_uint32_t)(readl(&regs->txflr));
/*
* Another concern is about the tx/rx mismatch, we
* thought about using (priv->fifo_len - rxflr - txflr) as
* one maximum value for tx, but it doesn't cover the
* data which is out of tx/rx fifo and inside the
* shift registers. So a control from sw point of
* view is taken.
*/
if (dw_spi_dev->rx != NULL && dw_spi_dev->tx != NULL)
{
rxtx_gap = dw_spi_dev->fifo_len - (dw_spi_dev->rx_len - dw_spi_dev->tx_len);
return min3(tx_left, tx_room, (rt_uint32_t)(rxtx_gap));
}
else
{
return tx_left < tx_room ? tx_left : tx_room;
}
}
static inline rt_uint32_t rx_max(struct dw_spi *dw_spi_dev)
{
rt_uint32_t rx_left = dw_spi_dev->rx_len;
struct dw_spi_regs *regs = dw_spi_dev->reg;
rt_uint32_t val = readl(&regs->rxflr);
return (rx_left < val) ? rx_left : val;
}
/* write data to spi */
static void dw_spi_writer(struct dw_spi *dw_spi_dev)
{
rt_uint32_t max = tx_max(dw_spi_dev);
rt_uint32_t txw = 0xFF;
struct dw_spi_regs *regs = dw_spi_dev->reg;
while (max--)
{
/* Set the tx word if the transfer's original "tx" is not null */
if (dw_spi_dev->tx)
{
if (dw_spi_dev->bits_per_word == 8)
txw = *(rt_uint8_t *)(dw_spi_dev->tx);
else
txw = *(rt_uint16_t *)(dw_spi_dev->tx);
dw_spi_dev->tx += dw_spi_dev->bits_per_word >> 3;
}
writel(txw, &regs->dr);
dw_spi_dev->tx_len--;
}
}
/* read data from spi */
static void dw_spi_reader(struct dw_spi *dw_spi_dev)
{
struct dw_spi_regs *regs = dw_spi_dev->reg;
rt_uint32_t max = rx_max(dw_spi_dev);
rt_uint16_t rxw;
while (max--)
{
rxw = readl(&regs->dr);
if (dw_spi_dev->rx)
{
if (dw_spi_dev->bits_per_word == 8)
*(rt_uint8_t *)(dw_spi_dev->rx) = rxw;
else
*(rt_uint16_t *)(dw_spi_dev->rx) = rxw;
dw_spi_dev->rx += dw_spi_dev->bits_per_word >> 3;
}
dw_spi_dev->rx_len--;
}
}
static void wait_for_idle(struct dw_spi *dw_spi_dev)
{
rt_uint32_t status;
struct dw_spi_regs *regs = dw_spi_dev->reg;
while (1)
{
status = readl(&regs->sr);
if (!(status & DW_SPI_SR_BUSY))
{
if (status & DW_SPI_SR_TX_EMPTY)
{
break;
}
}
rt_thread_yield();
}
}
static int dw_spi_poll_transfer(struct dw_spi *dw_spi_dev)
{
do
{
dw_spi_writer(dw_spi_dev);
wait_for_idle(dw_spi_dev);
dw_spi_reader(dw_spi_dev);
}
while (dw_spi_dev->rx_len && dw_spi_dev->tx_len);
return 0;
}
static rt_ssize_t _dw_spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct dw_spi *dw_spi_dev = (struct dw_spi *)(device->bus->parent.user_data);
if (!dw_spi_dev)
{
LOG_E("SPI device is null");
return -RT_ERROR;
}
dw_spi_dev->tx = (void *)message->send_buf;
dw_spi_dev->tx_end = dw_spi_dev->tx + dw_spi_dev->tx_len;
dw_spi_dev->rx = (void *)message->recv_buf;
dw_spi_dev->rx_end = dw_spi_dev->rx + dw_spi_dev->rx_len;
dw_spi_dev->tx_len = message->length;
dw_spi_dev->rx_len = message->length;
if (dw_spi_dev->tx && dw_spi_dev->rx)
{
/* set mode to Tx & Rx */
dw_spi_dev->tmode = DW_SPI_CTRLR0_TMOD_TX_RX;
}
else if (dw_spi_dev->rx)
{
/* set mode to Rx only */
dw_spi_dev->tmode = DW_SPI_CTRLR0_TMOD_RX;
}
else
{
/* set mode to Tx only */
dw_spi_dev->tmode = DW_SPI_CTRLR0_TMOD_TX;
}
struct dw_spi_regs *regs = dw_spi_dev->reg;
/* disable spi */
writel(0, &regs->ssienr);
LOG_D("dw_spixfer:tx 0x%x rx 0x%x len %d\n", dw_spi_dev->tx, dw_spi_dev->rx, message->length);
rt_uint32_t cr0 = dw_spi_dev->update_cr0(dw_spi_dev);
/* write control register */
if (cr0 != readl(&regs->ctrl0))
{
writel(cr0, &regs->ctrl0);
}
/* set slave select */
writel(1 << (dw_spi_dev->cs), &regs->ser);
/* enable spi */
writel(1, &regs->ssienr);
/* transfer data */
dw_spi_poll_transfer(dw_spi_dev);
/* wait for transfer complete */
wait_for_idle(dw_spi_dev);
return message->length;
}
const static struct rt_spi_ops dw_drv_spi_ops =
{
_dw_drv_spi_configure,
_dw_spixfer,
};
static int dw_spi_hw_init(struct dw_spi *dw_spi_dev)
{
struct dw_spi_regs *regs = dw_spi_dev->reg;
/* disable spi */
writel(0, &regs->ssienr);
/* disbale all interrupts */
writel(0, &regs->imr);
/* read and clear interrupt status */
readl(&regs->icr);
/* set slave select */
writel(0, &regs->ser);
/* enable spi */
writel(1, &regs->ssienr);
dw_spi_dev->version = readl(&regs->version);
rt_kprintf("ssi_version_id=%c.%c%c%c\n",
dw_spi_dev->version >> 24, dw_spi_dev->version >> 16,
dw_spi_dev->version >> 8, dw_spi_dev->version);
/* detect the FIFO depth if not set by interface driver */
if (!dw_spi_dev->fifo_len)
{
uint32_t fifo;
for (fifo = 1; fifo < 256; fifo++)
{
writel(fifo, &regs->txftlr);
if (fifo != readl(&regs->txftlr))
{
break;
}
}
dw_spi_dev->fifo_len = (fifo == 1) ? 0 : fifo;
writel(0, &regs->txftlr);
rt_kprintf("fifo length is %d\n", dw_spi_dev->fifo_len);
}
rt_uint32_t cr0, tmp = readl(&regs->ctrl0);
writel(0, &regs->ssienr);
writel(0xffffffff, &regs->ctrl0);
cr0 = readl(&regs->ctrl0);
writel(tmp, &regs->ctrl0);
writel(1, &regs->ssienr);
if (cr0 & DW_SPI_CTRLR0_DFS_MASK)
{
dw_spi_device.update_cr0 = update_control_reg_16;
}
else
{
dw_spi_device.update_cr0 = update_control_reg_32;
}
return 0;
}
int rt_hw_dw_spi_init(void)
{
rt_err_t ret = RT_EOK;
struct dw_spi_regs *reg = NULL;
/* set reg base */
#ifdef RT_USING_SMART
reg = (struct dw_spi_regs *)rt_ioremap((void *)DW_SPI_BASE_ADDR, sizeof(struct dw_spi_regs));
#else
reg = (struct dw_spi_regs *)DW_SPI_BASE_ADDR;
#endif
LOG_D("%s: reg base %p\n", __func__, reg);
if (!reg)
return -RT_ERROR;
dw_spi_device.reg = reg;
dw_spi_device.spi_bus.parent.user_data = &dw_spi_device;
dw_spi_device.tmode = 0; /* Tx & Rx */
dw_spi_device.bits_per_word = 8;
/* init spi */
dw_spi_hw_init(&dw_spi_device);
/* Register SPI bus*/
ret = rt_spi_bus_register(&dw_spi_device.spi_bus, dw_spi_device.device_name, &dw_drv_spi_ops);
if (ret == RT_EOK)
{
static struct rt_spi_device spi_device0;
rt_spi_bus_attach_device(&spi_device0, SPI0_BUS_DEVICE0_NAME, SPI0_BUS_NAME, (void *)&dw_spi_device);
}
return ret;
}
INIT_BOARD_EXPORT(rt_hw_dw_spi_init);
#endif /* BSP_USING_DW_SPI */

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* spi driver for synopsys dw apb spi
*
* Change Logs:
* Date Author Notes
* 2025-01-03 ZhangJing first version
*/
#ifndef __DRV_DW_SPI_H__
#define __DRV_DW_SPI_H__
/* dw spi register */
struct dw_spi_regs
{
uint32_t ctrl0; /* 0x00:Control Register 0 (ctrl0) */
uint32_t ctrl1; /* 0x04:Control Register 1 (ctrl1) */
uint32_t ssienr; /* 0x08:Synchronous Serial Interface Enable Register (ssienr) */
uint32_t mwcr; /* 0x0c:Master Mode Control Register (mwcr) */
uint32_t ser; /* 0x10:Slave Enable Register (ser) */
uint32_t baudr; /* 0x14:Baud Rate Select Register (baudr) */
uint32_t txftlr; /* 0x18:Transmit FIFO Threshold Level Register (txftlr) */
uint32_t rxftlr; /* 0x1c:Receive FIFO Threshold Level Register (rxftlr) */
uint32_t txflr; /* 0x20:Transmit FIFO Level Register (txflr) */
uint32_t rxflr; /* 0x24:Receive FIFO Level Register (rxflr) */
uint32_t sr; /* 0x28:Status Register (sr) */
uint32_t imr; /* 0x2c:Interrupt Mask Register (imr) */
uint32_t isr; /* 0x30:Interrupt Status Register (isr) */
uint32_t risr; /* 0x34:Raw Interrupt Status Register (risr) */
uint32_t txoicr; /* 0x38:Transmit FIFO Overflow Interrupt Clear Register (txoicr) */
uint32_t rxoicr; /* 0x3c:Receive FIFO Overflow Interrupt Clear Register (rxoicr) */
uint32_t rxuicr; /* 0x40:Receive FIFO Underflow Interrupt Clear Register (rxuicr) */
uint32_t msticr; /* 0x44:Multi-Master Contention Interrupt Clear Register (msticr) */
uint32_t icr; /* 0x48:Interrupt Clear Register (icr) */
uint32_t dmacr; /* 0x4c:DMA Control Register (dmacr) */
uint32_t dmatdlr; /* 0x50:DMA Transmit Data Level Register (dmatdlr) */
uint32_t dmardlr; /* 0x54:DMA Receive Data Level Register (dmardlr) */
uint32_t idr; /* 0x58:Identification Register (idr) */
uint32_t version; /* 0x5c:Version Register (version) */
uint32_t dr[36]; /* 0x60:Data Register (dr) */
uint32_t rx_sample_delay; /* 0xf0: RX Sample Delay Register */
uint32_t spi_ctrl0; /* 0xf4*/
uint32_t txd_drive_edge; /* 0xf8*/
uint32_t rsvd; /* 0xfc*/
};
/* dw spi device */
struct dw_spi
{
struct dw_spi_regs *reg;
struct rt_spi_bus spi_bus;
char *device_name;
uint32_t version;
int irq;
uint32_t fifo_len;
uint32_t max_freq;
int bits_per_word;
void *tx;
void *tx_end;
void *rx;
void *rx_end;
unsigned int tx_len;
unsigned int rx_len;
uint32_t (*update_cr0)(struct dw_spi *dw_spi_dev);
uint8_t mode;
uint8_t cs; /* chip select pin */
uint8_t tmode; /* TR/TO/RO/EEPROM */
uint8_t type; /* SPI/SSP/MicroWire */
};
/* CTRLR0 bit definiation */
#define DW_SPI_CTRLR0_DFS_MASK ((uint32_t)0x000F)
#define CTRLR0_DFS_SHIFT 0
#define DW_SPI_CTRLR0_DFS_0 ((uint32_t)(1<<0))
#define DW_SPI_CTRLR0_DFS_1 ((uint32_t)(1<<1))
#define DW_SPI_CTRLR0_DFS_2 ((uint32_t)(1<<2))
#define DW_SPI_CTRLR0_DFS_3 ((uint32_t)(1<<3))
#define DW_SPI_CTRLR0_FRF_SHIFT (4)
#define DW_SPI_CTRLR0_FRF_MOT (0)
#define DW_SPI_CTRLR0_FRF_TI (1)
#define DW_SPI_CTRLR0_FRF_MICROWIRE (2)
#define DW_SPI_CTRLR0_FRF_RESV (3)
#define DW_SPI_CTRLR0_MODE_SHIFT (6)
#define DW_SPI_CTRLR0_SCPH ((uint32_t)(1<<6))
#define DW_SPI_CTRLR0_SCPOL ((uint32_t)(1<<7))
#define DW_SPI_CTRLR0_TMOD_SHIFT (8)
#define DW_SPI_CTRLR0_TMOD_TX_RX (0) /* transmit and receive */
#define DW_SPI_CTRLR0_TMOD_TX (1) /* transmit only */
#define DW_SPI_CTRLR0_TMOD_RX (2) /* receive only */
#define DW_SPI_CTRLR0_TMOD_EEPROM_READ (3) /* eeprom read mode */
#define CTRLR0_DFS_32_SHIFT (16)
#define DW_SPI_CTRLR0_SLV_OE ((uint32_t)(1<<10)) /* salve output enable */
#define DW_SPI_CTRLR0_SRL ((uint32_t)(1<<11)) /* shift register loop */
#define DW_SPI_CTRLR0_CFS ((uint32_t)(0xF << 12)) /* control frame size */
#define DW_SPI_SR_BUSY ((uint32_t)(1<<0))
#define DW_SPI_SR_TX_EMPTY ((uint32_t)(1<<2))
#endif /* __DRV_DW_SPI_H__ */

View File

@ -0,0 +1,187 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-05-28 ZhangJing Porting to ultrarisc dp1000
*/
#include <rthw.h>
#include <rtdevice.h>
#include <rtthread.h>
#include "board.h"
#include "drv_uart.h"
#include <stdio.h>
#ifdef RT_USING_SMART
#include <ioremap.h>
#endif
#include "sbi.h"
struct device_uart
{
rt_ubase_t hw_base;
rt_uint32_t irqno;
};
#ifdef BSP_USING_UART0
void *uart0_base = (void *)UART0_BASE_ADDR;
struct rt_serial_device serial0;
struct device_uart uart0;
#define UART0_CLK (UART0_REFERENCE_CLOCK)
#define UART0_BAUDRATE (UART0_DEFAULT_BAUDRATE)
#endif
#define UART_REFERENCE_CLOCK (UART0_CLK)
#define REG_SHIFT (1 << UART0_REG_SHIFT)
#define write8_uart(base,idx, value) __raw_writeb(((rt_uint8_t)value), (void*)((size_t)base + (idx*REG_SHIFT)))
#define read8_uart(base,idx) __raw_readb((void*)((size_t)base + (idx*REG_SHIFT)))
static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
struct device_uart *uart = (struct device_uart *)serial->parent.user_data;
rt_uint32_t div = UART_REFERENCE_CLOCK / (cfg->baud_rate * 16);
rt_uint32_t ier = read8_uart(uart->hw_base, UART_IER);
write8_uart(uart->hw_base, UART_IER, 0x00);
write8_uart(uart->hw_base, UART_LCR, UART_LCR_BAUD_LATCH);
/* LSB */
write8_uart(uart->hw_base, 0, div & 0xff);
/* MSB */
write8_uart(uart->hw_base, 1, (div >> 8) & 0xff);
/* set word length to 8 bits, no parity */
write8_uart(uart->hw_base, UART_LCR, UART_LCR_EIGHT_BITS);
write8_uart(uart->hw_base, UART_FCR, UART_FCR_FIFO_ENABLE | UART_FCR_FIFO_CLEAR);
write8_uart(uart->hw_base, UART_IER, ier);
return (RT_EOK);
}
static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
struct device_uart *uart = (struct device_uart *)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
{
rt_uint8_t value = read8_uart(uart->hw_base, UART_IER);
write8_uart(uart->hw_base, UART_IER, value & ~UART_IER_RX_ENABLE);
}
break;
case RT_DEVICE_CTRL_SET_INT:
if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
{
rt_uint8_t value = read8_uart(uart->hw_base, UART_IER);
write8_uart(uart->hw_base, UART_IER, value | UART_IER_RX_ENABLE);
}
break;
}
return (RT_EOK);
}
static int _uart_putc(struct rt_serial_device *serial, char c)
{
struct device_uart *uart;
uart = (struct device_uart *)serial->parent.user_data;
/* wait for Transmit Holding Empty to be set in LSR. */
while ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_TX_IDLE) == 0)
;
write8_uart(uart->hw_base, UART_THR, c);
return (1);
}
static int _uart_getc(struct rt_serial_device *serial)
{
struct device_uart *uart;
volatile rt_uint32_t lsr;
int ch = -1;
uart = (struct device_uart *)serial->parent.user_data;
lsr = read8_uart(uart->hw_base, UART_LSR);
if (lsr & UART_LSR_RX_READY)
{
ch = read8_uart(uart->hw_base, UART_RHR);
}
return ch;
}
const struct rt_uart_ops _uart_ops =
{
_uart_configure,
_uart_control,
_uart_putc,
_uart_getc,
/* TODO: add DMA support */
RT_NULL
};
static void rt_hw_uart_isr(int irqno, void *param)
{
rt_ubase_t level = rt_hw_interrupt_disable();
struct rt_serial_device *serial = (struct rt_serial_device *)param;
struct device_uart *uart = (struct device_uart *)serial->parent.user_data;
if ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_RX_READY) != 0)
{
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
}
rt_hw_interrupt_enable(level);
return;
}
/*
* UART Initiation
*/
int rt_hw_uart_init(void)
{
struct rt_serial_device *serial;
struct device_uart *uart;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
char ch;
#ifdef BSP_USING_UART0
/* register device */
serial = &serial0;
uart = &uart0;
serial->ops = &_uart_ops;
serial->config = config;
serial->config.baud_rate = UART0_BAUDRATE;
uart->hw_base = (rt_ubase_t)uart0_base;
#ifdef RT_USING_SMART
uart->hw_base = (rt_ubase_t)rt_ioremap((void *)uart0_base, 0x1000);
#endif
uart->irqno = UART0_IRQ_BASE;
/* disable all uart irqs */
write8_uart(uart->hw_base, UART_IER, 0);
/* wait for Transmit Holding Empty to be set in LSR. */
while ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_TX_IDLE) == 0)
;
while ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_RX_READY) != 0)
{
ch = read8_uart(uart->hw_base, UART_RHR);
}
rt_hw_serial_register(serial,
RT_CONSOLE_DEVICE_NAME,
RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart);
rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, RT_CONSOLE_DEVICE_NAME);
rt_hw_interrupt_umask(uart->irqno);
#endif
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-05-28 ZhangJing Porting to ultrarisc dp1000
*/
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include "riscv_io.h"
/**
* uart ns16550a
* http://byterunner.com/16550.html
*/
/* TRANSMIT AND RECEIVE HOLDING REGISTER */
#define UART_RHR 0
#define UART_THR 0
/* INTERRUPT ENABLE REGISTER */
#define UART_IER 1
#define UART_IER_RX_ENABLE (1 << 0)
#define UART_IER_TX_ENABLE (1 << 1)
/* FIFO CONTROL REGISTER */
#define UART_FCR 2
#define UART_FCR_FIFO_ENABLE (1 << 0)
#define UART_FCR_FIFO_CLEAR (3 << 1)
/* INTERRUPT STATUS REGISTER */
#define UART_ISR 2
/* LINE CONTROL REGISTER */
#define UART_LCR 3
#define UART_LCR_EIGHT_BITS (3 << 0)
/* special mode to set baud rate */
#define UART_LCR_BAUD_LATCH (1 << 7)
/* LINE STATUS REGISTER */
#define UART_LSR 5
/* input is waiting to be read from RHR */
#define UART_LSR_RX_READY (1 << 0)
/* THR can accept another character to send */
#define UART_LSR_TX_IDLE (1 << 5)
/*#define UART_REFERENCE_CLOCK 1843200
#define UART_DEFAULT_BAUDRATE 115200*/
extern void *uart0_base;
void rt_hw_uart_start_rx_thread();
int rt_hw_uart_init(void);
void drv_uart_puts(char *str); /* for syscall */
#endif /* __DRV_UART_H__ */

View File

@ -0,0 +1,7 @@
peripheral.MMC:
kconfig:
- CONFIG_BSP_USING_DW_SPI=y
- CONFIG_DW_SPI_IRQ_BASE=19
- CONFIG_DW_SPI_BASE_ADDR=0x20320000
- CONFIG_DW_SPI_MAX_FREQ=62500000
- CONFIG_BSP_USING_MMC=y

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
mainmenu "RT-Thread Project Configuration"
BSP_DIR := .
RTT_DIR := ../../..
PKGS_DIR := packages
source "$(RTT_DIR)/Kconfig"
osource "$PKGS_DIR/Kconfig"
rsource "board/Kconfig"
config BOARD_UR_DP1000
bool
select ARCH_RISCV64
select ARCH_USING_RISCV_COMMON64
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select RT_USING_CACHE
select ARCH_MM_MMU
select ARCH_USING_ASID
select ARCH_RISCV_FPU_D
select ARCH_REMAP_KERNEL if RT_USING_SMART
select RT_USING_DEVICE_OPS
default y
config __STACKSIZE__
int "stack size for interrupt"
default 4096

View File

@ -0,0 +1,168 @@
UR-DP1000 Evb Board Support Package 使用说明
# 1. 概述
UR-DP1000是超睿科技研发的高性能多核RISC-V Soc拥有8个高性能自研RISC-V处理器核UR-CP100同时集成了24路PCIe 4.0、双路DDR 4以及一系列丰富的低速接口。
本 BSP 支持 UR-DP1000 EVB开发板。采用本BSP编译生成的RT-Thread标准版本以及Smart版本可以运行在 UR-DP1000 EVB开发板上。板卡集成16GB DDR4内存。
# 2. 芯片规格说明
| 硬件 | 描述 |
| -- | -- |
|芯片型号| UR-DP1000 |
|CPU| 8核UR-CP10064位乱序发射超标量微架构支持rv64imafdchx指令集支持虚拟化扩展 |
|主频| 2.0-2.3GHz |
|cache| 核内集成64KB L1I和64KB L1D Cache以及512KB L2 Cache |
| 外设 | 支持两路DDR4支持ECC最大支持内存容量128GB |
| | 支持24路PCIe 4.0接口 |
| | SPI、UART、QSPI、UART、GMAC、I2C、PWM、GPIO等 |
# 3. BSP外设支持
| 设备名称 | 支持情况 | 说明 |
| -------- | -------- | ---------------------------------------------------------- |
| PLIC | 支持 | 中断控制器 |
| CLINT | 支持 | RISC-V core local 中断控制器,系统时钟及核间中断依赖该设备 |
| MMU | 支持 | 支持SV39支持ASID |
| UART | 支持 | 调试串口 |
| SPI | 支持 | Designware apb ssi ,支持TF卡驱动 |
# 4. 编译
RT-Thread编译只支持Linux推荐Ubuntu 22.04。
## 4.1. toolchain下载
toolchain下载地址<https://download.rt-thread.org/rt-smart/riscv64/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_251248.tar.bz2>
将下载的toolchain解压到指定路径中例如/opt/riscv64gc-linux-musleabi_for_x86_64-pc-linux-gnu
## 4.2. BSP编译
### 4.2.1. 设置编译环境变量
```shell
export RTT_EXEC_PATH=/opt/riscv64gc-linux-musleabi_for_x86_64-pc-linux-gnu/bin
export RTT_CC_PREFIX=riscv64-unknown-linux-musl-
```
### 4.2.2. 安装编译依赖
```shell
sudo apt install scons python3-pip
pip install kconfiglib
```
### 4.2.3. 编译
```shell
git clone https://github.com/RT-Thread/rt-thread.git
cd bsp/ultrarisc/ur_dp1000_evb
#默认为RT-Thread标准版
scons
```
编译完成后可以在bsp目录下生成rt-thread.elf及rtthread.bin文件。
如果要编译RT-Thread Smart版本需要通过scons --menuconfig使能RT-Thread Kernel->Enable RT-Thread Smart (microkernel on kernel/userland);
同时使能SPI MMC驱动Ultrarisc DP1000 Soc Drivers Configuration->Using MMC。
# 5. 运行
编译完成后在UR-DP1000 EVB板卡上可以通过jtag加载镜像运行
在RT-Thread调试阶段为了能够快速的下载RT-Thread镜像方便功能调试可以通过jtag下载及调试
- 板卡上电后首先运行固化在flash里的固件opensbi启动
- 将jtag调试器与板卡jtag口连接同时启动openocd;
- 如果是标准版本可以直接通过gdb加载rt-thread.elf然后continue运行如果是RT-Thread Smart版本需要通过gdb加载rtthread.bin然后修改pc值为0x80200000,continue运行。
```shell
#gdb
restore rtthread.bin binary 0x80200000
set $pc=0x80200000
continue
```
成功运行时,串口端的输出如下:
```shell
OpenSBI v1.6-66-gbeb27559acd
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : ultrarisc,dp1000
Platform Features : medeleg
Platform HART Count : 8
Platform IPI Device : aclint-mswi
Platform Timer Device : aclint-mtimer @ 10000000Hz
Platform Console Device : uart8250
Platform HSM Device : ---
Platform PMU Device : ---
Platform Reboot Device : ---
Platform Shutdown Device : ---
Platform Suspend Device : ---
Platform CPPC Device : ---
Firmware Base : 0x80000000
Firmware Size : 403 KB
Firmware RW Offset : 0x40000
Firmware RW Size : 147 KB
Firmware Heap Offset : 0x54000
Firmware Heap Size : 67 KB (total), 4 KB (reserved), 11 KB (used), 51 KB (free)
Firmware Scratch Size : 4096 B (total), 400 B (used), 3696 B (free)
Runtime SBI Version : 2.0
Standard SBI Extensions : time,rfnc,ipi,base,hsm,pmu,dbcn,legacy
Experimental SBI Extensions : fwft,sse
Domain0 Name : root
Domain0 Boot HART : 0
Domain0 HARTs : 0*,1*,2*,3*,16*,17*,18*,19*
Domain0 Region00 : 0x0000000020310000-0x0000000020310fff M: (I,R,W) S/U: (R,W)
Domain0 Region01 : 0x0000000080000000-0x000000008003ffff M: (R,X) S/U: ()
Domain0 Region02 : 0x0000000080040000-0x000000008007ffff M: (R,W) S/U: ()
Domain0 Region03 : 0x0000000008000000-0x00000000080fffff M: (I,R,W) S/U: ()
Domain0 Region04 : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)
Domain0 Next Address : 0x0000000080200000
Domain0 Next Arg1 : 0x0000000082200000
Domain0 Next Mode : S-mode
Domain0 SysReset : yes
Domain0 SysSuspend : yes
Boot HART ID : 0
Boot HART Domain : root
Boot HART Priv Version : v1.12
Boot HART Base ISA : rv64imafdchx
Boot HART ISA Extensions : zicntr,zihpm
Boot HART PMP Count : 4
Boot HART PMP Granularity : 2 bits
Boot HART PMP Address Bits : 42
Boot HART MHPM Info : 6 (0x000001f8)
Boot HART Debug Triggers : 0 triggers
Boot HART MIDELEG : 0x0000000000000666
Boot HART MEDELEG : 0x0000000000f0b509
Test payload running
ssi_version_id=4.03*
fifo length is 64
heap: [0x002acb28 - 0x042acb28]
\ | /
- RT - Thread Smart Operating System
/ | \ 5.2.1 build May 28 2025 08:24:41
2006 - 2024 Copyright by RT-Thread team
[I/drivers.serial] Using /dev/ttyS0 as default console
Mount "/dev/sd0p1" on "/"
Hello RT-Thread
msh />
/ #
```
# 6. 联系人信息
zhangjing@ultrarisc.com

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')

View File

@ -0,0 +1,63 @@
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='ur-cp100'
rtconfig.ARCH='risc-v'
stack_size = 4096
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
if GetDepend('RT_USING_SMART'):
# use smart link.lds
env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds')
# os.system('cp .configmini .config')
#copy rtconfig.hmini to rtconfig.h
# os.system('cp rtconfig.hmini rtconfig.h')
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()
SDK_ROOT = os.path.abspath('./')
if os.path.exists(SDK_ROOT + '/drivers'):
drivers_path_prefix = SDK_ROOT + '/drivers'
else:
drivers_path_prefix = os.path.dirname(SDK_ROOT) + '/drivers'
if os.path.exists(SDK_ROOT + '/arch/ur-cp100'):
arch_path_prefix = SDK_ROOT + '/arch/ur-cp100'
else:
arch_path_prefix = os.path.dirname(SDK_ROOT) + '/arch/ur-cp100'
# include libraries
objs.extend(SConscript(drivers_path_prefix + '/SConscript', variant_dir='build/drivers', duplicate=0))
objs.extend(SConscript(arch_path_prefix + '/SConscript', variant_dir='build/arch/ur-cp100', duplicate=0))
# make a building
DoBuilding(TARGET, objs)

View File

@ -0,0 +1,18 @@
from building import *
import os
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
if not GetDepend('BSP_USING_DW_SPI'):
SrcRemove(src, ['mnt.c'])
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))
Return('group')

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-01-22 ZhangJing first version
*/
#include <stdio.h>
#include <string.h>
#include <rtthread.h>
int main(void)
{
rt_kprintf("Hello RT-Thread\n");
return 0;
}

View File

@ -0,0 +1,21 @@
#include <rtthread.h>
#include <rtconfig.h>
#include <dev_spi_msd.h>
#include <dfs_fs.h>
int mnt_init(void)
{
msd_init("sd0", "spi00");
if (dfs_mount("sd0", "/", "ext", 0, 0) == 0)
{
rt_kprintf("Mount \"/dev/sd0p1\" on \"/\"\n");
}
else if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
{
rt_kprintf("Mount \"/dev/sd0p1\" on \"/\"\n");
}
return 0;
}
INIT_ENV_EXPORT(mnt_init);

View File

@ -0,0 +1,69 @@
menu "Ultrarisc DP1000 Soc Drivers Configuration"
menuconfig BSP_USING_PLIC
bool "Using PLIC"
default y
if BSP_USING_PLIC
config PLIC_BASE_ADDR
hex "plic base mmio addr"
default 0x9000000
config PLIC_NDEV
hex "plic supported irqs"
default 160
endif
menuconfig BSP_USING_UART0
bool "Using UART0"
select RT_USING_SERIAL
default y
if BSP_USING_UART0
config UART0_IRQ_BASE
int "uart0 irq number"
default 18
config UART0_REFERENCE_CLOCK
int "uart0 clock"
default 62500000
config UART0_DEFAULT_BAUDRATE
int "uart0 baudrate"
default 115200
config UART0_BASE_ADDR
hex "uart0 base mmio addr"
default 0x20310000
config UART0_REG_SHIFT
int "uart0 reg shift"
default 2
endif
menuconfig BSP_USING_DW_SPI
bool "Using Dw apb ssi SPI"
select RT_USING_SPI
default n
if BSP_USING_DW_SPI
config DW_SPI_IRQ_BASE
int "spi irq number"
default 19
config DW_SPI_BASE_ADDR
hex "dw spi base mmio addr"
default 0x20320000
config DW_SPI_MAX_FREQ
int "dw max spi freq"
default 62500000
endif
menuconfig BSP_USING_MMC
bool "Using MMC"
select BSP_USING_SPI
select RT_USING_SPI_MSD
select RT_USING_DFS_ELMFAT
default n
endmenu

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')

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-01-22 ZhangJing first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "tick.h"
#include "drv_uart.h"
#include "sbi.h"
#include "riscv.h"
#include "plic.h"
#ifdef RT_USING_SMART
#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},
};
#define NUM_MEM_DESC (sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]))
#endif
void primary_cpu_entry(void)
{
/* disable global interrupt */
rt_hw_interrupt_disable();
entry();
}
/*initialize the bss section*/
void init_bss(void)
{
unsigned int *dst;
dst = &__bss_start;
while (dst < &__bss_end)
{
*dst++ = 0;
}
}
#define IOREMAP_SIZE (1ul << 30)
#ifndef ARCH_REMAP_KERNEL
#define IOREMAP_VEND USER_VADDR_START
#else
#define IOREMAP_VEND 0ul
#endif
/*set the plic base*/
void set_plic_base(void)
{
plic_base = PLIC_BASE_ADDR;
return;
}
void rt_hw_board_init(void)
{
#if defined(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
/*set the plic base*/
set_plic_base();
/* 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);

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023/06/25 flyingcys first version
* 2025-05-28 ZhangJing Porting to ultrarisc dp1000
*/
#ifndef BOARD_H__
#define BOARD_H__
#include <rtconfig.h>
extern unsigned int __bss_start;
extern unsigned int __bss_end;
#ifndef RT_USING_SMART
#define KERNEL_VADDR_START 0x0
#endif
#define VIRT64_SBI_MEMSZ (0x200000)
#define RT_HW_HEAP_BEGIN ((void *)&__bss_end)
#define RT_HW_HEAP_END ((void *)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024))
#define RT_HW_PAGE_START RT_HW_HEAP_END
#define RT_HW_PAGE_END ((void *)(KERNEL_VADDR_START + (256 * 1024 * 1024 - VIRT64_SBI_MEMSZ)))
void rt_hw_board_init(void);
#endif

View File

@ -0,0 +1,185 @@
/*
* 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:
* 0x80000000 - 0x80200000: SBI
* 0x80200000 - 0x81200000: Kernel
*/
MEMORY
{
SRAM : ORIGIN = 0x80200000, LENGTH = 0x1000000
}
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
.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,185 @@
/*
* 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:
* 0x80000000 - 0x80200000: SBI
* 0x80200000 - 0x81200000: Kernel
*/
MEMORY
{
SRAM : ORIGIN = 0xFFFFFFC000200000, LENGTH = 0x1000000 - 0x200000
}
ENTRY(_start)
SECTIONS
{
. = 0xFFFFFFC000200000;
/* __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
.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__ = 16384;

View File

@ -0,0 +1,476 @@
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
/* RT-Thread Kernel */
/* klibc options */
/* rt_vsnprintf options */
#define RT_KLIBC_USING_VSNPRINTF_LONGLONG
#define RT_KLIBC_USING_VSNPRINTF_STANDARD
#define RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS
#define RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS
#define RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER
#define RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER
#define RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE 32
#define RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE 32
#define RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION 6
#define RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9
#define RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS 4
/* end of rt_vsnprintf options */
/* rt_vsscanf options */
/* end of rt_vsscanf options */
/* rt_memset options */
/* end of rt_memset options */
/* rt_memcpy options */
/* end of rt_memcpy options */
/* rt_memmove options */
/* end of rt_memmove options */
/* rt_memcmp options */
/* end of rt_memcmp options */
/* rt_strstr options */
/* end of rt_strstr options */
/* rt_strcasecmp options */
/* end of rt_strcasecmp options */
/* rt_strncpy options */
/* end of rt_strncpy options */
/* rt_strcpy options */
/* end of rt_strcpy options */
/* rt_strncmp options */
/* end of rt_strncmp options */
/* rt_strcmp options */
/* end of rt_strcmp options */
/* rt_strlen options */
/* end of rt_strlen options */
/* rt_strnlen options */
/* end of rt_strnlen options */
/* end of klibc options */
#define RT_NAME_MAX 8
#define RT_CPUS_NR 1
#define RT_ALIGN_SIZE 8
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 100
#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 4096
#define RT_USING_TIMER_SOFT
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 8192
#define RT_USING_CPU_USAGE_TRACER
/* kservice options */
/* end of kservice options */
#define RT_USING_DEBUG
#define RT_DEBUGING_ASSERT
#define RT_DEBUGING_COLOR
#define RT_DEBUGING_CONTEXT
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_EVENT
#define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE
/* end of Inter-Thread communication */
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_HEAP
/* end of Memory Management */
#define RT_USING_DEVICE
#define RT_USING_DEVICE_OPS
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart0"
#define RT_VER_NUM 0x50201
#define RT_USING_STDC_ATOMIC
#define RT_BACKTRACE_LEVEL_MAX_NR 32
/* end of RT-Thread Kernel */
#define ARCH_CPU_64BIT
#define RT_USING_CACHE
#define ARCH_MM_MMU
#define ARCH_RISCV
#define ARCH_RISCV_FPU
#define ARCH_RISCV_FPU_D
#define ARCH_RISCV64
#define ARCH_USING_NEW_CTX_SWITCH
#define ARCH_USING_RISCV_COMMON64
#define ARCH_USING_ASID
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 16384
#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
#define FINSH_USING_OPTION_COMPLETION
/* 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_V2
#define RT_USING_DFS_ELMFAT
/* elm-chan's FatFs, Generic FAT Filesystem Module */
#define RT_DFS_ELM_CODE_PAGE 437
#define RT_DFS_ELM_WORD_ACCESS
#define RT_DFS_ELM_USE_LFN_3
#define RT_DFS_ELM_USE_LFN 3
#define RT_DFS_ELM_LFN_UNICODE_0
#define RT_DFS_ELM_LFN_UNICODE 0
#define RT_DFS_ELM_MAX_LFN 255
#define RT_DFS_ELM_DRIVES 2
#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
#define RT_DFS_ELM_REENTRANT
#define RT_DFS_ELM_MUTEX_TIMEOUT 3000
/* end of elm-chan's FatFs, Generic FAT Filesystem Module */
#define RT_USING_DFS_DEVFS
/* end of DFS: device virtual file system */
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_UNAMED_PIPE_NUMBER 64
#define RT_USING_SYSTEM_WORKQUEUE
#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V1
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_SERIAL_BYPASS
#define RT_USING_CPUTIME
#define RT_USING_CPUTIME_RISCV
#define CPUTIME_TIMER_FREQ 10000000
#define RT_USING_NULL
#define RT_USING_ZERO
#define RT_USING_RANDOM
#define RT_USING_RTC
#define RT_USING_SPI
#define RT_USING_SPI_MSD
#define RT_USING_BLK
/* Partition Types */
#define RT_BLK_PARTITION_DFS
#define RT_BLK_PARTITION_EFI
/* end of Partition Types */
#define RT_USING_PIN
#define RT_USING_KTIME
/* end of Device Drivers */
/* C/C++ and POSIX layer */
/* ISO-ANSI C layer */
/* Timezone and Daylight Saving Time */
#define RT_LIBC_USING_LIGHT_TZ_DST
#define RT_LIBC_TZ_DEFAULT_HOUR 8
#define RT_LIBC_TZ_DEFAULT_MIN 0
#define RT_LIBC_TZ_DEFAULT_SEC 0
/* end of Timezone and Daylight Saving Time */
/* end of ISO-ANSI C layer */
/* 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 */
/* end of Interprocess Communication (IPC) */
/* end of POSIX (Portable Operating System Interface) layer */
/* end of C/C++ and POSIX layer */
/* Network */
/* end of Network */
/* Memory protection */
/* end of Memory protection */
/* Utilities */
#define RT_USING_RESOURCE_ID
#define RT_USING_ADT
#define RT_USING_ADT_AVL
#define RT_USING_ADT_BITMAP
#define RT_USING_ADT_HASHMAP
#define RT_USING_ADT_REF
/* end of Utilities */
/* Memory management */
#define RT_PAGE_AFFINITY_BLOCK_SIZE 0x1000
#define RT_PAGE_MAX_ORDER 11
/* Debugging */
/* end of Debugging */
/* end of Memory management */
/* Using USB legacy version */
/* end of Using USB legacy version */
/* end of RT-Thread Components */
/* RT-Thread Utestcases */
/* end of RT-Thread Utestcases */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* end of Marvell WiFi */
/* Wiced WiFi */
/* end of Wiced WiFi */
/* CYW43012 WiFi */
/* end of CYW43012 WiFi */
/* BL808 WiFi */
/* end of BL808 WiFi */
/* CYW43439 WiFi */
/* end of CYW43439 WiFi */
/* end of Wi-Fi */
/* IoT Cloud */
/* end of IoT Cloud */
/* end of IoT - internet of things */
/* security packages */
/* end of security packages */
/* language packages */
/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* XML: Extensible Markup Language */
/* end of XML: Extensible Markup Language */
/* end of language packages */
/* multimedia packages */
/* LVGL: powerful and easy-to-use embedded GUI library */
/* end of LVGL: powerful and easy-to-use embedded GUI library */
/* u8g2: a monochrome graphic library */
/* end of u8g2: a monochrome graphic library */
/* end of multimedia packages */
/* tools packages */
/* end of tools packages */
/* system packages */
/* enhanced kernel services */
/* end of enhanced kernel services */
/* acceleration: Assembly language or algorithmic acceleration packages */
/* end of acceleration: Assembly language or algorithmic acceleration packages */
/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* Micrium: Micrium software products porting for RT-Thread */
/* end of Micrium: Micrium software products porting for RT-Thread */
/* end of system packages */
/* peripheral libraries and drivers */
/* HAL & SDK Drivers */
/* STM32 HAL & SDK Drivers */
/* end of STM32 HAL & SDK Drivers */
/* Infineon HAL Packages */
/* end of Infineon HAL Packages */
/* Kendryte SDK */
/* end of Kendryte SDK */
/* end of HAL & SDK Drivers */
/* sensors drivers */
/* end of sensors drivers */
/* touch drivers */
/* end of touch drivers */
/* end of peripheral libraries and drivers */
/* AI packages */
/* end of AI packages */
/* Signal Processing and Control Algorithm Packages */
/* end of Signal Processing and Control Algorithm Packages */
/* miscellaneous packages */
/* project laboratory */
/* end of project laboratory */
/* samples: kernel and components samples */
/* end of samples: kernel and components samples */
/* entertainment: terminal games and other interesting software packages */
/* end of entertainment: terminal games and other interesting software packages */
/* end of miscellaneous packages */
/* Arduino libraries */
/* Projects and Demos */
/* end of Projects and Demos */
/* Sensors */
/* end of Sensors */
/* Display */
/* end of Display */
/* Timing */
/* end of Timing */
/* Data Processing */
/* end of Data Processing */
/* Data Storage */
/* Communication */
/* end of Communication */
/* Device Control */
/* end of Device Control */
/* Other */
/* end of Other */
/* Signal IO */
/* end of Signal IO */
/* Uncategorized */
/* end of Arduino libraries */
/* end of RT-Thread online packages */
/* Ultrarisc DP1000 Soc Drivers Configuration */
#define BSP_USING_PLIC
#define PLIC_BASE_ADDR 0x9000000
#define PLIC_NDEV 160
#define BSP_USING_UART0
#define UART0_IRQ_BASE 18
#define UART0_REFERENCE_CLOCK 62500000
#define UART0_DEFAULT_BAUDRATE 115200
#define UART0_BASE_ADDR 0x20310000
#define UART0_REG_SHIFT 2
/* end of Ultrarisc DP1000 Soc Drivers Configuration */
#define BOARD_UR_DP1000
#define __STACKSIZE__ 16384
#endif

View File

@ -0,0 +1,60 @@
import os
# toolchains options
ARCH ='risc-v'
CPU ='ur-cp100'
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 = os.getenv('RTT_EXEC_PATH') or '/usr/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'
CHIP_TYPE = 'ultrarisc'
if PLATFORM == 'gcc':
# toolchains
#PREFIX = 'riscv64-unknown-elf-'
PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-elf-'
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'
# + ' -Wl,--no-warn-rwx-segments'
DEVICE = ' -mcmodel=medany -march=rv64gc -mabi=lp64'
CFLAGS = DEVICE + ' -Wno-cpp -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 -fvar-tracking '
AFLAGS += ' -ggdb'
else:
CFLAGS += ' -O2 -Os'
CXXFLAGS = CFLAGS
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtthread.asm\n'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'

View File

@ -5,7 +5,7 @@ from building import *
Import('rtconfig')
common64_arch = ['virt64', 'c906', 'c908']
common64_arch = ['virt64', 'c906', 'c908','ur-cp100']
cwd = GetCurrentDir()
group = []
list = os.listdir(cwd)