1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * This software may be distributed and modified according to the terms of
5 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
6 * See "LICENSE_GPLv2.txt" for details.
7 *
8 * @TAG(GD_GPL)
9 */
10
11#include <plat/machine/hardware.h>
12#include <arch/user_access.h>
13#include <mode/machine/debug.h>
14
15#define PMUSERENR_ENABLE BIT(0)
16
17#define CNTKCTL_PL0PCTEN BIT(0)
18#define CNTKCTL_PL0VCTEN BIT(1)
19#define CNTKCTL_PL0VTEN  BIT(8)
20#define CNTKCTL_PL0PTEN  BIT(9)
21
22#define ID_DFR0_PMU_MASK (0xful << 28)
23#define ID_DFR0_PMU_NONE (0xful << 28)
24
25#define ID_PFR1_GENERIC_TIMER BIT(16)
26
27
28
29static void
30check_export_pmu(void)
31{
32#ifdef CONFIG_EXPORT_PMU_USER
33    /* Export performance counters */
34    uint32_t v;
35    v = PMUSERENR_ENABLE;
36    MCR(PMUSERENR, v);
37
38    /* enable user-level pmu event counter if we're in secure mode */
39    if (!(readDscrCp() & DBGDSCR_SECURE_MODE_DISABLED)) {
40        MRC(DBGSDER, v);
41        v |= DBGSDER_ENABLE_SECURE_USER_NON_INVASIVE_DEBUG;
42        MCR(DBGSDER, v);
43    }
44#endif
45}
46
47
48static void
49check_export_arch_timer(void)
50{
51    uint32_t v;
52    MRC(CNTKCTL, v);
53#ifdef CONFIG_EXPORT_PCNT_USER
54    v |= CNTKCTL_PL0PCTEN;
55#endif
56#ifdef CONFIG_EXPORT_VCNT_USER
57    v |= CNTKCTL_PL0VCTEN;
58#endif
59    MCR(CNTKCTL, v);
60}
61
62
63void
64armv_init_user_access(void)
65{
66    uint32_t v;
67    /* Performance Monitoring Unit */
68    MRC(ID_DFR0, v);
69    if ((v & ID_DFR0_PMU_MASK) != ID_DFR0_PMU_NONE) {
70        check_export_pmu();
71    }
72    /* Arch timers */
73    MRC(ID_PFR1, v);
74    if (v & ID_PFR1_GENERIC_TIMER) {
75        check_export_arch_timer();
76    }
77}
78
79