#include <plat/machine/hardware.h>
#include <arch/user_access.h>
#include <mode/machine/debug.h>
#define PMUSERENR_ENABLE BIT(0)
#define CNTKCTL_PL0PCTEN BIT(0)
#define CNTKCTL_PL0VCTEN BIT(1)
#define CNTKCTL_PL0VTEN BIT(8)
#define CNTKCTL_PL0PTEN BIT(9)
#define ID_DFR0_PMU_MASK (0xful << 28)
#define ID_DFR0_PMU_NONE (0xful << 28)
#define ID_PFR1_GENERIC_TIMER BIT(16)
static void
check_export_pmu(void)
{
#ifdef CONFIG_EXPORT_PMU_USER
uint32_t v;
v = PMUSERENR_ENABLE;
MCR(PMUSERENR, v);
if (!(readDscrCp() & DBGDSCR_SECURE_MODE_DISABLED)) {
MRC(DBGSDER, v);
v |= DBGSDER_ENABLE_SECURE_USER_NON_INVASIVE_DEBUG;
MCR(DBGSDER, v);
}
#endif
}
static void
check_export_arch_timer(void)
{
uint32_t v;
MRC(CNTKCTL, v);
#ifdef CONFIG_EXPORT_PCNT_USER
v |= CNTKCTL_PL0PCTEN;
#endif
#ifdef CONFIG_EXPORT_VCNT_USER
v |= CNTKCTL_PL0VCTEN;
#endif
MCR(CNTKCTL, v);
}
void
armv_init_user_access(void)
{
uint32_t v;
MRC(ID_DFR0, v);
if ((v & ID_DFR0_PMU_MASK) != ID_DFR0_PMU_NONE) {
check_export_pmu();
}
MRC(ID_PFR1, v);
if (v & ID_PFR1_GENERIC_TIMER) {
check_export_arch_timer();
}
}