arch/risc-v: Add support for SOPHGO SG2000 SoC (T-Head C906)

This PR adds support for the SOPHGO SG2000 SoC, based on T-Head C906 64-bit RISC-V Core. This will be used by the upcoming port of NuttX for Milk-V Duo S SBC.

Most of the code was derived from NuttX for Ox64 BL808. The source files are explained in the articles here: https://github.com/lupyuen/nuttx-sg2000

Modified Files in arch/risc-v:

`Kconfig`: Added ARCH_CHIP_SG2000 for SG2000 SoC

New Files in arch/risc-v:

`include/sg2000/chip.h`: SG2000 Definitions

`include/sg2000/irq.h`: External Interrupts

`src/sg2000/chip.h`: Interrupt Stack Macro

`src/sg2000/sg2000_allocateheap.c`: Kernel Heap

`src/sg2000/sg2000_head.S`: Linux Header and Boot Code

`src/sg2000/sg2000_irq.c`: Configure Interrupts

`src/sg2000/sg2000_irq_dispatch.c`: Dispatch Interrupts

`src/sg2000/sg2000_memorymap.h`: Memory Map

`src/sg2000/sg2000_mm_init.c`, `sg2000_mm_init.h`: Memory Mgmt

`src/sg2000/sg2000_pgalloc.c`: Page Allocator

`src/sg2000/sg2000_start.c`: Startup Code

`src/sg2000/sg2000_timerisr.c`: Timer Interrupt

`src/sg2000/hardware/sg2000_memorymap.h`: PLIC and UART Base Address

`src/sg2000/hardware/sg2000_plic.h`: PLIC Register Addresses

`src/sg2000/Kconfig`: SG2000 Config

`src/sg2000/Make.defs`: Makefile
This commit is contained in:
Lee Lup Yuen 2024-06-16 19:39:17 +08:00 committed by Xiang Xiao
parent 16d14218fc
commit 8e30c13441
18 changed files with 1619 additions and 0 deletions

View File

@ -322,6 +322,25 @@ config ARCH_CHIP_K230
---help---
Kendryte K230 SoC (RV64GCV and RV64GCVX C908 cores).
config ARCH_CHIP_SG2000
bool "SOPHGO SG2000"
select ARCH_RV64
select ARCH_RV_ISA_M
select ARCH_RV_ISA_A
select ARCH_RV_ISA_C
select ARCH_HAVE_FPU
select ARCH_HAVE_DPFPU
select ARCH_HAVE_MULTICPU
select ARCH_HAVE_MPU
select ARCH_MMU_TYPE_SV39
select ARCH_HAVE_ADDRENV
select ARCH_NEED_ADDRENV_MAPPING
select ARCH_HAVE_S_MODE
select ONESHOT
select ALARM_ARCH
---help---
SOPHGO SG2000 SoC.
config ARCH_CHIP_RISCV_CUSTOM
bool "Custom RISC-V chip"
select ARCH_CHIP_CUSTOM
@ -452,6 +471,7 @@ config ARCH_CHIP
default "jh7110" if ARCH_CHIP_JH7110
default "bl808" if ARCH_CHIP_BL808
default "k230" if ARCH_CHIP_K230
default "sg2000" if ARCH_CHIP_SG2000
config ARCH_RISCV_INTXCPT_EXTENSIONS
bool "RISC-V Integer Context Extensions"
@ -658,4 +678,7 @@ endif
if ARCH_CHIP_K230
source "arch/risc-v/src/k230/Kconfig"
endif
if ARCH_CHIP_SG2000
source "arch/risc-v/src/sg2000/Kconfig"
endif
endif # ARCH_RISCV

View File

@ -0,0 +1,24 @@
/****************************************************************************
* arch/risc-v/include/sg2000/chip.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_INCLUDE_SG2000_CHIP_H
#define __ARCH_RISCV_INCLUDE_SG2000_CHIP_H
#endif /* __ARCH_RISCV_INCLUDE_SG2000_CHIP_H */

View File

@ -0,0 +1,36 @@
/****************************************************************************
* arch/risc-v/include/sg2000/irq.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_INCLUDE_SG2000_IRQ_H
#define __ARCH_RISCV_INCLUDE_SG2000_IRQ_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Map RISC-V exception code to NuttX IRQ */
#define NR_IRQS (RISCV_IRQ_SEXT + 57)
#endif /* __ARCH_RISCV_INCLUDE_SG2000_IRQ_H */

View File

