ARMv8: move timer related code to timers.h
authorReto Achermann <reto.achermann@inf.ethz.ch>
Tue, 14 Mar 2017 15:01:56 +0000 (16:01 +0100)
committerReto Achermann <reto.achermann@inf.ethz.ch>
Tue, 14 Mar 2017 15:01:56 +0000 (16:01 +0100)
Signed-off-by: Reto Achermann <reto.achermann@inf.ethz.ch>

kernel/arch/armv8/exn.c
kernel/arch/armv8/timers.c
kernel/include/arch/armv8/platform.h
kernel/include/arch/armv8/timers.h [new file with mode: 0644]

index a60e413..72c0aa6 100644 (file)
@@ -18,6 +18,7 @@
 #include <misc.h>
 #include <stdio.h>
 #include <wakeup.h>
+#include <timers.h>
 #include <irq.h>
 #include <arch/armv8/gic_v3.h>
 #include <dev/armv8_dev.h>
@@ -216,7 +217,7 @@ void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
 
     irq = gicv3_get_active_irq();
 
-    printk(LOG_NOTE, "handle_irq IRQ %"PRIu32"\n", irq);
+   // printk(LOG_NOTE, "handle_irq IRQ %"PRIu32"\n", irq);
 
     debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
           dcb_current ? (dcb_current->disabled ? "disabled": "enabled") :
@@ -254,8 +255,9 @@ void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
 #endif
     if(irq == 30)
     {
-       gicv3_ack_irq(irq);
-       dispatch(schedule());
+        gicv3_ack_irq(irq);
+        timer_reset(kernel_timeslice);
+        dispatch(schedule());
     }
     else {
         gicv3_ack_irq(irq);
index b9fa294..79582c0 100644 (file)
@@ -19,6 +19,9 @@
 #include <sysreg.h>
 #include <arch/arm/gic.h>
 #include <systime.h>
+#include <timers.h>
+
+cycles_t ticks_per_ms = 1;
 
 /*
  * Timers
@@ -27,50 +30,43 @@ void timers_init(int timeslice)
 {
     printk(LOG_NOTE, "isr_el1=%p\n", sysreg_read_isr_el1());
     {
-        uint32_t CNTKCTL_EL1 = sysreg_read_cntkctl_el1();
-        CNTKCTL_EL1 |= (0 << 9); // Trap access to CNTP_* to EL1
-        CNTKCTL_EL1 |= (0 << 8); // Dont trap access to CNTV_* to EL1
-        CNTKCTL_EL1 |= (1 << 1); // Dont trap access to CNTFRQ* to EL1
-        CNTKCTL_EL1 |= (1 << 0); // Dont trap access to CNTFRQ* to EL1
-        sysreg_write_cntkctl_el1(CNTKCTL_EL1);
-    }
+        armv8_generic_timer_kernel_ctrl_el1_t kctl;
+        kctl = armv8_generic_timer_kernel_ctrl_el1_rd(NULL);
 
-    {
-        uint32_t cntp_ctl_el0 = sysreg_read_cntp_ctl_el0();
+        /* don't trap access to CNTFRQ* and CNTFRQ* registers from EL0 to EL1 */
+        kctl = armv8_generic_timer_kernel_ctrl_el1_EL0PCTEN_insert(kctl, 0x1);
+        kctl = armv8_generic_timer_kernel_ctrl_el1_EL0VCTEN_insert(kctl, 0x1);
 
-        // Enable the timer
-        cntp_ctl_el0 |= (1 << 0);
+        /* trap access to CNTP_* and CNTV_* registers from EL0 to EL1 */
+        kctl = armv8_generic_timer_kernel_ctrl_el1_EL0PTEN_insert(kctl, 0x0);
+        kctl = armv8_generic_timer_kernel_ctrl_el1_EL0VTEN_insert(kctl, 0x0);
 
-        sysreg_write_cntp_ctl_el0(cntp_ctl_el0);
+        armv8_generic_timer_kernel_ctrl_el1_wr(NULL, kctl);
     }
 
-    {
-        uint64_t CNTP_CVAL_EL0 = (uint64_t) 0xffffffff | (uint64_t) 0xffffffff << 32;
-        sysreg_write_cntp_cval_el0(CNTP_CVAL_EL0);
-    }
+    /* enable the timer */
+    armv8_generic_timer_ctrl_el0_ENABLE_wrf(NULL, 0x1);
+
+    /* set the compare value */
+    armv8_generic_timer_compare_val_el0_wr(NULL, 0xffffffffffffffff);
 
-    systime_frequency = timestamp_freq();
+
+    systime_frequency = timer_get_frequency() / 1000;
     /* The timeslice is in ms, so divide by 1000. */
     kernel_timeslice = ns_to_systime(timeslice * 1000000);
 
-    printf("System counter frequency is %uHz.\n", timestamp_freq());
+    printf("System counter frequency is %uHz.\n", timer_get_frequency());
     printf("Timeslice interrupt every %u ticks (%dms).\n",
             kernel_timeslice, timeslice);
 
