aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaresh Bhat <naresh.bhat@linaro.org>2014-07-07 21:32:58 +0530
committerNaresh Bhat <naresh.bhat@linaro.org>2014-09-03 16:48:47 +0530
commitc1d6b5b4e1ead7080f99c3c7122f06ac10f98daa (patch)
tree67e452a5aac79636c71453b3c472561b48a1bb1f
parentc2663547bf467e1c81e76f0046903ed047bb2583 (diff)
downloadxen-c1d6b5b4e1ead7080f99c3c7122f06ac10f98daa.tar.gz
ARM64 / ACPI: Parse GTDT to initialize timer
Parse GTDT (Generic Timer Descriptor Table) to initialize timer. Using the information presented by GTDT to initialize the arch timer (not momery-mapped). Signed-off-by: Naresh Bhat <naresh.bhat@linaro.org>
-rw-r--r--xen/arch/arm/setup.c8
-rw-r--r--xen/arch/arm/time.c47
-rw-r--r--xen/include/xen/time.h1
3 files changed, 56 insertions, 0 deletions
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 6a0b25d7a6..d71427a187 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -803,7 +803,12 @@ void __init start_xen(unsigned long boot_phys_offset,
smp_init_cpus();
cpus = smp_get_max_cpus();
+/* Comment for now take it after GIC initialization */
+#if defined(CONFIG_ACPI) && defined(CONFIG_ARM_64)
+ init_xen_acpi_time();
+#else
init_xen_time();
+#endif
gic_init();
@@ -819,6 +824,9 @@ void __init start_xen(unsigned long boot_phys_offset,
xsm_dt_init();
init_maintenance_interrupt();
+
+/* FIXME: Crashing here, If I do not add the condition */
+if (acpi_disabled)
init_timer_interrupt();
timer_init();
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index a6436f1df4..7287d3c8f3 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -29,6 +29,7 @@
#include <xen/time.h>
#include <xen/sched.h>
#include <xen/event.h>
+#include <xen/acpi.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/gic.h>
@@ -226,6 +227,52 @@ struct tm wallclock_time(uint64_t *ns)
return (struct tm) { 0 };
}
+#if defined(CONFIG_ARM_64) && defined(CONFIG_ACPI)
+
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
+{
+ int res;
+ struct acpi_table_gtdt *gtdt;
+ gtdt = (struct acpi_table_gtdt *)table;
+
+ /* Initialize all the generic timer IRQ variable from GTDT table */
+ timer_irq[TIMER_PHYS_NONSECURE_PPI] = gtdt->non_secure_el1_interrupt;
+ timer_irq[TIMER_PHYS_SECURE_PPI] = gtdt->secure_el1_interrupt;
+ timer_irq[TIMER_HYP_PPI] = gtdt->non_secure_el2_interrupt;
+ timer_irq[TIMER_VIRT_PPI] = gtdt->virtual_timer_interrupt;
+
+ printk("Generic Timer IRQ from ACPI GTDT: phys=%u hyp=%u virt=%u\n",
+ timer_irq[TIMER_PHYS_NONSECURE_PPI],
+ timer_irq[TIMER_HYP_PPI],
+ timer_irq[TIMER_VIRT_PPI]);
+
+ res = platform_init_time();
+ if ( res )
+ printk("Timer: Cannot initialize platform timer");
+
+ /* Check that this CPU supports the Generic Timer interface */
+ if ( !cpu_has_gentimer )
+ printk("CPU does not support the Generic Timer v1 interface");
+
+ cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000;
+
+ boot_count = READ_SYSREG64(CNTPCT_EL0);
+
+ printk("Using generic timer at %lu KHz\n", cpu_khz);
+
+ return 0;
+}
+
+int __init init_xen_acpi_time(void)
+{
+ /* Initialize all the generic timers presented in GTDT */
+ acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+ return 0;
+}
+
+#endif
+
/*
* Local variables:
* mode: C
diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h
index 709501f359..4598a0cf62 100644
--- a/xen/include/xen/time.h
+++ b/xen/include/xen/time.h
@@ -11,6 +11,7 @@
#include <xen/types.h>
#include <public/xen.h>
+extern int init_xen_acpi_time(void);
extern int init_xen_time(void);
extern void cstate_restore_tsc(void);