int domain_vtimer_init(struct domain *d) { d->arch.phys_timer_base.offset = NOW(); d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0); /* At this stage vgic_reserve_virq can't fail */ if ( is_hardware_domain(d) ) { if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_PHYS_SECURE_PPI)) ) BUG(); if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_PHYS_NONSECURE_PPI)) ) BUG(); if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_VIRT_PPI)) ) BUG(); } else { if ( !vgic_reserve_virq(d, GUEST_TIMER_PHYS_S_PPI) ) BUG(); if ( !vgic_reserve_virq(d, GUEST_TIMER_PHYS_NS_PPI) ) BUG(); if ( !vgic_reserve_virq(d, GUEST_TIMER_VIRT_PPI) ) BUG(); } return 0; }
/* Set up the timer on the boot CPU (early init function) */ void __init preinit_xen_time(void) { static const struct dt_device_match timer_ids[] __initconst = { DT_MATCH_TIMER, { /* sentinel */ }, }; int res; u32 rate; timer = dt_find_matching_node(NULL, timer_ids); if ( !timer ) panic("Unable to find a compatible timer in the device tree"); dt_device_set_used_by(timer, DOMID_XEN); res = platform_init_time(); if ( res ) panic("Timer: Cannot initialize platform timer"); res = dt_property_read_u32(timer, "clock-frequency", &rate); if ( res ) cpu_khz = rate / 1000; else cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000; boot_count = READ_SYSREG64(CNTPCT_EL0); }
int domain_vtimer_init(struct domain *d, struct xen_arch_domainconfig *config) { d->arch.phys_timer_base.offset = NOW(); d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0); d->time_offset_seconds = ticks_to_ns(d->arch.virt_timer_base.offset - boot_count); do_div(d->time_offset_seconds, 1000000000); config->clock_frequency = timer_dt_clock_frequency; /* At this stage vgic_reserve_virq can't fail */ if ( is_hardware_domain(d) ) { if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_PHYS_SECURE_PPI)) ) BUG(); if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_PHYS_NONSECURE_PPI)) ) BUG(); if ( !vgic_reserve_virq(d, timer_get_irq(TIMER_VIRT_PPI)) ) BUG(); } else { if ( !vgic_reserve_virq(d, GUEST_TIMER_PHYS_S_PPI) ) BUG(); if ( !vgic_reserve_virq(d, GUEST_TIMER_PHYS_NS_PPI) ) BUG(); if ( !vgic_reserve_virq(d, GUEST_TIMER_VIRT_PPI) ) BUG(); } return 0; }
asmlinkage void do_bad_mode(struct cpu_user_regs *regs, int reason) { uint64_t esr = READ_SYSREG64(ESR_EL2); printk("Bad mode in %s handler detected, code 0x%08"PRIx64"\n", handler[reason], esr); local_irq_disable(); panic("bad mode"); }
void dump_hyp_walk(vaddr_t addr) { uint64_t ttbr = READ_SYSREG64(TTBR0_EL2); printk("Walking Hypervisor VA 0x%"PRIvaddr" via TTBR 0x%016"PRIx64"\n", addr, ttbr); BUG_ON( (lpae_t *)(unsigned long)(ttbr - phys_offset) != xen_pgtable ); dump_pt_walk(xen_pgtable, addr); }
int vcpu_vtimer_init(struct vcpu *v) { struct vtimer *t = &v->arch.phys_timer; init_timer(&t->timer, phys_timer_expired, t, smp_processor_id()); t->ctl = 0; t->offset = NOW(); t->cval = NOW(); t->irq = 30; t->v = v; t = &v->arch.virt_timer; init_timer(&t->timer, virt_timer_expired, t, smp_processor_id()); t->ctl = 0; t->offset = READ_SYSREG64(CNTVCT_EL0) + READ_SYSREG64(CNTVOFF_EL2); t->cval = 0; t->irq = 27; t->v = v; return 0; }
/* Set up the timer on the boot CPU */ int __init init_xen_time(void) { static const struct dt_device_match timer_ids[] __initconst = { DT_MATCH_TIMER, { /* sentinel */ }, }; struct dt_device_node *dev; int res; unsigned int i; u32 rate; dev = dt_find_matching_node(NULL, timer_ids); if ( !dev ) panic("Unable to find a compatible timer in the device tree"); dt_device_set_used_by(dev, DOMID_XEN); /* Retrieve all IRQs for the timer */ for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ ) { res = platform_get_irq(dev, i); if ( res < 0 ) panic("Timer: Unable to retrieve IRQ %u from the device tree", i); timer_irq[i] = res; } printk("Generic Timer IRQ: 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 ) panic("Timer: Cannot initialize platform timer"); /* Check that this CPU supports the Generic Timer interface */ if ( !cpu_has_gentimer ) panic("CPU does not support the Generic Timer v1 interface"); res = dt_property_read_u32(dev, "clock-frequency", &rate); if ( res ) cpu_khz = rate / 1000; else 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 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.cval = READ_SYSREG64(CNTV_CVAL_EL0); if ( (v->arch.virt_timer.ctl & CNTx_CTL_ENABLE) && !(v->arch.virt_timer.ctl & CNTx_CTL_MASK)) { set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_timer.cval + v->domain->arch.virt_timer_base.offset - boot_count)); } return 0; }
int virt_timer_save(struct vcpu *v) { if ( is_idle_domain(v->domain) ) return 0; 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.cval = READ_SYSREG64(CNTV_CVAL_EL0); if ( v->arch.virt_timer.ctl & CNTx_CTL_ENABLE ) { set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_timer.cval + v->arch.virt_timer.offset - boot_count)); } return 0; }
void dump_hyp_walk(vaddr_t addr) { uint64_t ttbr = READ_SYSREG64(TTBR0_EL2); lpae_t *pgtable = THIS_CPU_PGTABLE; printk("Walking Hypervisor VA 0x%"PRIvaddr" " "on CPU%d via TTBR 0x%016"PRIx64"\n", addr, smp_processor_id(), ttbr); if ( smp_processor_id() == 0 ) BUG_ON( (lpae_t *)(unsigned long)(ttbr - phys_offset) != pgtable ); else BUG_ON( virt_to_maddr(pgtable) != ttbr ); dump_pt_walk(ttbr, addr, HYP_PT_ROOT_LEVEL, 1); }
void __init preinit_xen_time(void) { int res; /* Initialize all the generic timers presented in GTDT */ if ( acpi_disabled ) preinit_dt_xen_time(); else preinit_acpi_xen_time(); if ( !cpu_khz ) cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000; res = platform_init_time(); if ( res ) panic("Timer: Cannot initialize platform timer"); boot_count = READ_SYSREG64(CNTPCT_EL0); }
/* Return number of nanoseconds since boot */ s_time_t get_s_time(void) { uint64_t ticks = READ_SYSREG64(CNTPCT_EL0) - boot_count; return ticks_to_ns(ticks); }
static void ctxt_switch_from(struct vcpu *p) { p2m_save_state(p); /* CP 15 */ p->arch.csselr = READ_SYSREG(CSSELR_EL1); /* Control Registers */ p->arch.cpacr = READ_SYSREG(CPACR_EL1); p->arch.contextidr = READ_SYSREG(CONTEXTIDR_EL1); p->arch.tpidr_el0 = READ_SYSREG(TPIDR_EL0); p->arch.tpidrro_el0 = READ_SYSREG(TPIDRRO_EL0); p->arch.tpidr_el1 = READ_SYSREG(TPIDR_EL1); /* Arch timer */ p->arch.cntkctl = READ_SYSREG32(CNTKCTL_EL1); virt_timer_save(p); if ( is_32bit_domain(p->domain) && cpu_has_thumbee ) { p->arch.teecr = READ_SYSREG32(TEECR32_EL1); p->arch.teehbr = READ_SYSREG32(TEEHBR32_EL1); } #ifdef CONFIG_ARM_32 p->arch.joscr = READ_CP32(JOSCR); p->arch.jmcr = READ_CP32(JMCR); #endif isb(); /* MMU */ p->arch.vbar = READ_SYSREG(VBAR_EL1); p->arch.ttbcr = READ_SYSREG(TCR_EL1); p->arch.ttbr0 = READ_SYSREG64(TTBR0_EL1); p->arch.ttbr1 = READ_SYSREG64(TTBR1_EL1); if ( is_32bit_domain(p->domain) ) p->arch.dacr = READ_SYSREG(DACR32_EL2); p->arch.par = READ_SYSREG64(PAR_EL1); #if defined(CONFIG_ARM_32) p->arch.mair0 = READ_CP32(MAIR0); p->arch.mair1 = READ_CP32(MAIR1); p->arch.amair0 = READ_CP32(AMAIR0); p->arch.amair1 = READ_CP32(AMAIR1); #else p->arch.mair = READ_SYSREG64(MAIR_EL1); p->arch.amair = READ_SYSREG64(AMAIR_EL1); #endif /* Fault Status */ #if defined(CONFIG_ARM_32) p->arch.dfar = READ_CP32(DFAR); p->arch.ifar = READ_CP32(IFAR); p->arch.dfsr = READ_CP32(DFSR); #elif defined(CONFIG_ARM_64) p->arch.far = READ_SYSREG64(FAR_EL1); p->arch.esr = READ_SYSREG64(ESR_EL1); #endif if ( is_32bit_domain(p->domain) ) p->arch.ifsr = READ_SYSREG(IFSR32_EL2); p->arch.afsr0 = READ_SYSREG(AFSR0_EL1); p->arch.afsr1 = READ_SYSREG(AFSR1_EL1); /* XXX MPU */ /* VFP */ vfp_save_state(p); /* VGIC */ gic_save_state(p); isb(); context_saved(p); }
int domain_vtimer_init(struct domain *d) { d->arch.phys_timer_base.offset = NOW(); d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0); return 0; }