riscv: Add CLINT and PLIC support

The CLINT and PLIC need some per-processor state.

Update #3433.
This commit is contained in:
Sebastian Huber
2018-07-20 10:57:59 +02:00
parent c2670deb49
commit 6b9ef097c3
4 changed files with 49 additions and 67 deletions

View File

@@ -33,6 +33,7 @@
*/
#include <rtems/timecounter.h>
#include <rtems/score/cpuimpl.h>
#include <rtems/score/riscv-utility.h>
#include <bsp/fatal.h>
@@ -40,8 +41,6 @@
#include <bsp/irq.h>
#include <bsp/riscv.h>
#include <dev/irq/clint.h>
#include <libfdt.h>
/* This is defined in dev/clock/clockimpl.h */
@@ -49,7 +48,7 @@ void Clock_isr(void *arg);
typedef struct {
struct timecounter base;
volatile clint_regs *clint;
volatile RISCV_CLINT_regs *clint;
} riscv_timecounter;
static riscv_timecounter riscv_clock_tc;
@@ -58,7 +57,7 @@ static uint32_t riscv_clock_interval;
static void riscv_clock_at_tick(riscv_timecounter *tc)
{
volatile clint_regs *clint;
volatile RISCV_CLINT_regs *clint;
uint64_t cmp;
clint = tc->clint;
@@ -94,7 +93,7 @@ static void riscv_clock_handler_install(void)
static uint32_t riscv_clock_get_timecount(struct timecounter *base)
{
riscv_timecounter *tc;
volatile clint_regs *clint;
volatile RISCV_CLINT_regs *clint;
tc = (riscv_timecounter *) base;
clint = tc->clint;

View File

@@ -10,10 +10,6 @@ include_bsp_HEADERS =
include_bsp_HEADERS += ../../../../../../bsps/riscv/riscv/include/bsp/irq.h
include_bsp_HEADERS += ../../../../../../bsps/riscv/riscv/include/bsp/riscv.h
include_dev_irqdir = $(includedir)/dev/irq
include_dev_irq_HEADERS =
include_dev_irq_HEADERS += ../../../../../../bsps/riscv/riscv/include/dev/irq/clint.h
include_dev_serialdir = $(includedir)/dev/serial
include_dev_serial_HEADERS =
include_dev_serial_HEADERS += ../../../../../../bsps/riscv/riscv/include/dev/serial/htif.h

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2018 embedded brains GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdint.h>
#ifndef DEV_IRQ_CLINT_H
#define DEV_IRQ_CLINT_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct {
uint32_t msip[4096];
union {
uint64_t val_64;
uint32_t val_32[2];
} mtimecmp[2048];
uint32_t reserved_8000[4094];
union {
uint64_t val_64;
uint32_t val_32[2];
} mtime;
uint32_t reserved_c000[4096];
} clint_regs;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DEV_IRQ_CLINT_H */

View File

@@ -34,10 +34,14 @@
#include <rtems/score/cpu.h>
#ifdef __riscv_atomic
#if defined(__riscv_atomic) && __riscv_xlen == 64
#define CPU_PER_CPU_CONTROL_SIZE 48
#elif defined(__riscv_atomic) && __riscv_xlen == 32
#define CPU_PER_CPU_CONTROL_SIZE 32
#elif __riscv_xlen == 64
#define CPU_PER_CPU_CONTROL_SIZE 32
#elif __riscv_xlen == 32
#define CPU_PER_CPU_CONTROL_SIZE 16
#else
#define CPU_PER_CPU_CONTROL_SIZE 0
#endif
#ifdef RTEMS_SMP
@@ -282,12 +286,48 @@
extern "C" {
#endif
#ifdef __riscv_atomic
/* Core Local Interruptor (CLINT) */
typedef union {
uint64_t val_64;
uint32_t val_32[2];
} RISCV_CLINT_timer_reg;
typedef struct {
uint32_t msip[4096];
RISCV_CLINT_timer_reg mtimecmp[2048];
uint32_t reserved_8000[4094];
RISCV_CLINT_timer_reg mtime;
uint32_t reserved_c000[4096];
} RISCV_CLINT_regs;
/* Platform-Level Interrupt Controller (PLIC) */
#define RISCV_PLIC_MAX_INTERRUPTS 1024
typedef struct {
uint32_t priority_threshold;
uint32_t claim_complete;
uint32_t reserved_8[1022];
} RISCV_PLIC_hart_regs;
typedef struct {
uint32_t priority[RISCV_PLIC_MAX_INTERRUPTS];
uint32_t pending[1024];
uint32_t enable[16320][32];
RISCV_PLIC_hart_regs harts[CPU_MAXIMUM_PROCESSORS];
} RISCV_PLIC_regs;
typedef struct {
#ifdef __riscv_atomic
uint64_t clear_reservations;
uint32_t reserved_for_alignment_of_interrupt_frame[ 2 ];
} CPU_Per_CPU_control;
#endif
volatile RISCV_PLIC_hart_regs *plic_hart_regs;
volatile uint32_t *plic_m_ie;
volatile RISCV_CLINT_timer_reg *clint_mtimecmp;
volatile uint32_t *clint_msip;
} CPU_Per_CPU_control;
struct Per_CPU_Control;