-    {
-        // Wait for n time units, close to cycles
-        sysreg_write_cntp_tval_el0(100);
-        uint32_t cntp_ctl_el0;
-        do {
-            cntp_ctl_el0 = sysreg_read_cntp_ctl_el0();
-        } while ((cntp_ctl_el0 & 4) == 0);
+    // Wait for n time units, close to cycles
+    armv8_generic_timer_timer_val_el0_wr(NULL, 100);
 
-    }
+    while(timer_is_set())
+        ;
+
+    armv8_generic_timer_timer_val_el0_wr(NULL, kernel_timeslice);
 
-    {
-        uint32_t cntp_tval_el0 = timeslice * timestamp_freq() / 1000 ;
-        sysreg_write_cntp_tval_el0(cntp_tval_el0);
-    }
 
     uint32_t PMCR_EL0  = 0;
 
@@ -96,30 +92,17 @@ void timers_init(int timeslice)
     __asm volatile("msr PMUSERENR_EL0, %[PMUSERENR_EL0]" : : [PMUSERENR_EL0] "r" (PMUSERENR_EL0));
 }
 
-uint64_t timestamp_read(void)
-{
-    return sysreg_read_cntpct_el0();
-}
-
-uint32_t timestamp_freq(void)
-{
-    return sysreg_read_cntfrq_el0();
-}
-
-bool timer_interrupt(uint32_t irq)
+/**
+ *
+ * @param ms
+ */
+void timer_reset(uint64_t ms)
 {
-    printk(LOG_NOTE, "Got interrupt %d\n", irq);
-    return 0;
+    armv8_generic_timer_timer_val_el0_wr(NULL, ms * systime_frequency);
 }
 
-void timer_timeout(uint32_t ms)
-{
-    uint32_t cntp_tval_el0 = ms * timestamp_freq() / 1000 ;
-    sysreg_write_cntp_tval_el0(cntp_tval_el0);
-    printk(LOG_NOTE, "CNTP_TVAL_EL0=%ld\n", sysreg_read_cntp_tval_el0());
-}
 
 systime_t systime_now(void)
 {
-    return timestamp_read();
+    return timer_get_timestamp();
 }
index 9c4d601..84f2ed1 100644 (file)
@@ -83,15 +83,6 @@ void platform_notify_bsp(lpaddr_t *mailbox);
 
 
 /*
- * Timers
- */
-void     timers_init(int timeslice);
-uint64_t timestamp_read(void);
-uint32_t timestamp_freq(void);
-bool     timer_interrupt(uint32_t irq);
-void timer_timeout(uint32_t ms);
-
-/*
  * UART locations
  */
 extern lpaddr_t uart_base[];
@@ -103,8 +94,8 @@ extern size_t uart_size[];
 extern lpaddr_t platform_gic_cpu_base;
 extern lpaddr_t platform_gic_dist_base;
 
-#define tsc_read() timestamp_read()
-#define tsc_get_hz() timestamp_freq()
+#define tsc_read() timer_get_timestamp()
+#define tsc_get_hz() timer_get_frequency()
 
 /*
  * GIC interface
diff --git a/kernel/include/arch/armv8/timers.h b/kernel/include/arch/armv8/timers.h
new file mode 100644 (file)
index 0000000..9300542
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * \file
+ * \brief Platform interface for ARMv7-A boards.
+ *
+ * This file defines the hardware abstraction layer for ARM targets. Each
+ * board is expected to have an implementation that corresponds to this
+ * interface.
+ *
+ * This interface is expected to change as new boards are added.
+ */
+
+/*
+ * Copyright (c) 2016 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef __ARMv8_TIMER_H_
+#define __ARMv8_TIMER_H_
+
+#include <barrelfish_kpi/types.h>
+#include <barrelfish_kpi/platform.h>
+
+#include <sysreg.h>
+#include <dev/armv8/armv8_generic_timer_dev.h>
+
+/*
+ * Timers
+ */
+
+/**
+ * @brief initialize the timers
+ */
+void timers_init(int timeslice);
+
+
+/**
+ * @brief resets the timer to fire in $ms milliseconds
+ *
+ * @param ms millisecons
+ */
+void timer_reset(uint64_t ms);
+
+/**
+ * @brief obtains the current frequency
+ *
+ * @return returns the frequency in Hz
+ */
+static inline cycles_t timer_get_frequency(void)
+{
+    return armv8_generic_timer_frequency_el0_rd(NULL);
+}
+
+/**
+ * @brief get the current timer value
+ *
+ * @return returns the current timer value in clock cycles
+ */
+static inline cycles_t timer_get_timestamp(void)
+{
+    return armv8_generic_timer_count_el0_rd(NULL);
+}
+
+/**
+ * @brief queries the timer if it is set
+ *
+ * @return TRUE if the timer has not fired yet
+ */
+static inline volatile bool timer_is_set(void)
+{
+    return (armv8_generic_timer_ctrl_el0_ISTATUS_rdf(NULL) == 0);
+}
+
+#endif // __ARMv8_TIMER_H_