Commit a4110027 authored by Andrew Jones's avatar Andrew Jones Committed by Paolo Bonzini
Browse files

arm/arm64: timer: Extract irqs at setup time



The timer can be useful for other tests besides the timer test.
Extract the DT parsing of the irqs out of the timer test into
setup and provide them along with some defines in a new timer.h
file.

Signed-off-by: Andrew Jones's avatarAndrew Jones <drjones@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 13fc88ab
......@@ -8,15 +8,12 @@
#include <libcflat.h>
#include <devicetree.h>
#include <errata.h>
#include <asm/timer.h>
#include <asm/delay.h>
#include <asm/processor.h>
#include <asm/gic.h>
#include <asm/io.h>
#define ARCH_TIMER_CTL_ENABLE (1 << 0)
#define ARCH_TIMER_CTL_IMASK (1 << 1)
#define ARCH_TIMER_CTL_ISTATUS (1 << 2)
static void *gic_isenabler;
static void *gic_icenabler;
......@@ -108,7 +105,6 @@ static void write_ptimer_ctl(u64 val)
struct timer_info {
u32 irq;
u32 irq_flags;
volatile bool irq_received;
u64 (*read_counter)(void);
u64 (*read_cval)(void);
......@@ -304,23 +300,9 @@ static void test_ptimer(void)
static void test_init(void)
{
const struct fdt_property *prop;
const void *fdt = dt_fdt();
int node, len;
u32 *data;
node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
assert(node >= 0);
prop = fdt_get_property(fdt, node, "interrupts", &len);
assert(prop && len == (4 * 3 * sizeof(u32)));
data = (u32 *)prop->data;
assert(fdt32_to_cpu(data[3]) == 1);
ptimer_info.irq = fdt32_to_cpu(data[4]);
ptimer_info.irq_flags = fdt32_to_cpu(data[5]);
assert(fdt32_to_cpu(data[6]) == 1);
vtimer_info.irq = fdt32_to_cpu(data[7]);
vtimer_info.irq_flags = fdt32_to_cpu(data[8]);
assert(TIMER_PTIMER_IRQ != -1 && TIMER_VTIMER_IRQ != -1);
ptimer_info.irq = TIMER_PTIMER_IRQ;
vtimer_info.irq = TIMER_VTIMER_IRQ;
install_exception_handler(EL1H_SYNC, ESR_EL1_EC_UNKNOWN, ptimer_unsupported_handler);
ptimer_info.read_ctl();
......
/*
* Copyright (C) 2020, Red Hat Inc, Andrew Jones <drjones@redhat.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.
*/
#ifndef _ASMARM_TIMER_H_
#define _ASMARM_TIMER_H_
#define ARCH_TIMER_CTL_ENABLE (1 << 0)
#define ARCH_TIMER_CTL_IMASK (1 << 1)
#define ARCH_TIMER_CTL_ISTATUS (1 << 2)
#ifndef __ASSEMBLY__
struct timer_state {
struct {
u32 irq;
u32 irq_flags;
} ptimer;
struct {
u32 irq;
u32 irq_flags;
} vtimer;
};
extern struct timer_state __timer_state;
#define TIMER_PTIMER_IRQ (__timer_state.ptimer.irq)
#define TIMER_VTIMER_IRQ (__timer_state.vtimer.irq)
#endif /* !__ASSEMBLY__ */
#endif /* _ASMARM_TIMER_H_ */
......@@ -22,6 +22,7 @@
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/smp.h>
#include <asm/timer.h>
#include "io.h"
......@@ -29,6 +30,8 @@
extern unsigned long stacktop;
struct timer_state __timer_state;
char *initrd;
u32 initrd_size;
......@@ -156,6 +159,43 @@ static void mem_init(phys_addr_t freemem_start)
page_alloc_ops_enable();
}
static void timer_save_state(void)
{
const struct fdt_property *prop;
const void *fdt = dt_fdt();
int node, len;
u32 *data;
node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
if (node == -FDT_ERR_NOTFOUND) {
__timer_state.ptimer.irq = -1;
__timer_state.vtimer.irq = -1;
return;
}
/*
* From Linux devicetree timer binding documentation
*
* interrupts <type irq flags>:
* secure timer irq
* non-secure timer irq (ptimer)
* virtual timer irq (vtimer)
* hypervisor timer irq
*/
prop = fdt_get_property(fdt, node, "interrupts", &len);
assert(prop && len == (4 * 3 * sizeof(u32)));
data = (u32 *)prop->data;
assert(fdt32_to_cpu(data[3]) == 1 /* PPI */);
__timer_state.ptimer.irq = fdt32_to_cpu(data[4]);
__timer_state.ptimer.irq_flags = fdt32_to_cpu(data[5]);
assert(fdt32_to_cpu(data[6]) == 1 /* PPI */);
__timer_state.vtimer.irq = fdt32_to_cpu(data[7]);
__timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]);
}
void setup(const void *fdt)
{
void *freemem = &stacktop;
......@@ -211,6 +251,8 @@ void setup(const void *fdt)
io_init();
/* finish setup */
timer_save_state();
ret = dt_get_bootargs(&bootargs);
assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
setup_args_progname(bootargs);
......
#include "../../arm/asm/timer.h"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment