[rtems commit] bsp/qoriq: Add decrementer clock driver

Sebastian Huber sebh at rtems.org
Tue Sep 19 12:36:21 UTC 2017


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Sep 19 09:12:02 2017 +0200

bsp/qoriq: Add decrementer clock driver

Update #3085.

---

 .../lib/libbsp/powerpc/qoriq/clock/clock-config.c  | 51 +++++++++++++++++++---
 c/src/lib/libbsp/powerpc/qoriq/include/bsp.h       |  6 +++
 c/src/lib/libbsp/powerpc/qoriq/irq/irq.c           |  5 +++
 c/src/lib/libbsp/powerpc/qoriq/start/start.S       |  8 ++++
 c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c  |  7 ++-
 5 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
index ca61d25..82d8b8c 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
@@ -7,7 +7,7 @@
  */
 
 /*
- * Copyright (c) 2011, 2016 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2011, 2017 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -31,6 +31,45 @@
 /* This is defined in clockdrv_shell.h */
 static rtems_isr Clock_isr(void *arg);
 
+static struct timecounter qoriq_clock_tc;
+
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+
+#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR
+
+void qoriq_decrementer_dispatch(void)
+{
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_TSR, BOOKE_TSR_DIS);
+  Clock_isr(NULL);
+}
+
+static uint32_t qoriq_clock_get_timecount(struct timecounter *tc)
+{
+  return ppc_alternate_time_base();
+}
+
+static void qoriq_clock_initialize(void)
+{
+  uint64_t frequency = bsp_time_base_frequency;
+  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
+
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_DECAR, interval - 1);
+  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(
+    BOOKE_TCR,
+    BOOKE_TCR_DIE | BOOKE_TCR_ARE
+  );
+  ppc_set_decrementer_register(interval - 1);
+
+  qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount;
+  qoriq_clock_tc.tc_counter_mask = 0xffffffff;
+  qoriq_clock_tc.tc_frequency = qoriq_clock_frequency;
+  qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&qoriq_clock_tc);
+}
+
+#else /* !QORIQ_IS_HYPERVISOR_GUEST */
+
 static volatile qoriq_pic_global_timer *const qoriq_clock =
   #if QORIQ_CLOCK_TIMER < 4
     &qoriq.pic.gta [QORIQ_CLOCK_TIMER];
@@ -47,8 +86,6 @@ static volatile qoriq_pic_global_timer *const qoriq_timecounter =
 
 #define CLOCK_INTERRUPT (QORIQ_IRQ_GT_BASE + QORIQ_CLOCK_TIMER)
 
-static struct timecounter qoriq_clock_tc;
-
 static void qoriq_clock_handler_install(void)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
@@ -123,9 +160,6 @@ static void qoriq_clock_cleanup(void)
   }
 }
 
-#define Clock_driver_support_initialize_hardware() \
-  qoriq_clock_initialize()
-
 #define Clock_driver_support_install_isr(clock_isr) \
   qoriq_clock_handler_install()
 
@@ -135,5 +169,10 @@ static void qoriq_clock_cleanup(void)
 #define Clock_driver_support_shutdown_hardware() \
   qoriq_clock_cleanup()
 
+#endif /* QORIQ_IS_HYPERVISOR_GUEST */
+
+#define Clock_driver_support_initialize_hardware() \
+  qoriq_clock_initialize()
+
 /* Include shared source clock driver code */
 #include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h b/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h
index 0497905..d7e9e95 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h
@@ -113,6 +113,12 @@ void qoriq_restart_secondary_processor(
 
 void qoriq_initialize_exceptions(void *interrupt_stack_begin);
 
+void qoriq_decrementer_dispatch(void);
+
+extern uint32_t bsp_time_base_frequency;
+
+extern uint32_t qoriq_clock_frequency;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c
index 39031c2..92d918f 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c
@@ -89,6 +89,11 @@ void bsp_interrupt_dispatch(uintptr_t exception_number)
 {
 	unsigned int vector;
 
+	if (exception_number == 10) {
+		qoriq_decrementer_dispatch();
+		return;
+	}
+
 	ev_int_iack(0, &vector);
 
 	if (vector != SPURIOUS) {
diff --git a/c/src/lib/libbsp/powerpc/qoriq/start/start.S b/c/src/lib/libbsp/powerpc/qoriq/start/start.S
index 11c326d..100173c 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/start/start.S
+++ b/c/src/lib/libbsp/powerpc/qoriq/start/start.S
@@ -425,10 +425,18 @@ bsp_exc_vector_base:
 	START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
 #endif
 	/* Decrementer */
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+	PPC_REG_STORE_UPDATE	r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
+#else
 	PPC_REG_STORE_UPDATE	r1, -EXC_GENERIC_SIZE(r1)
+#endif
 	PPC_REG_STORE	r3, GPR3_OFFSET(r1)
 	li	r3, 10
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+	b	ppc_exc_interrupt
+#else
 	b	ppc_exc_fatal_normal
+#endif
 	START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
 	/* Fixed-interval timer interrupt */
 	PPC_REG_STORE_UPDATE	r1, -EXC_GENERIC_SIZE(r1)
diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c
index 22eb678..72746ba 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c
@@ -48,7 +48,9 @@ qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT];
 unsigned int BSP_bus_frequency;
 
 /* Configuration parameter for clock driver, ... */
-uint32_t bsp_clicks_per_usec;
+uint32_t bsp_time_base_frequency;
+
+uint32_t qoriq_clock_frequency;
 
 void BSP_panic(char *s)
 {
@@ -97,13 +99,14 @@ static void initialize_frequency_parameters(void)
   if (val_fdt == NULL || len != 4) {
     bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY);
   }
-  bsp_clicks_per_usec = fdt32_to_cpu(*val_fdt) / 1000000;
+  bsp_time_base_frequency = fdt32_to_cpu(*val_fdt);
 
   #ifdef __PPC_CPU_E6500__
     val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len);
     if (val_fdt == NULL || len != 4) {
       bsp_fatal(QORIQ_FATAL_FDT_NO_CLOCK_FREQUENCY);
     }
+    qoriq_clock_frequency = fdt32_to_cpu(*val_fdt);
   #endif
   rtems_counter_initialize_converter(fdt32_to_cpu(*val_fdt));
 }



More information about the vc mailing list