armv8: Start with all interrupts disabled
[barrelfish] / kernel / arch / armv8 / timers.c
1 /**
2  * \file timers.c
3  * \brief Timer support for ARMv8
4  */
5
6 /*
7  * Copyright (c) 2016 ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #include <kernel.h>
16 #include <offsets.h>
17 #include <arch/arm/platform.h>
18 #include <serial.h>
19 #include <sysreg.h>
20 #include <systime.h>
21 #include <arch/arm/platform.h>
22 #include <dev/armv8_dev.h>
23
24 /*
25  * Timers
26  */
27 void platform_timer_init(int timeslice)
28 {
29     printk(LOG_NOTE, "isr_el1=%p\n", sysreg_read_isr_el1());
30     {
31         //armv8_CNTPS_CTL_EL1_t kctl;
32         armv8_CNTKCTL_EL1_t kctl;
33         kctl = armv8_CNTKCTL_EL1_rd(NULL);
34
35         /* don't trap access to CNTFRQ* and CNTFRQ* registers from EL0 to EL1 */
36         kctl = armv8_CNTKCTL_EL1_EL0PCTEN_insert(kctl, 0x1);
37         kctl = armv8_CNTKCTL_EL1_EL0VCTEN_insert(kctl, 0x1);
38
39         /* trap access to CNTP_* and CNTV_* registers from EL0 to EL1 */
40         kctl = armv8_CNTKCTL_EL1_EL0PTEN_insert(kctl, 0x0);
41         kctl = armv8_CNTKCTL_EL1_EL0VTEN_insert(kctl, 0x0);
42
43         armv8_CNTKCTL_EL1_wr(NULL, kctl);
44     }
45
46     /* enable the timer */
47     armv8_CNTP_CTL_EL0_IMASK_wrf(NULL, 0x0);
48     armv8_CNTP_CTL_EL0_ENABLE_wrf(NULL, 0x1);
49
50     systime_frequency = armv8_CNTFRQ_EL0_rd(NULL);
51
52     /* The timeslice is in ms */
53     kernel_timeslice = ns_to_systime(timeslice * 1000000);
54
55     printf("System counter frequency is %lluHz.\n", systime_frequency);
56     printf("Timeslice interrupt every %u ticks (%dms).\n",
57             kernel_timeslice, timeslice);
58
59     armv8_PMCR_EL0_t pmcr = 0;
60     pmcr = armv8_PMCR_EL0_E_insert(pmcr, 1); /* All counters are enabled.*/
61     pmcr = armv8_PMCR_EL0_P_insert(pmcr, 1); /* reset all event counters */
62     pmcr = armv8_PMCR_EL0_C_insert(pmcr, 1); /* reset all clock counters */
63     pmcr = armv8_PMCR_EL0_D_insert(pmcr, 0); /* set counter to tick every clock cycle (1=ever 64th) */
64     pmcr = armv8_PMCR_EL0_X_insert(pmcr, 1); /* enable event support */
65     pmcr = armv8_PMCR_EL0_DP_insert(pmcr, 0); /* don't disable cycle counter */
66     //pmcr = armv8_PMCR_EL0_N_insert(pmcr, 6);  /* N is RO ? */
67     armv8_PMCR_EL0_wr(NULL, pmcr);
68
69     errval_t err;
70     err = platform_enable_interrupt(platform_get_timer_interrupt(), 0, 0, 0);
71     assert(err_is_ok(err));
72
73 // AT: disable for now because it's not supported by QEMU version<2.6.0
74 // AT: doesn't seem to break anything
75 //    armv8_PMUSERENR_EL0_t pmu = 0;
76     /* don't trap access to PM registers to EL 1 */
77 //    pmu = armv8_PMUSERENR_EL0_EN_insert(pmu, 1);
78     /* don't trap software increment wrap to EL 1 */
79 //    pmu = armv8_PMUSERENR_EL0_SW_insert(pmu, 1);
80     /* don't trap cycle counter to EL 1 */
81 //    pmu = armv8_PMUSERENR_EL0_CR_insert(pmu, 1);
82     /* don't trap event counter read to EL 1*/
83 //    pmu = armv8_PMUSERENR_EL0_ER_insert(pmu, 1);
84 //    armv8_PMUSERENR_EL0_wr(NULL, pmu);
85 }
86
87 systime_t systime_now(void)
88 {
89     return armv8_CNTPCT_EL0_rd(NULL);
90 }
91
92 void systime_set_timeout(systime_t absolute_timeout)
93 {
94     armv8_CNTP_CVAL_EL0_wr(NULL, absolute_timeout);
95 }
96
97 void systime_set_timer(systime_t relative_timeout)
98 {
99     armv8_CNTP_TVAL_EL0_wr(NULL, relative_timeout);
100 }
101
102 bool platform_is_timer_interrupt(uint32_t irq)
103 {
104     if (irq == 30 || irq == 29) {
105         return 1;
106     }
107     return 0;
108 }