summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-07-19 14:38:44 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-07-25 10:07:43 +0200
commit3a263a9b02227ebb056eef7bcbbc378cacbd476e (patch)
tree385585033875178d8e0ce88362036e7edcc26f59
parentbsp/riscv: Disable HTIF support by default (diff)
downloadrtems-3a263a9b02227ebb056eef7bcbbc378cacbd476e.tar.bz2
bsp/riscv: Add and use riscv_fdt_get_address()
Update #3433.
-rw-r--r--bsps/include/bsp/fatal.h3
-rw-r--r--bsps/riscv/riscv/clock/clockdrv.c46
-rw-r--r--bsps/riscv/riscv/console/console-config.c12
-rw-r--r--bsps/riscv/riscv/include/bsp/riscv.h2
-rw-r--r--bsps/riscv/riscv/start/bspstart.c43
5 files changed, 81 insertions, 25 deletions
diff --git a/bsps/include/bsp/fatal.h b/bsps/include/bsp/fatal.h
index 92ab55fbb4..71edcb0afc 100644
--- a/bsps/include/bsp/fatal.h
+++ b/bsps/include/bsp/fatal.h
@@ -144,7 +144,8 @@ typedef enum {
RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE,
RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE,
RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION,
- RISCV_FATAL_CLOCK_IRQ_INSTALL
+ RISCV_FATAL_CLOCK_IRQ_INSTALL,
+ RISCV_FATAL_NO_CLINT_REG_IN_DEVICE_TREE
} bsp_fatal_code;
RTEMS_NO_RETURN static inline void
diff --git a/bsps/riscv/riscv/clock/clockdrv.c b/bsps/riscv/riscv/clock/clockdrv.c
index 52fb441ce1..1420e312a4 100644
--- a/bsps/riscv/riscv/clock/clockdrv.c
+++ b/bsps/riscv/riscv/clock/clockdrv.c
@@ -35,30 +35,33 @@
#include <rtems/timecounter.h>
#include <rtems/score/riscv-utility.h>
-#include <bsp.h>
#include <bsp/fatal.h>
#include <bsp/fdt.h>
#include <bsp/irq.h>
+#include <bsp/riscv.h>
#include <dev/irq/clint.h>
#include <libfdt.h>
-#define CLINT ((volatile clint_regs *) 0x02000000)
-
/* This is defined in dev/clock/clockimpl.h */
void Clock_isr(void *arg);
-static struct timecounter riscv_clock_tc;
+typedef struct {
+ struct timecounter base;
+ volatile clint_regs *clint;
+} riscv_timecounter;
+
+static riscv_timecounter riscv_clock_tc;
static uint32_t riscv_clock_interval;
-static void riscv_clock_at_tick(void)
+static void riscv_clock_at_tick(riscv_timecounter *tc)
{
volatile clint_regs *clint;
uint64_t cmp;
- clint = CLINT;
+ clint = tc->clint;
cmp = clint->mtimecmp[0].val_64;
cmp += riscv_clock_interval;
@@ -88,11 +91,13 @@ static void riscv_clock_handler_install(void)
}
}
-static uint32_t riscv_clock_get_timecount(struct timecounter *tc)
+static uint32_t riscv_clock_get_timecount(struct timecounter *base)
{
+ riscv_timecounter *tc;
volatile clint_regs *clint;
- clint = CLINT;
+ tc = (riscv_timecounter *) base;
+ clint = tc->clint;
return clint->mtime.val_32[0];
}
@@ -114,25 +119,36 @@ static uint32_t riscv_clock_get_timebase_frequency(const void *fdt)
static void riscv_clock_initialize(void)
{
const char *fdt;
+ riscv_timecounter *tc;
+ int node;
uint32_t tb_freq;
uint64_t us_per_tick;
fdt = bsp_fdt_get();
+ tc = &riscv_clock_tc;
+
+ node = fdt_node_offset_by_compatible(fdt, -1, "riscv,clint0");
+ tc->clint = riscv_fdt_get_address(fdt, node);
+
+ if (tc->clint == NULL) {
+ bsp_fatal(RISCV_FATAL_NO_CLINT_REG_IN_DEVICE_TREE);
+ }
+
tb_freq = riscv_clock_get_timebase_frequency(fdt);
us_per_tick = rtems_configuration_get_microseconds_per_tick();
riscv_clock_interval = (uint32_t) ((tb_freq * us_per_tick) / 1000000);
- riscv_clock_at_tick();
+ riscv_clock_at_tick(tc);
/* Enable mtimer interrupts */
set_csr(mie, MIP_MTIP);
/* Initialize timecounter */
- riscv_clock_tc.tc_get_timecount = riscv_clock_get_timecount;
- riscv_clock_tc.tc_counter_mask = 0xffffffff;
- riscv_clock_tc.tc_frequency = tb_freq;
- riscv_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
- rtems_timecounter_install(&riscv_clock_tc);
+ tc->base.tc_get_timecount = riscv_clock_get_timecount;
+ tc->base.tc_counter_mask = 0xffffffff;
+ tc->base.tc_frequency = tb_freq;
+ tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&tc->base);
}
uint32_t _CPU_Counter_frequency( void )
@@ -140,7 +156,7 @@ uint32_t _CPU_Counter_frequency( void )
return riscv_clock_get_timebase_frequency(bsp_fdt_get());
}
-#define Clock_driver_support_at_tick() riscv_clock_at_tick()
+#define Clock_driver_support_at_tick() riscv_clock_at_tick(&riscv_clock_tc)
#define Clock_driver_support_initialize_hardware() riscv_clock_initialize()
diff --git a/bsps/riscv/riscv/console/console-config.c b/bsps/riscv/riscv/console/console-config.c
index 50d292dcb8..270646ffe1 100644
--- a/bsps/riscv/riscv/console/console-config.c
+++ b/bsps/riscv/riscv/console/console-config.c
@@ -17,10 +17,10 @@
#include <rtems/sysinit.h>
#include <rtems/termiostypes.h>
-#include <bsp.h>
#include <bsp/fatal.h>
#include <bsp/fdt.h>
#include <bsp/irq.h>
+#include <bsp/riscv.h>
#include <dev/serial/htif.h>
#include <libchip/ns16550.h>
@@ -119,18 +119,12 @@ static void riscv_console_probe(void)
ctx->set_reg = set_register;
ctx->initial_baud = BSP_CONSOLE_BAUD;
- val = (fdt32_t *) fdt_getprop(fdt, node, "reg", &len);
+ ctx->port = (uintptr_t) riscv_fdt_get_address(fdt, node);
- if (val == NULL || (len != 8 && len != 16)) {
+ if (ctx->port == 0) {
bsp_fatal(RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE);
}
- if (len == 16) {
- ctx->port = fdt32_to_cpu(val[1]);
- } else {
- ctx->port = fdt32_to_cpu(val[0]);
- }
-
val = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len);
if (val == NULL || len != 4) {
diff --git a/bsps/riscv/riscv/include/bsp/riscv.h b/bsps/riscv/riscv/include/bsp/riscv.h
index b2b9d2400a..b85b250526 100644
--- a/bsps/riscv/riscv/include/bsp/riscv.h
+++ b/bsps/riscv/riscv/include/bsp/riscv.h
@@ -32,6 +32,8 @@
extern "C" {
#endif
+void *riscv_fdt_get_address(const void *fdt, int node);
+
#if RISCV_ENABLE_HTIF_SUPPORT != 0
void htif_poweroff(void);
#endif
diff --git a/bsps/riscv/riscv/start/bspstart.c b/bsps/riscv/riscv/start/bspstart.c
index 217e6f23a6..6b5797786a 100644
--- a/bsps/riscv/riscv/start/bspstart.c
+++ b/bsps/riscv/riscv/start/bspstart.c
@@ -25,6 +25,49 @@
#include <bsp/bootcard.h>
#include <bsp/irq-generic.h>
+#include <bsp/riscv.h>
+
+#include <libfdt.h>
+
+void *riscv_fdt_get_address(const void *fdt, int node)
+{
+ int parent;
+ int ac;
+ int len;
+ const uint32_t *reg;
+ uint64_t addr;
+
+ parent = fdt_parent_offset(fdt, node);
+ if (parent < 0) {
+ return NULL;
+ }
+
+ ac = fdt_address_cells(fdt, parent);
+ if (ac != 1 && ac != 2) {
+ return NULL;
+ }
+
+ reg = fdt_getprop(fdt, node, "reg", &len);
+ if (reg == NULL || len < ac) {
+ return NULL;
+ }
+
+ addr = 0;
+
+ while (ac > 0) {
+ addr = (addr << 32) | fdt32_to_cpu(*reg);
+ ++reg;
+ --ac;
+ }
+
+#if __riscv_xlen < 64
+ if (addr > 0xffffffff) {
+ return NULL;
+ }
+#endif
+
+ return (void *)(uintptr_t) addr;
+}
void bsp_start(void)
{