[rtems commit] bsp/riscv: Add and use riscv_fdt_get_address()

Sebastian Huber sebh at rtems.org
Wed Jul 25 08:11:10 UTC 2018


Module:    rtems
Branch:    master
Commit:    3a263a9b02227ebb056eef7bcbbc378cacbd476e
Changeset: http://git.rtems.org/rtems/commit/?id=3a263a9b02227ebb056eef7bcbbc378cacbd476e

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Jul 19 14:38:44 2018 +0200

bsp/riscv: Add and use riscv_fdt_get_address()

Update #3433.

---

 bsps/include/bsp/fatal.h                  |  3 +-
 bsps/riscv/riscv/clock/clockdrv.c         | 46 +++++++++++++++++++++----------
 bsps/riscv/riscv/console/console-config.c | 12 ++------
 bsps/riscv/riscv/include/bsp/riscv.h      |  2 ++
 bsps/riscv/riscv/start/bspstart.c         | 43 +++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+), 25 deletions(-)

diff --git a/bsps/include/bsp/fatal.h b/bsps/include/bsp/fatal.h
index 92ab55f..71edcb0 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 52fb441..1420e31 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 50d292d..270646f 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 b2b9d24..b85b250 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 217e6f2..6b57977 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)
 {




More information about the vc mailing list