View File

@ -0,0 +1,30 @@
############################################################################
# arch/risc-v/src/sg2000/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include common/Make.defs
# Specify our HEAD assembly file. This will be linked as
# the first object file, so it will appear at address 0
HEAD_ASRC = sg2000_head.S
# Specify our C code within this directory to be included
CHIP_CSRCS = sg2000_start.c sg2000_irq_dispatch.c sg2000_irq.c
CHIP_CSRCS += sg2000_timerisr.c sg2000_allocateheap.c
CHIP_CSRCS += sg2000_mm_init.c sg2000_pgalloc.c

View File

@ -0,0 +1,75 @@
/****************************************************************************
* arch/risc-v/src/sg2000/chip.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_SG2000_CHIP_H
#define __ARCH_RISCV_SRC_SG2000_CHIP_H
/****************************************************************************
* Included Files
****************************************************************************/
/* Include the chip capabilities file */
#include <arch/sg2000/chip.h>
#include "sg2000_memorymap.h"
#include "hardware/sg2000_memorymap.h"
#include "hardware/sg2000_plic.h"
#include "riscv_internal.h"
#include "riscv_percpu.h"
/****************************************************************************
* Macro Definitions
****************************************************************************/
#ifdef __ASSEMBLY__
/****************************************************************************
* Name: setintstack
*
* Description:
* Set the current stack pointer to the "top" the correct interrupt stack
* for the current CPU.
*
****************************************************************************/
#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
.macro setintstack tmp0, tmp1
riscv_mhartid \tmp0
li \tmp1, STACK_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)
mul \tmp1, \tmp0, \tmp1
la \tmp0, g_intstacktop
sub sp, \tmp0, \tmp1
.endm
#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 15 */
#if CONFIG_ARCH_INTERRUPTSTACK > 15
#if !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE)
.macro setintstack tmp0, tmp1
csrr \tmp0, CSR_SCRATCH
REGLOAD sp, RISCV_PERCPU_IRQSTACK(\tmp0)
.endm
#endif /* !defined(CONFIG_SMP) && defined(CONFIG_ARCH_USE_S_MODE) */
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 15 */
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_SG2000_CHIP_H */

View File

@ -0,0 +1,32 @@
/****************************************************************************
* arch/risc-v/src/sg2000/hardware/sg2000_memorymap.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_SG2000_HARDWARE_SG2000_MEMORYMAP_H
#define __ARCH_RISCV_SRC_SG2000_HARDWARE_SG2000_MEMORYMAP_H
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Register Base Address ****************************************************/
#define SG2000_PLIC_BASE 0x70000000ul
#endif /* __ARCH_RISCV_SRC_SG2000_HARDWARE_SG2000_MEMORYMAP_H */

View File

@ -0,0 +1,51 @@
/****************************************************************************
* arch/risc-v/src/sg2000/hardware/sg2000_plic.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_SG2000_HARDWARE_SG2000_PLIC_H
#define __ARCH_RISCV_SRC_SG2000_HARDWARE_SG2000_PLIC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Interrupt Priority */
#define SG2000_PLIC_PRIORITY (SG2000_PLIC_BASE + 0x000000)
/* Hart 0 S-Mode Interrupt Enable */
#define SG2000_PLIC_ENABLE1 (SG2000_PLIC_BASE + 0x002080)
#define SG2000_PLIC_ENABLE2 (SG2000_PLIC_BASE + 0x002084)
/* Hart 0 S-Mode Priority Threshold */
#define SG2000_PLIC_THRESHOLD (SG2000_PLIC_BASE + 0x201000)
/* Hart 0 S-Mode Claim / Complete */
#define SG2000_PLIC_CLAIM (SG2000_PLIC_BASE + 0x201004)
#endif /* __ARCH_RISCV_SRC_SG2000_HARDWARE_SG2000_PLIC_H */

View File

