mirror of https://github.com/RT-Thread/rt-thread
[bsp]增加超睿DP1000 bsp支持
This commit is contained in:
parent
890a4bad72
commit
c3d33f39d4
|
@ -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"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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')
|
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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')
|
|
@ -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, ®s->ssienr);
|
||||
writel(0, ®s->ser);
|
||||
writel(0, ®s->imr);
|
||||
writel(0, ®s->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, ®s->baudr);
|
||||
|
||||
/* write TX threshold register */
|
||||
writel(0, ®s->txflr);
|
||||
/* write RX threshold register */
|
||||
writel(0, ®s->rxflr);
|
||||
/* enable spi */
|
||||
writel(1, ®s->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(®s->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(®s->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, ®s->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(®s->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(®s->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, ®s->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(®s->ctrl0))
|
||||
{
|
||||
writel(cr0, ®s->ctrl0);
|
||||
}
|
||||
/* set slave select */
|
||||
writel(1 << (dw_spi_dev->cs), ®s->ser);
|
||||
|
||||
/* enable spi */
|
||||
writel(1, ®s->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, ®s->ssienr);
|
||||
/* disbale all interrupts */
|
||||
writel(0, ®s->imr);
|
||||
/* read and clear interrupt status */
|
||||
readl(®s->icr);
|
||||
/* set slave select */
|
||||
writel(0, ®s->ser);
|
||||
/* enable spi */
|
||||
writel(1, ®s->ssienr);
|
||||
|
||||
dw_spi_dev->version = readl(®s->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, ®s->txftlr);
|
||||
if (fifo != readl(®s->txftlr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
dw_spi_dev->fifo_len = (fifo == 1) ? 0 : fifo;
|
||||
writel(0, ®s->txftlr);
|
||||
rt_kprintf("fifo length is %d\n", dw_spi_dev->fifo_len);
|
||||
}
|
||||
|
||||
rt_uint32_t cr0, tmp = readl(®s->ctrl0);
|
||||
writel(0, ®s->ssienr);
|
||||
|
||||
writel(0xffffffff, ®s->ctrl0);
|
||||
cr0 = readl(®s->ctrl0);
|
||||
writel(tmp, ®s->ctrl0);
|
||||
|
||||
writel(1, ®s->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 */
|
|
@ -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__ */
|
|
@ -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
|
||||
}
|
|
@ -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__ */
|
|
@ -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
|
@ -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
|
|
@ -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-CP100,64位乱序发射超标量微架构,支持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
|
|
@ -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')
|
|
@ -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)
|
|
@ -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')
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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
|
|
@ -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')
|
|
@ -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);
|
|
@ -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
|
|
@ -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) }
|
||||
}
|
|
@ -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) }
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
__STACKSIZE__ = 16384;
|
|
@ -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
|
|
@ -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'
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue