Skip to content

Commit

Permalink
arm/time,vtimer: Get rid of READ/WRITE_SYSREG32
Browse files Browse the repository at this point in the history
AArch64 registers are 64bit whereas AArch32 registers
are 32bit or 64bit. MSR/MRS are expecting 64bit values thus
we should get rid of helpers READ/WRITE_SYSREG32
in favour of using READ/WRITE_SYSREG.
We should also use register_t type when reading sysregs
which can correspond to uint64_t or uint32_t.
Even though many AArch64 registers have upper 32bit reserved
it does not mean that they can't be widen in the future.

Modify type of vtimer structure's member: ctl to register_t.

Add macro CNTFRQ_MASK containing mask for timer clock frequency
field of CNTFRQ_EL0 register.

Modify CNTx_CTL_* macros to return unsigned long instead of
unsigned int as ctl is now of type register_t.

Signed-off-by: Michal Orzel <[email protected]>
Acked-by: Julien Grall <[email protected]>
  • Loading branch information
orzelmichal authored and Julien Grall committed May 10, 2021
1 parent 86faae5 commit 3f56835
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 21 deletions.
28 changes: 14 additions & 14 deletions xen/arch/arm/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void __init preinit_xen_time(void)
preinit_acpi_xen_time();

if ( !cpu_khz )
cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000;
cpu_khz = (READ_SYSREG(CNTFRQ_EL0) & CNTFRQ_MASK) / 1000;

res = platform_init_time();
if ( res )
Expand Down Expand Up @@ -205,13 +205,13 @@ int reprogram_timer(s_time_t timeout)

if ( timeout == 0 )
{
WRITE_SYSREG32(0, CNTHP_CTL_EL2);
WRITE_SYSREG(0, CNTHP_CTL_EL2);
return 1;
}

deadline = ns_to_ticks(timeout) + boot_count;
WRITE_SYSREG64(deadline, CNTHP_CVAL_EL2);
WRITE_SYSREG32(CNTx_CTL_ENABLE, CNTHP_CTL_EL2);
WRITE_SYSREG(CNTx_CTL_ENABLE, CNTHP_CTL_EL2);
isb();

/* No need to check for timers in the past; the Generic Timer fires
Expand All @@ -223,23 +223,23 @@ int reprogram_timer(s_time_t timeout)
static void timer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
{
if ( irq == (timer_irq[TIMER_HYP_PPI]) &&
READ_SYSREG32(CNTHP_CTL_EL2) & CNTx_CTL_PENDING )
READ_SYSREG(CNTHP_CTL_EL2) & CNTx_CTL_PENDING )
{
perfc_incr(hyp_timer_irqs);
/* Signal the generic timer code to do its work */
raise_softirq(TIMER_SOFTIRQ);
/* Disable the timer to avoid more interrupts */
WRITE_SYSREG32(0, CNTHP_CTL_EL2);
WRITE_SYSREG(0, CNTHP_CTL_EL2);
}

if ( irq == (timer_irq[TIMER_PHYS_NONSECURE_PPI]) &&
READ_SYSREG32(CNTP_CTL_EL0) & CNTx_CTL_PENDING )
READ_SYSREG(CNTP_CTL_EL0) & CNTx_CTL_PENDING )
{
perfc_incr(phys_timer_irqs);
/* Signal the generic timer code to do its work */
raise_softirq(TIMER_SOFTIRQ);
/* Disable the timer to avoid more interrupts */
WRITE_SYSREG32(0, CNTP_CTL_EL0);
WRITE_SYSREG(0, CNTP_CTL_EL0);
}
}

Expand All @@ -260,8 +260,8 @@ static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)

perfc_incr(virt_timer_irqs);

current->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0);
WRITE_SYSREG32(current->arch.virt_timer.ctl | CNTx_CTL_MASK, CNTV_CTL_EL0);
current->arch.virt_timer.ctl = READ_SYSREG(CNTV_CTL_EL0);
WRITE_SYSREG(current->arch.virt_timer.ctl | CNTx_CTL_MASK, CNTV_CTL_EL0);
vgic_inject_irq(current->domain, current, current->arch.virt_timer.irq, true);
}

Expand Down Expand Up @@ -297,9 +297,9 @@ void init_timer_interrupt(void)
/* Sensible defaults */
WRITE_SYSREG64(0, CNTVOFF_EL2); /* No VM-specific offset */
/* Do not let the VMs program the physical timer, only read the physical counter */
WRITE_SYSREG32(CNTHCTL_EL2_EL1PCTEN, CNTHCTL_EL2);
WRITE_SYSREG32(0, CNTP_CTL_EL0); /* Physical timer disabled */
WRITE_SYSREG32(0, CNTHP_CTL_EL2); /* Hypervisor's timer disabled */
WRITE_SYSREG(CNTHCTL_EL2_EL1PCTEN, CNTHCTL_EL2);
WRITE_SYSREG(0, CNTP_CTL_EL0); /* Physical timer disabled */
WRITE_SYSREG(0, CNTHP_CTL_EL2); /* Hypervisor's timer disabled */
isb();

request_irq(timer_irq[TIMER_HYP_PPI], 0, timer_interrupt,
Expand All @@ -320,8 +320,8 @@ void init_timer_interrupt(void)
*/
static void deinit_timer_interrupt(void)
{
WRITE_SYSREG32(0, CNTP_CTL_EL0); /* Disable physical timer */
WRITE_SYSREG32(0, CNTHP_CTL_EL2); /* Disable hypervisor's timer */
WRITE_SYSREG(0, CNTP_CTL_EL0); /* Disable physical timer */
WRITE_SYSREG(0, CNTHP_CTL_EL2); /* Disable hypervisor's timer */
isb();

release_irq(timer_irq[TIMER_HYP_PPI], NULL);
Expand Down
10 changes: 5 additions & 5 deletions xen/arch/arm/vtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ void virt_timer_save(struct vcpu *v)
{
ASSERT(!is_idle_vcpu(v));

v->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0);
WRITE_SYSREG32(v->arch.virt_timer.ctl & ~CNTx_CTL_ENABLE, CNTV_CTL_EL0);
v->arch.virt_timer.ctl = READ_SYSREG(CNTV_CTL_EL0);
WRITE_SYSREG(v->arch.virt_timer.ctl & ~CNTx_CTL_ENABLE, CNTV_CTL_EL0);
v->arch.virt_timer.cval = READ_SYSREG64(CNTV_CVAL_EL0);
if ( (v->arch.virt_timer.ctl & CNTx_CTL_ENABLE) &&
!(v->arch.virt_timer.ctl & CNTx_CTL_MASK))
Expand All @@ -159,7 +159,7 @@ void virt_timer_restore(struct vcpu *v)

WRITE_SYSREG64(v->domain->arch.virt_timer_base.offset, CNTVOFF_EL2);
WRITE_SYSREG64(v->arch.virt_timer.cval, CNTV_CVAL_EL0);
WRITE_SYSREG32(v->arch.virt_timer.ctl, CNTV_CTL_EL0);
WRITE_SYSREG(v->arch.virt_timer.ctl, CNTV_CTL_EL0);
}

static bool vtimer_cntp_ctl(struct cpu_user_regs *regs, uint32_t *r, bool read)
Expand Down Expand Up @@ -347,7 +347,7 @@ bool vtimer_emulate(struct cpu_user_regs *regs, union hsr hsr)
}

static void vtimer_update_irq(struct vcpu *v, struct vtimer *vtimer,
uint32_t vtimer_ctl)
register_t vtimer_ctl)
{
bool level;

Expand Down Expand Up @@ -389,7 +389,7 @@ void vtimer_update_irqs(struct vcpu *v)
* but this requires reworking the arch timer to implement this.
*/
vtimer_update_irq(v, &v->arch.virt_timer,
READ_SYSREG32(CNTV_CTL_EL0) & ~CNTx_CTL_MASK);
READ_SYSREG(CNTV_CTL_EL0) & ~CNTx_CTL_MASK);

/* For the physical timer we rely on our emulated state. */
vtimer_update_irq(v, &v->arch.phys_timer, v->arch.phys_timer.ctl);
Expand Down
2 changes: 1 addition & 1 deletion xen/include/asm-arm/domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct vtimer {
struct vcpu *v;
int irq;
struct timer timer;
uint32_t ctl;
register_t ctl;
uint64_t cval;
};

Expand Down
5 changes: 4 additions & 1 deletion xen/include/asm-arm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,9 +485,12 @@ extern register_t __cpu_logical_map[];

/* Timer control registers */
#define CNTx_CTL_ENABLE (1u<<0) /* Enable timer */
#define CNTx_CTL_MASK (1u<<1) /* Mask IRQ */
#define CNTx_CTL_MASK (1ul<<1) /* Mask IRQ */
#define CNTx_CTL_PENDING (1u<<2) /* IRQ pending */

/* Timer frequency mask */
#define CNTFRQ_MASK GENMASK(31, 0)

/* Exception Vector offsets */
/* ... ARM32 */
#define VECTOR32_RST 0
Expand Down

0 comments on commit 3f56835

Please sign in to comment.