@ -0,0 +1,85 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_allocateheap.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/userspace.h>
#include <nuttx/arch.h>
#include <arch/board/board_memorymap.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define KRAM_END KSRAM_END
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_allocate_heap
*
* Description:
* This function will be called to dynamically set aside the heap region.
*
* For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and
* user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the
* size of the unprotected, user-space heap.
*
* If a protected kernel-space heap is provided, the kernel heap must be
* allocated (and protected) by an analogous up_allocate_kheap().
*
* The following memory map is assumed for the flat build:
*
* .data region. Size determined at link time.
* .bss region Size determined at link time.
* IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE.
* Heap. Extends to the end of User SRAM.
*
* The following memory map is assumed for the protect build.
* The kernel and user space have it's own dedicated heap space.
*
* User .data region Size determined at link time
* User .bss region Size determined at link time
* User heap Extends to the end of User SRAM
* Kernel .data region Size determined at link time
* Kernel .bss region Size determined at link time
* Kernel IDLE thread stack Size determined by CONFIG_IDLETHREAD_STACKSIZE
* Kernel heap Size determined by CONFIG_MM_KERNEL_HEAPSIZE
*
****************************************************************************/
void up_allocate_kheap(void **heap_start, size_t *heap_size)
{
/* Return the heap settings */
*heap_start = (void *)g_idle_topstack;
*heap_size = KRAM_END - g_idle_topstack;
}

View File

@ -0,0 +1,111 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_head.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/arch.h>
#include <arch/irq.h>
#include "chip.h"
#include "riscv_internal.h"
#include "riscv_macros.S"
/****************************************************************************
* Public Symbols
****************************************************************************/
/* Exported Symbols */
.section .text
.global __start
__start:
/* DO NOT MODIFY. Image Header expected by Linux bootloaders.
*
* This `li` instruction has no meaningful effect except that
* its opcode forms the magic "MZ" signature of a PE/COFF file
* that is required for UEFI applications.
*
* Some bootloaders check the magic "MZ" to see if the image is a valid
* Linux image. But modifying the bootLoader is unnecessary unless we
* need to do a customized secure boot. So we just put "MZ" in the
* header to make the bootloader happy.
*/
c.li s4, -13 /* Magic Signature "MZ" (2 bytes) */
j real_start /* Jump to Kernel Start (2 bytes) */
.long 0 /* Executable Code padded to 8 bytes */
.quad 0x200000 /* Image load offset from start of RAM */
.quad _ebss - __start /* Effective size of kernel image */
.quad 0 /* Kernel flags, little-endian */
.long 2 /* Version of this header */
.long 0 /* Reserved */
.quad 0 /* Reserved */
.ascii "RISCV\x00\x00\x00" /* Magic number, "RISCV" (8 bytes) */
.ascii "RSC\x05" /* Magic number 2, "RSC\x05" (4 bytes) */
.long 0 /* Reserved for PE COFF offset */
real_start:
/* Load the number of CPUs that the kernel supports */
#ifdef CONFIG_SMP
li t1, CONFIG_SMP_NCPUS
#else
li t1, 1
#endif
/* If a0 (hartid) >= t1 (the number of CPUs), stop here */
blt a0, t1, 3f
csrw CSR_SIE, zero
wfi
3:
/* Set stack pointer to the idle thread stack */
riscv_set_inital_sp SG2000_IDLESTACK_BASE, SMP_STACK_SIZE, a0
/* Disable all interrupts (i.e. timer, external) in sie */
csrw CSR_SIE, zero
la t0, __trap_vec
csrw CSR_STVEC, t0
/* Jump to sg2000_start */
jal x1, sg2000_start
/* We shouldn't return from _start */
.global _init
.global _fini
_init:
_fini:
/* These don't have to do anything since we use init_array/fini_array. */
ret

View File

@ -0,0 +1,202 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_irq.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include "riscv_internal.h"
#include "riscv_ipi.h"
#include "chip.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_irqinitialize
****************************************************************************/
void up_irqinitialize(void)
{
uintptr_t claim;
/* Disable S-Mode interrupts */
up_irq_save();
/* Attach the common interrupt handler */
riscv_exception_attach();
/* Disable all global interrupts */
putreg32(0x0, SG2000_PLIC_ENABLE1);
putreg32(0x0, SG2000_PLIC_ENABLE2);
/* Clear pendings in PLIC */
claim = getreg32(SG2000_PLIC_CLAIM);
putreg32(claim, SG2000_PLIC_CLAIM);
/* Colorize the interrupt stack for debug purposes */
#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 15
size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~15);
riscv_stack_color(g_intstackalloc, intstack_size);
#endif
/* Set priority for all global interrupts to 1 (lowest) */
int id;
for (id = 1; id <= NR_IRQS; id++)
{
putreg32(1, (uintptr_t)(SG2000_PLIC_PRIORITY + 4 * id));
}
/* Set irq threshold to 0 (permits all global interrupts) */
putreg32(0, SG2000_PLIC_THRESHOLD);
#ifdef CONFIG_SMP
/* Clear IPI for CPU0 */
riscv_ipi_clear(0);
up_enable_irq(RISCV_IRQ_SOFT);
#endif
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* And finally, enable interrupts */
up_irq_enable();
#endif
}
/****************************************************************************
* Name: up_disable_irq
*
* Description:
* Disable the IRQ specified by 'irq'
*
****************************************************************************/
void up_disable_irq(int irq)
{
int extirq;
if (irq == RISCV_IRQ_SOFT)
{
/* Read sstatus & clear software interrupt enable in sie */
CLEAR_CSR(CSR_IE, IE_SIE);
}
else if (irq == RISCV_IRQ_TIMER)
{
/* Read sstatus & clear timer interrupt enable in sie */
CLEAR_CSR(CSR_IE, IE_TIE);
}
else if (irq > RISCV_IRQ_EXT)
{
extirq = irq - RISCV_IRQ_EXT;
/* Clear enable bit for the irq */
if (0 <= extirq && extirq <= 63)
{
modifyreg32(SG2000_PLIC_ENABLE1 + (4 * (extirq / 32)),
1 << (extirq % 32), 0);
}
else
{
PANIC();
}
}
}
/****************************************************************************
* Name: up_enable_irq
*
* Description:
* Enable the IRQ specified by 'irq'
*
****************************************************************************/
void up_enable_irq(int irq)
{
int extirq;
if (irq == RISCV_IRQ_SOFT)
{
/* Read sstatus & set software interrupt enable in sie */
SET_CSR(CSR_IE, IE_SIE);
}
else if (irq == RISCV_IRQ_TIMER)
{
/* Read sstatus & set timer interrupt enable in sie */
SET_CSR(CSR_IE, IE_TIE);
}
else if (irq > RISCV_IRQ_EXT)
{
extirq = irq - RISCV_IRQ_EXT;
/* Set enable bit for the irq */
if (0 <= extirq && extirq <= 63)
{
modifyreg32(SG2000_PLIC_ENABLE1 + (4 * (extirq / 32)),
0, 1 << (extirq % 32));
}
else
{
PANIC();
}
}
}
irqstate_t up_irq_enable(void)
{
irqstate_t oldstat;
/* Enable external interrupts (sie) */
SET_CSR(CSR_IE, IE_EIE);
/* Read and enable global interrupts (sie) in sstatus */
oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE);
return oldstat;
}

View File

@ -0,0 +1,84 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_irq_dispatch.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <sys/types.h>
#include "riscv_internal.h"
#include "hardware/sg2000_memorymap.h"
#include "hardware/sg2000_plic.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define RV_IRQ_MASK 59
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* riscv_dispatch_irq
****************************************************************************/
void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
{
int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf);
/* Firstly, check if the irq is machine external interrupt */
if (RISCV_IRQ_EXT == irq)
{
uintptr_t val = getreg32(SG2000_PLIC_CLAIM);
/* Add the value to nuttx irq which is offset to the mext */
irq += val;
}
/* EXT means no interrupt */
if (RISCV_IRQ_EXT != irq)
{
/* Deliver the IRQ */
regs = riscv_doirq(irq, regs);
}
if (RISCV_IRQ_EXT <= irq)
{
/* Then write PLIC_CLAIM to clear pending in PLIC */
putreg32(irq - RISCV_IRQ_EXT, SG2000_PLIC_CLAIM);
}
return regs;
}

View File

@ -0,0 +1,42 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_memorymap.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_SG2000_SG2000_MEMORYMAP_H
#define __ARCH_RISCV_SRC_SG2000_SG2000_MEMORYMAP_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "riscv_common_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Idle thread stack starts from _ebss */
#ifndef __ASSEMBLY__
#define SG2000_IDLESTACK_BASE (uintptr_t)_ebss
#else
#define SG2000_IDLESTACK_BASE _ebss
#endif
#endif /* __ARCH_RISCV_SRC_SG2000_SG2000_MEMORYMAP_H */

View File

