Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/vmm/vmm_hyp.c
| Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
| static void | static void | ||||
| vmm_hyp_reg_store(struct hypctx *hypctx, struct hyp *hyp, bool guest) | vmm_hyp_reg_store(struct hypctx *hypctx, struct hyp *hyp, bool guest) | ||||
| { | { | ||||
| uint64_t dfr0; | uint64_t dfr0; | ||||
| /* Store the guest VFP registers */ | /* Store the guest VFP registers */ | ||||
| if (guest) { | if (guest) { | ||||
| /* Store the timer registers */ | /* Store the timer registers */ | ||||
| hypctx->vtimer_cpu.cntkctl_el1 = READ_SPECIALREG(cntkctl_el1); | hypctx->vtimer_cpu.cntkctl_el1 = | ||||
| READ_SPECIALREG(EL1_REG(CNTKCTL)); | |||||
| hypctx->vtimer_cpu.virt_timer.cntx_cval_el0 = | hypctx->vtimer_cpu.virt_timer.cntx_cval_el0 = | ||||
| READ_SPECIALREG(cntv_cval_el0); | READ_SPECIALREG(EL0_REG(CNTV_CVAL)); | ||||
| hypctx->vtimer_cpu.virt_timer.cntx_ctl_el0 = | hypctx->vtimer_cpu.virt_timer.cntx_ctl_el0 = | ||||
| READ_SPECIALREG(cntv_ctl_el0); | READ_SPECIALREG(EL0_REG(CNTV_CTL)); | ||||
| /* Store the GICv3 registers */ | /* Store the GICv3 registers */ | ||||
| hypctx->vgic_v3_regs.ich_eisr_el2 = | hypctx->vgic_v3_regs.ich_eisr_el2 = | ||||
| READ_SPECIALREG(ich_eisr_el2); | READ_SPECIALREG(ich_eisr_el2); | ||||
| hypctx->vgic_v3_regs.ich_elrsr_el2 = | hypctx->vgic_v3_regs.ich_elrsr_el2 = | ||||
| READ_SPECIALREG(ich_elrsr_el2); | READ_SPECIALREG(ich_elrsr_el2); | ||||
| hypctx->vgic_v3_regs.ich_hcr_el2 = | hypctx->vgic_v3_regs.ich_hcr_el2 = | ||||
| READ_SPECIALREG(ich_hcr_el2); | READ_SPECIALREG(ich_hcr_el2); | ||||
| ▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | #undef STORE_PMU | ||||
| hypctx->tf.tf_sp = READ_SPECIALREG(sp_el1); | hypctx->tf.tf_sp = READ_SPECIALREG(sp_el1); | ||||
| hypctx->tf.tf_elr = READ_SPECIALREG(elr_el2); | hypctx->tf.tf_elr = READ_SPECIALREG(elr_el2); | ||||
| hypctx->tf.tf_spsr = READ_SPECIALREG(spsr_el2); | hypctx->tf.tf_spsr = READ_SPECIALREG(spsr_el2); | ||||
| if (guest) { | if (guest) { | ||||
| hypctx->tf.tf_esr = READ_SPECIALREG(esr_el2); | hypctx->tf.tf_esr = READ_SPECIALREG(esr_el2); | ||||
| } | } | ||||
| /* Store the guest special registers */ | /* Store the guest special registers */ | ||||
| hypctx->elr_el1 = READ_SPECIALREG(elr_el1); | |||||
| hypctx->sp_el0 = READ_SPECIALREG(sp_el0); | hypctx->sp_el0 = READ_SPECIALREG(sp_el0); | ||||
| hypctx->tpidr_el0 = READ_SPECIALREG(tpidr_el0); | hypctx->tpidr_el0 = READ_SPECIALREG(tpidr_el0); | ||||
| hypctx->tpidrro_el0 = READ_SPECIALREG(tpidrro_el0); | hypctx->tpidrro_el0 = READ_SPECIALREG(tpidrro_el0); | ||||
| hypctx->tpidr_el1 = READ_SPECIALREG(tpidr_el1); | hypctx->tpidr_el1 = READ_SPECIALREG(tpidr_el1); | ||||
| hypctx->vbar_el1 = READ_SPECIALREG(vbar_el1); | |||||
| hypctx->actlr_el1 = READ_SPECIALREG(actlr_el1); | hypctx->actlr_el1 = READ_SPECIALREG(actlr_el1); | ||||
| hypctx->afsr0_el1 = READ_SPECIALREG(afsr0_el1); | |||||
| hypctx->afsr1_el1 = READ_SPECIALREG(afsr1_el1); | |||||
| hypctx->amair_el1 = READ_SPECIALREG(amair_el1); | |||||
| hypctx->contextidr_el1 = READ_SPECIALREG(contextidr_el1); | |||||
| hypctx->cpacr_el1 = READ_SPECIALREG(cpacr_el1); | |||||
| hypctx->csselr_el1 = READ_SPECIALREG(csselr_el1); | hypctx->csselr_el1 = READ_SPECIALREG(csselr_el1); | ||||
| hypctx->esr_el1 = READ_SPECIALREG(esr_el1); | |||||
| hypctx->far_el1 = READ_SPECIALREG(far_el1); | |||||
| hypctx->mair_el1 = READ_SPECIALREG(mair_el1); | |||||
| hypctx->mdccint_el1 = READ_SPECIALREG(mdccint_el1); | hypctx->mdccint_el1 = READ_SPECIALREG(mdccint_el1); | ||||
| hypctx->mdscr_el1 = READ_SPECIALREG(mdscr_el1); | hypctx->mdscr_el1 = READ_SPECIALREG(mdscr_el1); | ||||
| hypctx->par_el1 = READ_SPECIALREG(par_el1); | hypctx->par_el1 = READ_SPECIALREG(par_el1); | ||||
| hypctx->sctlr_el1 = READ_SPECIALREG(sctlr_el1); | |||||
| hypctx->spsr_el1 = READ_SPECIALREG(spsr_el1); | if (guest_or_nonvhe(guest)) { | ||||
| hypctx->tcr_el1 = READ_SPECIALREG(tcr_el1); | hypctx->elr_el1 = READ_SPECIALREG(EL1_REG(ELR)); | ||||
| hypctx->vbar_el1 = READ_SPECIALREG(EL1_REG(VBAR)); | |||||
| hypctx->afsr0_el1 = READ_SPECIALREG(EL1_REG(AFSR0)); | |||||
| hypctx->afsr1_el1 = READ_SPECIALREG(EL1_REG(AFSR1)); | |||||
| hypctx->amair_el1 = READ_SPECIALREG(EL1_REG(AMAIR)); | |||||
| hypctx->contextidr_el1 = READ_SPECIALREG(EL1_REG(CONTEXTIDR)); | |||||
| hypctx->cpacr_el1 = READ_SPECIALREG(EL1_REG(CPACR)); | |||||
| hypctx->esr_el1 = READ_SPECIALREG(EL1_REG(ESR)); | |||||
| hypctx->far_el1 = READ_SPECIALREG(EL1_REG(FAR)); | |||||
| hypctx->mair_el1 = READ_SPECIALREG(EL1_REG(MAIR)); | |||||
| hypctx->sctlr_el1 = READ_SPECIALREG(EL1_REG(SCTLR)); | |||||
| hypctx->spsr_el1 = READ_SPECIALREG(EL1_REG(SPSR)); | |||||
| hypctx->tcr_el1 = READ_SPECIALREG(EL1_REG(TCR)); | |||||
| /* TODO: Support when this is not res0 */ | /* TODO: Support when this is not res0 */ | ||||
| hypctx->tcr2_el1 = 0; | hypctx->tcr2_el1 = 0; | ||||
| hypctx->ttbr0_el1 = READ_SPECIALREG(ttbr0_el1); | hypctx->ttbr0_el1 = READ_SPECIALREG(EL1_REG(TTBR0)); | ||||
| hypctx->ttbr1_el1 = READ_SPECIALREG(ttbr1_el1); | hypctx->ttbr1_el1 = READ_SPECIALREG(EL1_REG(TTBR1)); | ||||
| } | |||||
| hypctx->cptr_el2 = READ_SPECIALREG(cptr_el2); | hypctx->cptr_el2 = READ_SPECIALREG(cptr_el2); | ||||
| hypctx->hcr_el2 = READ_SPECIALREG(hcr_el2); | hypctx->hcr_el2 = READ_SPECIALREG(hcr_el2); | ||||
| hypctx->vpidr_el2 = READ_SPECIALREG(vpidr_el2); | hypctx->vpidr_el2 = READ_SPECIALREG(vpidr_el2); | ||||
| hypctx->vmpidr_el2 = READ_SPECIALREG(vmpidr_el2); | hypctx->vmpidr_el2 = READ_SPECIALREG(vmpidr_el2); | ||||
| } | } | ||||
| static void | static void | ||||
| vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest) | vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest) | ||||
| { | { | ||||
| uint64_t dfr0; | uint64_t dfr0; | ||||
| /* Restore the special registers */ | /* Restore the special registers */ | ||||
| WRITE_SPECIALREG(hcr_el2, hypctx->hcr_el2); | WRITE_SPECIALREG(hcr_el2, hypctx->hcr_el2); | ||||
| isb(); | isb(); | ||||
| WRITE_SPECIALREG(elr_el1, hypctx->elr_el1); | |||||
| WRITE_SPECIALREG(sp_el0, hypctx->sp_el0); | WRITE_SPECIALREG(sp_el0, hypctx->sp_el0); | ||||
| WRITE_SPECIALREG(tpidr_el0, hypctx->tpidr_el0); | WRITE_SPECIALREG(tpidr_el0, hypctx->tpidr_el0); | ||||
| WRITE_SPECIALREG(tpidrro_el0, hypctx->tpidrro_el0); | WRITE_SPECIALREG(tpidrro_el0, hypctx->tpidrro_el0); | ||||
| WRITE_SPECIALREG(tpidr_el1, hypctx->tpidr_el1); | WRITE_SPECIALREG(tpidr_el1, hypctx->tpidr_el1); | ||||
| WRITE_SPECIALREG(vbar_el1, hypctx->vbar_el1); | |||||
| WRITE_SPECIALREG(actlr_el1, hypctx->actlr_el1); | WRITE_SPECIALREG(actlr_el1, hypctx->actlr_el1); | ||||
| WRITE_SPECIALREG(afsr0_el1, hypctx->afsr0_el1); | |||||
| WRITE_SPECIALREG(afsr1_el1, hypctx->afsr1_el1); | |||||
| WRITE_SPECIALREG(amair_el1, hypctx->amair_el1); | |||||
| WRITE_SPECIALREG(contextidr_el1, hypctx->contextidr_el1); | |||||
| WRITE_SPECIALREG(cpacr_el1, hypctx->cpacr_el1); | |||||
| WRITE_SPECIALREG(csselr_el1, hypctx->csselr_el1); | WRITE_SPECIALREG(csselr_el1, hypctx->csselr_el1); | ||||
| WRITE_SPECIALREG(esr_el1, hypctx->esr_el1); | |||||
| WRITE_SPECIALREG(far_el1, hypctx->far_el1); | |||||
| WRITE_SPECIALREG(mdccint_el1, hypctx->mdccint_el1); | WRITE_SPECIALREG(mdccint_el1, hypctx->mdccint_el1); | ||||
| WRITE_SPECIALREG(mdscr_el1, hypctx->mdscr_el1); | WRITE_SPECIALREG(mdscr_el1, hypctx->mdscr_el1); | ||||
| WRITE_SPECIALREG(mair_el1, hypctx->mair_el1); | |||||
| WRITE_SPECIALREG(par_el1, hypctx->par_el1); | WRITE_SPECIALREG(par_el1, hypctx->par_el1); | ||||
| WRITE_SPECIALREG(sctlr_el1, hypctx->sctlr_el1); | |||||
| WRITE_SPECIALREG(tcr_el1, hypctx->tcr_el1); | if (guest_or_nonvhe(guest)) { | ||||
| WRITE_SPECIALREG(EL1_REG(ELR), hypctx->elr_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(VBAR), hypctx->vbar_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(AFSR0), hypctx->afsr0_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(AFSR1), hypctx->afsr1_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(AMAIR), hypctx->amair_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(CONTEXTIDR), hypctx->contextidr_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(CPACR), hypctx->cpacr_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(ESR), hypctx->esr_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(FAR), hypctx->far_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(MAIR), hypctx->mair_el1); // | |||||
| WRITE_SPECIALREG(EL1_REG(SCTLR), hypctx->sctlr_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(SPSR), hypctx->spsr_el1); | |||||
| WRITE_SPECIALREG(EL1_REG(TCR), hypctx->tcr_el1); | |||||
| /* TODO: tcr2_el1 */ | /* TODO: tcr2_el1 */ | ||||
| WRITE_SPECIALREG(ttbr0_el1, hypctx->ttbr0_el1); | WRITE_SPECIALREG(EL1_REG(TTBR0), hypctx->ttbr0_el1); | ||||
| WRITE_SPECIALREG(ttbr1_el1, hypctx->ttbr1_el1); | WRITE_SPECIALREG(EL1_REG(TTBR1), hypctx->ttbr1_el1); | ||||
| WRITE_SPECIALREG(spsr_el1, hypctx->spsr_el1); | } | ||||
| WRITE_SPECIALREG(cptr_el2, hypctx->cptr_el2); | WRITE_SPECIALREG(cptr_el2, hypctx->cptr_el2); | ||||
| WRITE_SPECIALREG(vpidr_el2, hypctx->vpidr_el2); | WRITE_SPECIALREG(vpidr_el2, hypctx->vpidr_el2); | ||||
| WRITE_SPECIALREG(vmpidr_el2, hypctx->vmpidr_el2); | WRITE_SPECIALREG(vmpidr_el2, hypctx->vmpidr_el2); | ||||
| /* Load the special regs from the trapframe */ | /* Load the special regs from the trapframe */ | ||||
| WRITE_SPECIALREG(sp_el1, hypctx->tf.tf_sp); | WRITE_SPECIALREG(sp_el1, hypctx->tf.tf_sp); | ||||
| WRITE_SPECIALREG(elr_el2, hypctx->tf.tf_elr); | WRITE_SPECIALREG(elr_el2, hypctx->tf.tf_elr); | ||||
| ▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | #define LOAD_DBG_WRP(x) \ | ||||
| LOAD_DBG_WRP(1); | LOAD_DBG_WRP(1); | ||||
| default: | default: | ||||
| LOAD_DBG_WRP(0); | LOAD_DBG_WRP(0); | ||||
| #undef LOAD_DBG_WRP | #undef LOAD_DBG_WRP | ||||
| } | } | ||||
| if (guest) { | if (guest) { | ||||
| /* Load the timer registers */ | /* Load the timer registers */ | ||||
| WRITE_SPECIALREG(cntkctl_el1, hypctx->vtimer_cpu.cntkctl_el1); | WRITE_SPECIALREG(EL1_REG(CNTKCTL), | ||||
| WRITE_SPECIALREG(cntv_cval_el0, | hypctx->vtimer_cpu.cntkctl_el1); | ||||
| WRITE_SPECIALREG(EL0_REG(CNTV_CVAL), | |||||
| hypctx->vtimer_cpu.virt_timer.cntx_cval_el0); | hypctx->vtimer_cpu.virt_timer.cntx_cval_el0); | ||||
| WRITE_SPECIALREG(cntv_ctl_el0, | WRITE_SPECIALREG(EL0_REG(CNTV_CTL), | ||||
| hypctx->vtimer_cpu.virt_timer.cntx_ctl_el0); | hypctx->vtimer_cpu.virt_timer.cntx_ctl_el0); | ||||
| WRITE_SPECIALREG(cnthctl_el2, hyp->vtimer.cnthctl_el2); | WRITE_SPECIALREG(cnthctl_el2, hyp->vtimer.cnthctl_el2); | ||||
| WRITE_SPECIALREG(cntvoff_el2, hyp->vtimer.cntvoff_el2); | WRITE_SPECIALREG(cntvoff_el2, hyp->vtimer.cntvoff_el2); | ||||
| /* Load the GICv3 registers */ | /* Load the GICv3 registers */ | ||||
| WRITE_SPECIALREG(ich_hcr_el2, hypctx->vgic_v3_regs.ich_hcr_el2); | WRITE_SPECIALREG(ich_hcr_el2, hypctx->vgic_v3_regs.ich_hcr_el2); | ||||
| WRITE_SPECIALREG(ich_vmcr_el2, | WRITE_SPECIALREG(ich_vmcr_el2, | ||||
| hypctx->vgic_v3_regs.ich_vmcr_el2); | hypctx->vgic_v3_regs.ich_vmcr_el2); | ||||
| ▲ Show 20 Lines • Show All 240 Lines • Show Last 20 Lines | |||||