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 */ 27void 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 87systime_t systime_now(void) 88{ 89 return armv8_CNTPCT_EL0_rd(NULL); 90} 91 92void systime_set_timeout(systime_t absolute_timeout) 93{ 94 armv8_CNTP_CVAL_EL0_wr(NULL, absolute_timeout); 95} 96 97void systime_set_timer(systime_t relative_timeout) 98{ 99 armv8_CNTP_TVAL_EL0_wr(NULL, relative_timeout); 100} 101 102bool platform_is_timer_interrupt(uint32_t irq) 103{ 104 if (irq == 30 || irq == 29) { 105 return 1; 106 } 107 return 0; 108} 109