@ -0,0 +1,324 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_mm_init.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <arch/board/board_memorymap.h>
#include "sg2000_memorymap.h"
#include "riscv_internal.h"
#include "riscv_mmu.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* T-Head C906 MMU requires Strong Order and Shareable for I/O Memory */
#define MMU_THEAD_SHAREABLE (1ul << 60)
#define MMU_THEAD_STRONG_ORDER (1ul << 63)
#define MMU_THEAD_IO_FLAGS (MMU_IO_FLAGS | MMU_THEAD_SHAREABLE | \
MMU_THEAD_STRONG_ORDER)
/* Map the I/O and PLIC Memory with vaddr = paddr mappings */
#define MMU_IO_BASE (0x00000000ul)
#define MMU_IO_SIZE (0x40000000ul)
#define MMU_INT_BASE (0x70000000ul)
#define MMU_INT_SIZE (0x10000000ul)
/* Physical and virtual addresses to page tables (vaddr = paddr mapping) */
#define PGT_L1_PBASE (uintptr_t)&m_l1_pgtable
#define PGT_L2_PBASE (uintptr_t)&m_l2_pgtable
#define PGT_L2_INT_PBASE (uintptr_t)&m_l2_int_pgtable
#define PGT_L3_PBASE (uintptr_t)&m_l3_pgtable
#define PGT_L1_VBASE PGT_L1_PBASE
#define PGT_L2_VBASE PGT_L2_PBASE
#define PGT_L2_INT_VBASE PGT_L2_INT_PBASE
#define PGT_L3_VBASE PGT_L3_PBASE
#define PGT_L1_SIZE (512) /* Enough to map 512 GiB */
#define PGT_L2_SIZE (512) /* Enough to map 1 GiB */
#define PGT_L2_INT_SIZE (512) /* Enough to map 1 GiB */
#define PGT_L3_SIZE (1024) /* Enough to map 4 MiB (2MiB x 2) */
#define SLAB_COUNT (sizeof(m_l3_pgtable) / RV_MMU_PAGE_SIZE)
#define KMM_PAGE_SIZE RV_MMU_L3_PAGE_SIZE
#define KMM_PBASE PGT_L3_PBASE
#define KMM_PBASE_IDX 3
#define KMM_SPBASE PGT_L2_PBASE
#define KMM_SPBASE_IDX 2
/****************************************************************************
* Private Types
****************************************************************************/
struct pgalloc_slab_s
{
sq_entry_t *next;
void *memory;
};
typedef struct pgalloc_slab_s pgalloc_slab_t;
/****************************************************************************
* Private Data
****************************************************************************/
/* Kernel mappings simply here, mapping is vaddr=paddr */
static size_t m_l1_pgtable[PGT_L1_SIZE] locate_data(".pgtables");
static size_t m_l2_pgtable[PGT_L2_SIZE] locate_data(".pgtables");
static size_t m_l2_int_pgtable[PGT_L2_INT_SIZE] locate_data(".pgtables");
static size_t m_l3_pgtable[PGT_L3_SIZE] locate_data(".pgtables");
/* Kernel mappings (L1 base) */
uintptr_t g_kernel_mappings = PGT_L1_VBASE;
uintptr_t g_kernel_pgt_pbase = PGT_L1_PBASE;
/* L3 page table allocator */
static sq_queue_t g_free_slabs;
static pgalloc_slab_t g_slabs[SLAB_COUNT];
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: slab_init
*
* Description:
* Initialize slab allocator for L2 or L3 page table entries.
* L2 Page table is used for SV32. L3 is used for SV39.
*
* Input Parameters:
* start - Beginning of the L2 or L3 page table pool
*
****************************************************************************/
static void slab_init(uintptr_t start)
{
int i;
sq_init(&g_free_slabs);
for (i = 0; i < SLAB_COUNT; i++)
{
g_slabs[i].memory = (void *)start;
sq_addlast((sq_entry_t *)&g_slabs[i], (sq_queue_t *)&g_free_slabs);
start += RV_MMU_PAGE_SIZE;
}
}
/****************************************************************************
* Name: slab_alloc
*
* Description:
* Allocate single slab for L2/L3 page table entry.
* L2 Page table is used for SV32. L3 is used for SV39.
*
****************************************************************************/
static uintptr_t slab_alloc(void)
{
pgalloc_slab_t *slab = (pgalloc_slab_t *)sq_remfirst(&g_free_slabs);
return slab ? (uintptr_t)slab->memory : 0;
}
/****************************************************************************
* Name: map_region
*
* Description:
* Map a region of physical memory to the L3 page table
*
* Input Parameters:
* paddr - Beginning of the physical address mapping
* vaddr - Beginning of the virtual address mapping
* size - Size of the region in bytes
* mmuflags - The MMU flags to use in the mapping
*
****************************************************************************/
static void map_region(uintptr_t paddr, uintptr_t vaddr, size_t size,
uint64_t mmuflags)
{
uintptr_t endaddr;
uintptr_t pbase;
int npages;
int i;
int j;
/* How many pages */
npages = (size + RV_MMU_PAGE_MASK) >> RV_MMU_PAGE_SHIFT;
endaddr = vaddr + size;
for (i = 0; i < npages; i += RV_MMU_PAGE_ENTRIES)
{
/* See if a mapping exists */
pbase = mmu_pte_to_paddr(mmu_ln_getentry(KMM_SPBASE_IDX,
KMM_SPBASE, vaddr));
if (!pbase)
{
/* No, allocate 1 page, this must not fail */
pbase = slab_alloc();
DEBUGASSERT(pbase);
/* Map it to the new table */
mmu_ln_setentry(KMM_SPBASE_IDX, KMM_SPBASE, pbase, vaddr,
MMU_UPGT_FLAGS);
}
/* Then add the mappings */
for (j = 0; j < RV_MMU_PAGE_ENTRIES && vaddr < endaddr; j++)
{
mmu_ln_setentry(KMM_PBASE_IDX, pbase, paddr, vaddr, mmuflags);
paddr += KMM_PAGE_SIZE;
vaddr += KMM_PAGE_SIZE;
}
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sg2000_kernel_mappings
*
* Description:
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up the kernel
* MMU mappings.
*
****************************************************************************/
void sg2000_kernel_mappings(void)
{
/* Initialize slab allocator for the L2/L3 page tables */
slab_init(KMM_PBASE);
/* Begin mapping memory to MMU; note that at this point the MMU is not yet
* active, so the page table virtual addresses are actually physical
* addresses and so forth.
*/
/* Map I/O region, use enough large page tables for the IO region. */
binfo("map I/O regions\n");
mmu_ln_map_region(1, PGT_L1_VBASE, MMU_IO_BASE, MMU_IO_BASE,
MMU_IO_SIZE, MMU_THEAD_IO_FLAGS);
/* Map the PLIC with L2 page table */
binfo("map PLIC with L2 page table\n");
mmu_ln_map_region(2, PGT_L2_INT_PBASE, MMU_INT_BASE, MMU_INT_BASE,
MMU_INT_SIZE, MMU_THEAD_IO_FLAGS);
/* Connect the L1 and PLIC L2 page tables */
binfo("connect the L1 and PLIC L2 page tables\n");
mmu_ln_setentry(1, PGT_L1_VBASE, PGT_L2_INT_PBASE, MMU_INT_BASE, PTE_G);
/* Map the kernel text and data for L2/L3 */
binfo("map kernel text\n");
map_region(KFLASH_START, KFLASH_START, KFLASH_SIZE, MMU_KTEXT_FLAGS);
binfo("map kernel data\n");
map_region(KSRAM_START, KSRAM_START, KSRAM_SIZE, MMU_KDATA_FLAGS);
/* Connect the L1 and L2 page tables for the kernel text and data */
binfo("connect the L1 and L2 page tables\n");
mmu_ln_setentry(1, PGT_L1_VBASE, PGT_L2_PBASE, KFLASH_START, PTE_G);
/* Map the page pool */
binfo("map the page pool\n");
mmu_ln_map_region(2, PGT_L2_VBASE, PGPOOL_START, PGPOOL_START, PGPOOL_SIZE,
MMU_KDATA_FLAGS);
}
/****************************************************************************
* Name: sg2000_mm_init
*
* Description:
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up kernel MMU
* mappings. Function also sets the first address environment (satp value).
*
****************************************************************************/
void sg2000_mm_init(void)
{
/* Setup the kernel mappings */
sg2000_kernel_mappings();
/* Enable MMU */
binfo("mmu_enable: satp=%" PRIuPTR "\n", g_kernel_pgt_pbase);
mmu_enable(g_kernel_pgt_pbase, 0);
}
/****************************************************************************
* Name: mmu_flush_cache
*
* Description:
* Flush the MMU Cache for T-Head C906. Called by mmu_write_satp() after
* updating the MMU SATP Register, when swapping MMU Page Tables.
* This operation executes RISC-V Instructions that are specific to
* T-Head C906.
*
****************************************************************************/
void weak_function mmu_flush_cache(uintptr_t reg)
{
UNUSED(reg);
__asm__ __volatile__
(
/* DCACHE.IALL: Invalidate all Page Table Entries in the D-Cache */
".long 0x0020000b\n"
/* SYNC.S: Ensure that all Cache Operations are completed */
".long 0x0190000b\n"
);
}

View File

@ -0,0 +1,58 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_mm_init.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISC_V_SRC_SG2000_SG2000_MM_INIT_H
#define __ARCH_RISC_V_SRC_SG2000_SG2000_MM_INIT_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "riscv_mmu.h"
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/
/****************************************************************************
* Name: sg2000_kernel_mappings
*
* Description:
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up the kernel
* MMU mappings.
*
****************************************************************************/
void sg2000_kernel_mappings(void);
/****************************************************************************
* Name: sg2000_mm_init
*
* Description:
* Setup kernel mappings when using CONFIG_BUILD_KERNEL. Sets up kernel MMU
* mappings. Function also sets the first address environment (satp value).
*
****************************************************************************/
void sg2000_mm_init(void);
#endif /* __ARCH_RISC_V_SRC_SG2000_SG2000_MM_INIT_H */

View File

@ -0,0 +1,53 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_pgalloc.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/arch.h>
#include <nuttx/config.h>
#include <nuttx/pgalloc.h>
#include <assert.h>
#include <debug.h>
#include <arch/board/board_memorymap.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_allocate_pgheap
*
* Description:
* If there is a page allocator in the configuration, then this function
* must be provided by the platform-specific code. The OS initialization
* logic will call this function early in the initialization sequence to
* get the page heap information needed to configure the page allocator.
*
****************************************************************************/
void up_allocate_pgheap(void **heap_start, size_t *heap_size)
{
DEBUGASSERT(heap_start && heap_size);
*heap_start = (void *)PGPOOL_START;
*heap_size = (size_t)PGPOOL_SIZE;
}

View File

@ -0,0 +1,320 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_start.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/init.h>
#include <nuttx/arch.h>
#include <nuttx/serial/uart_16550.h>
#include <debug.h>
#include <arch/board/board.h>
#include <arch/board/board_memorymap.h>
#include "riscv_internal.h"
#include "chip.h"
#include "sg2000_mm_init.h"
#include "sg2000_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_DEBUG_FEATURES
#define showprogress(c) up_putc(c)
#else
#define showprogress(c)
#endif
/****************************************************************************
* Extern Function Declarations
****************************************************************************/
extern void __trap_vec(void);
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: sg2000_copy_overlap
*
* Description:
* Copy an overlapping memory region. dest overlaps with src + count.
*
* Input Parameters:
* dest - Destination address
* src - Source address
* count - Number of bytes to copy
*
****************************************************************************/
static void sg2000_copy_overlap(uint8_t *dest, const uint8_t *src,
size_t count)
{
uint8_t *d = dest + count - 1;
const uint8_t *s = src + count - 1;
if (dest <= src)
{
_err("dest and src should overlap");
PANIC();
}
while (count--)
{
volatile uint8_t c = *s; /* Prevent compiler optimization */
*d = c;
d--;
s--;
}
}
/****************************************************************************
* Name: sg2000_copy_ramdisk
*
* Description:
* Copy the RAM Disk from NuttX Image to RAM Disk Region.
*
****************************************************************************/
static void sg2000_copy_ramdisk(void)
{
const char *header = "-rom1fs-";
const uint8_t *limit = (uint8_t *)g_idle_topstack + (256 * 1024);
uint8_t *ramdisk_addr = NULL;
uint8_t *addr;
uint32_t size;
/* After _edata, search for "-rom1fs-". This is the RAM Disk Address.
* Limit search to 256 KB after Idle Stack Top.
*/
binfo("_edata=%p, _sbss=%p, _ebss=%p, idlestack_top=%p\n",
(void *)_edata, (void *)_sbss, (void *)_ebss,
(void *)g_idle_topstack);
for (addr = _edata; addr < limit; addr++)
{
if (memcmp(addr, header, strlen(header)) == 0)
{
ramdisk_addr = addr;
break;
}
}
/* Stop if RAM Disk is missing */
binfo("ramdisk_addr=%p\n", ramdisk_addr);
if (ramdisk_addr == NULL)
{
_err("Missing RAM Disk. Check the initrd padding.");
PANIC();
}
/* RAM Disk must be after Idle Stack, to prevent overwriting */
if (ramdisk_addr <= (uint8_t *)g_idle_topstack)
{
const size_t pad = (size_t)g_idle_topstack - (size_t)ramdisk_addr;
_err("RAM Disk must be after Idle Stack. Increase initrd padding "
"by %ul bytes.", pad);
PANIC();
}
/* Read the Filesystem Size from the next 4 bytes (Big Endian) */
size = (ramdisk_addr[8] << 24) + (ramdisk_addr[9] << 16) +
(ramdisk_addr[10] << 8) + ramdisk_addr[11] + 0x1f0;
binfo("size=%d\n", size);
/* Filesystem Size must be less than RAM Disk Memory Region */
if (size > (size_t)__ramdisk_size)
{
_err("RAM Disk Region too small. Increase by %ul bytes.\n",
size - (size_t)__ramdisk_size);
PANIC();
}
/* Copy the RAM Disk from NuttX Image to RAM Disk Region.
* __ramdisk_start overlaps with ramdisk_addr + size.
*/
sg2000_copy_overlap(__ramdisk_start, ramdisk_addr, size);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sg2000_clear_bss
*
* Description:
* Clear .bss. We'll do this inline (vs. calling memset) just to be
* certain that there are no issues with the state of global variables.
*
****************************************************************************/
void sg2000_clear_bss(void)
{
uint32_t *dest;
for (dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; )
{
*dest++ = 0;
}
}
/****************************************************************************
* Name: sg2000_start_s
*
* Description:
* Start the NuttX Kernel. Assume that we are in RISC-V Supervisor Mode.
*
* Input Parameters:
* mhartid - Hart ID
*
****************************************************************************/
void sg2000_start_s(int mhartid)
{
/* Configure FPU */
riscv_fpuconfig();
if (mhartid > 0)
{
goto cpux;
}
showprogress('A');
#ifdef USE_EARLYSERIALINIT
riscv_earlyserialinit();
#endif
showprogress('B');
/* Do board initialization */
showprogress('C');
/* Setup page tables for kernel and enable MMU */
sg2000_mm_init();
/* Call nx_start() */
nx_start();
cpux:
#ifdef CONFIG_SMP
riscv_cpu_boot(mhartid);
#endif
while (true)
{
asm("WFI");
}
}
/****************************************************************************
* Name: sg2000_start
*
* Description:
* Start the NuttX Kernel. Called by Boot Code.
*
* Input Parameters:
* mhartid - Hart ID
*
****************************************************************************/
void sg2000_start(int mhartid)
{
DEBUGASSERT(mhartid == 0); /* Only Hart 0 supported for now */
if (0 == mhartid)
{
/* Clear the BSS */
sg2000_clear_bss();
/* Copy the RAM Disk */
sg2000_copy_ramdisk();
/* Initialize the per CPU areas */
riscv_percpu_add_hart(mhartid);
}
/* Disable MMU */
WRITE_CSR(CSR_SATP, 0x0);
/* Set the trap vector for S-mode */
WRITE_CSR(CSR_STVEC, (uintptr_t)__trap_vec);
/* Start S-mode */
sg2000_start_s(mhartid);
}
/****************************************************************************
* Name: riscv_earlyserialinit
*
* Description:
* Performs the low level UART initialization early in debug so that the
* serial console will be available during bootup. This must be called
* before riscv_serialinit. NOTE: This function depends on GPIO pin
* configuration performed in up_consoleinit() and main clock
* initialization performed in up_clkinitialize().
*
****************************************************************************/
void riscv_earlyserialinit(void)
{
u16550_earlyserialinit();
}
/****************************************************************************
* Name: riscv_serialinit
*
* Description:
* Register serial console and serial ports. This assumes
* that riscv_earlyserialinit was called previously.
*
****************************************************************************/
void riscv_serialinit(void)
{
u16550_serialinit();
}

View File

@ -0,0 +1,69 @@
/****************************************************************************
* arch/risc-v/src/sg2000/sg2000_timerisr.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <stdint.h>
#include <time.h>
#include <debug.h>
#include <nuttx/timers/arch_alarm.h>
#include "riscv_internal.h"
#include "riscv_mtimer.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MTIMER_FREQ 1000000
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_timer_initialize
*
* Description:
* This function is called during start-up to initialize
* the timer interrupt.
*
****************************************************************************/
void up_timer_initialize(void)
{
struct oneshot_lowerhalf_s *lower;
/* Initialize the OpenSBI Timer. mtime and mtimecmp are unused for
* OpenSBI.
*/
lower = riscv_mtimer_initialize(0, 0, RISCV_IRQ_STIMER, MTIMER_FREQ);
DEBUGASSERT(lower != NULL);
up_alarm_set_lowerhalf(lower);
}