3 * \brief Platform code for the Cortex-A15 MPCore.
7 * Copyright (c) 2016 ETH Zurich.
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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
16 #include <maps/a15mpcore_map.h>
22 #include <paging_kernel_arch.h>
23 #include <arch/arm/platform.h>
25 #include <arch/armv7/irq.h>
27 #define MSG(format, ...) \
28 printk( LOG_NOTE, "CortexA15 platform: "format, ## __VA_ARGS__ )
30 /* These are called from the A9/A15 common GIC (interrupt controller) code. */
32 lpaddr_t platform_gic_cpu_interface_base = 0;
33 lpaddr_t platform_gic_distributor_base = 0;
35 /* A15 platforms don't need anything special done. */
36 void platform_revision_init(void)
38 platform_gic_cpu_interface_base =
39 A15MPCORE_GICC_OFFSET + platform_get_private_region();
40 platform_gic_distributor_base =
41 A15MPCORE_GICD_OFFSET + platform_get_private_region();
45 * Return the core count from the interrupt controller
48 platform_get_core_count(void) {
49 return gic_cpu_count();
52 /* Timeslice counter uses the Non-secure Physical Timer. */
55 /* This *should* be IRQ 30, for the non-secure timer, but GEM5 only
56 * provides the secure timer, even in NS mode.
57 * The timerirq parameter allows this to be overridden. */
59 /// For now, use secure timer
60 #define DEFAULT_TIMER_IRQ 29
62 extern uint32_t timerirq;
63 extern uint32_t cntfrq;
65 void platform_timer_init(int timeslice)
67 /* If there was a cntfrq parameter passed, then overwrite the current
68 * CNTFRQ register. We need to do this if there was no bootloader to set
69 * it for us, as on the FVP simulators. */
70 if(cntfrq != 0) a15_gt_set_cntfrq(cntfrq);
72 systime_frequency = a15_gt_frequency();
74 /* The timeslice is in ms, so multiply by 1000000. */
75 kernel_timeslice = ns_to_systime(timeslice * 1000000);
77 MSG("System counter frequency is %lluHz.\n", systime_frequency);
78 MSG("Timeslice interrupt every %" PRIu64 " ticks (%dms).\n",
79 kernel_timeslice, timeslice);
83 if(timerirq == 0) timerirq = DEFAULT_TIMER_IRQ;
84 MSG("Timer interrupt is %u\n", timerirq);
86 ///* Enable the interrupt. */
87 platform_enable_interrupt(timerirq, 0, 0, 0);
89 /* Set the first timeout. */
90 systime_set_timer(kernel_timeslice);
92 /* We use the system counter for timestamps, which doesn't need any
93 * further initialisation. */
96 bool platform_is_timer_interrupt(uint32_t irq)
98 if (irq == timerirq) {
99 a15_gt_mask_interrupt();
101 /* Reset the timeout. */
102 systime_set_timer(kernel_timeslice);
109 uint32_t platform_get_timer_interrupt(void){
113 systime_t systime_now(void)
115 return a15_gt_counter();
118 void systime_set_timeout(systime_t absolute_timeout)
120 a15_gt_set_comparator(absolute_timeout);
123 void systime_set_timer(systime_t relative_timeout)
125 systime_set_timeout(systime_now() + relative_timeout);