From 8e2e8db9763fdaa54f20ac7c6a215db77bc2d4c2 Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Thu, 3 Mar 2016 16:03:22 +1100 Subject: [PATCH] arm_hyp: rm ARM_HYP ifdefs; func inline assembly vcpu.c: encapsulate inline assembly into inline functions that added to device_pl2.h file. other files: replace #ifdef ARM_HYP with config_set(ARM_HYP) --- .../arch/arm/arch/32/mode/fastpath/fastpath.h | 6 +-- .../arm/arch/32/mode/machine/registerset.h | 32 +++++++------ include/arch/arm/arch/32/mode/machine_pl2.h | 36 +++++++++++++-- include/arch/arm/arch/object/vcpu.h | 2 + .../arm/armv/armv7-a/armv/context_switch.h | 46 +++++++++---------- include/plat/exynos5/plat/machine/devices.h | 4 +- src/arch/arm/object/tcb.c | 16 +++---- src/arch/arm/object/vcpu.c | 27 +++++------ src/plat/exynos5/machine/hardware.c | 29 ++++++------ 9 files changed, 113 insertions(+), 85 deletions(-) diff --git a/include/arch/arm/arch/32/mode/fastpath/fastpath.h b/include/arch/arm/arch/32/mode/fastpath/fastpath.h index 8c325e399..1d858b484 100644 --- a/include/arch/arm/arch/32/mode/fastpath/fastpath.h +++ b/include/arch/arm/arch/32/mode/fastpath/fastpath.h @@ -41,9 +41,9 @@ switchToThread_fp(tcb_t *thread, pde_t *cap_pd, pde_t stored_hw_asid) hw_asid_t hw_asid; hw_asid = pde_pde_invalid_get_stored_hw_asid(stored_hw_asid); -#ifdef ARM_HYP - vcpu_switch(thread->tcbArch.vcpu); -#endif + if (config_set(ARM_HYP)) { + vcpu_switch(thread->tcbArch.vcpu); + } armv_contextSwitch_HWASID(cap_pd, hw_asid); *armKSGlobalsFrame = thread->tcbIPCBuffer; diff --git a/include/arch/arm/arch/32/mode/machine/registerset.h b/include/arch/arm/arch/32/mode/machine/registerset.h index e2a719bac..507ee5dda 100644 --- a/include/arch/arm/arch/32/mode/machine/registerset.h +++ b/include/arch/arm/arch/32/mode/machine/registerset.h @@ -123,22 +123,24 @@ static inline word_t CONST sanitiseRegister(register_t reg, word_t v) { if (reg == CPSR) { -#ifdef ARM_HYP - switch (v & 0x1f) { - case PMODE_USER: - case PMODE_FIQ: - case PMODE_IRQ: - case PMODE_SUPERVISOR: - case PMODE_ABORT: - case PMODE_UNDEFINED: - case PMODE_SYSTEM: - return v; - case PMODE_HYPERVISOR: - default: - /* For backwards compatibility, Invalid modes revert to USER mode */ - break; + + if (config_set(ARM_HYP)) { + switch (v & 0x1f) { + case PMODE_USER: + case PMODE_FIQ: + case PMODE_IRQ: + case PMODE_SUPERVISOR: + case PMODE_ABORT: + case PMODE_UNDEFINED: + case PMODE_SYSTEM: + return v; + case PMODE_HYPERVISOR: + default: + /* For backwards compatibility, Invalid modes revert to USER mode */ + break; + } } -#endif + return (v & 0xf8000000) | CPSR_USER; } else { return v; diff --git a/include/arch/arm/arch/32/mode/machine_pl2.h b/include/arch/arm/arch/32/mode/machine_pl2.h index f34477668..6ac8dd384 100644 --- a/include/arch/arm/arch/32/mode/machine_pl2.h +++ b/include/arch/arm/arch/32/mode/machine_pl2.h @@ -133,12 +133,42 @@ static inline word_t PURE getHPFAR(void) return HPFAR; } +/** MODIFIES: */ +static inline word_t getSCTLR(void) +{ + word_t SCTLR; + asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r"(SCTLR)); + return SCTLR; +} + +/** MODIFIES: */ +static inline void setSCTLR(word_t sctlr) +{ + asm volatile ("mcr p15, 0, %0, c1, c0, 0" :: "r"(sctlr)); +} + +/** MODIFIES */ +static inline word_t getACTLR(void) +{ + word_t ACTLR; + asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r"(ACTLR)); + return ACTLR; +} + +/** MODIFIES: */ +static inline void setACTLR(word_t actlr) +{ + asm volatile ("mcr p15, 0, %0, c1, c0, 1" :: "r"(actlr)); +} + #else /* used in other files without guards */ -static inline void setCurrentPDPL2(paddr_t addr) { return; } -static inline void invalidateHypTLB(void) { return; } -static inline void writeContextIDPL2(word_t id) { return; } +static inline void setCurrentPDPL2(paddr_t pa) {} +static inline void invalidateHypTLB(void) {} +static inline void writeContextIDPL2(word_t pd) {} +static inline void writeContextIDAndPD(word_t id, word_t pd) {} +static inline paddr_t addressTranslateS1CPR(vptr_t vaddr) { return vaddr; } #endif /* !ARM_HYP */ #endif /* __ARCH_MACHINE_PL2_32_H */ diff --git a/include/arch/arm/arch/object/vcpu.h b/include/arch/arm/arch/object/vcpu.h index 5621ed474..906bf5dee 100644 --- a/include/arch/arm/arch/object/vcpu.h +++ b/include/arch/arm/arch/object/vcpu.h @@ -73,6 +73,8 @@ exception_t invokeVCPUSetTCB(vcpu_t *vcpu, tcb_t *tcb); /* used in boot.c with a guard, use a marco to avoid exposing vcpu_t */ #define vcpu_restore(x) +#define vcpu_switch(x) +static inline void VGICMaintenance(void) {} #endif /* end of !ARM_HYP */ diff --git a/include/arch/arm/armv/armv7-a/armv/context_switch.h b/include/arch/arm/armv/armv7-a/armv/context_switch.h index be8ca4055..31a9c3a6f 100644 --- a/include/arch/arm/armv/armv7-a/armv/context_switch.h +++ b/include/arch/arm/armv/armv7-a/armv/context_switch.h @@ -24,29 +24,29 @@ static inline void setHardwareASID(hw_asid_t hw_asid) static inline void armv_contextSwitch_HWASID(pde_t *cap_pd, hw_asid_t hw_asid) { -#ifdef ARM_HYP - writeContextIDAndPD(hw_asid, addrFromPPtr(cap_pd)); -#else - /* - * On ARMv7, speculative refills that complete between switching - * ASID and PD can cause TLB entries to be Tagged with the wrong - * ASID. The correct method to avoid this problem is to - * either cycle the context switch through a reserved ASID or - * through a page directory that has only global mappings. - * The reserved Page directory method has shown to perform better - * than the reserved ASID method. - * - * We do not call setCurrentPD here as we want to perform a - * minimal number of DSB and ISBs and the second PD switch we - * do does not need a DSB - */ - dsb(); - writeTTBR0(addrFromPPtr(armKSGlobalPD)); - isb(); - setHardwareASID(hw_asid); - writeTTBR0(addrFromPPtr(cap_pd)); - isb(); -#endif + if (config_set(ARM_HYP)) { + writeContextIDAndPD(hw_asid, addrFromPPtr(cap_pd)); + } else { + /* + * On ARMv7, speculative refills that complete between switching + * ASID and PD can cause TLB entries to be Tagged with the wrong + * ASID. The correct method to avoid this problem is to + * either cycle the context switch through a reserved ASID or + * through a page directory that has only global mappings. + * The reserved Page directory method has shown to perform better + * than the reserved ASID method. + * + * We do not call setCurrentPD here as we want to perform a + * minimal number of DSB and ISBs and the second PD switch we + * do does not need a DSB + */ + dsb(); + writeTTBR0(addrFromPPtr(armKSGlobalPD)); + isb(); + setHardwareASID(hw_asid); + writeTTBR0(addrFromPPtr(cap_pd)); + isb(); + } } static inline void armv_contextSwitch(pde_t* cap_pd, asid_t asid) diff --git a/include/plat/exynos5/plat/machine/devices.h b/include/plat/exynos5/plat/machine/devices.h index f15b76ade..ff7491f89 100644 --- a/include/plat/exynos5/plat/machine/devices.h +++ b/include/plat/exynos5/plat/machine/devices.h @@ -17,10 +17,10 @@ #define L2CC_PPTR 0xfff03000 #define GIC_DISTRIBUTOR_PPTR 0xfff04000 #define GIC_CONTROLLER_PPTR 0xfff05000 -#if defined(ARM_HYP) + +/* HYP mode kernel devices */ #define GIC_VCPUCTRL_PPTR 0xfff06000 #define GIC_PL400_VCPUCTRL_PPTR GIC_VCPUCTRL_PPTR -#endif #define L2CC_L2C310_PPTR L2CC_PPTR #define GIC_PL390_CONTROLLER_PPTR GIC_CONTROLLER_PPTR diff --git a/src/arch/arm/object/tcb.c b/src/arch/arm/object/tcb.c index 86a0cdf76..356878fa4 100644 --- a/src/arch/arm/object/tcb.c +++ b/src/arch/arm/object/tcb.c @@ -82,14 +82,14 @@ setMRs_fault(tcb_t *sender, tcb_t* receiver, word_t *receiveIPCBuffer) sender->tcbLookupFailure, 3); case fault_vm_fault: { -#ifdef ARM_HYP - word_t ipa, va; - va = getRestartPC(sender); - ipa = (addressTranslateS1CPR(va) & ~MASK(PAGE_BITS)) | (va & MASK(PAGE_BITS)); - setMR(receiver, receiveIPCBuffer, 0, ipa); -#else - setMR(receiver, receiveIPCBuffer, 0, getRestartPC(sender)); -#endif + if (config_set(ARM_HYP)) { + word_t ipa, va; + va = getRestartPC(sender); + ipa = (addressTranslateS1CPR(va) & ~MASK(PAGE_BITS)) | (va & MASK(PAGE_BITS)); + setMR(receiver, receiveIPCBuffer, 0, ipa); + } else { + setMR(receiver, receiveIPCBuffer, 0, getRestartPC(sender)); + } setMR(receiver, receiveIPCBuffer, 1, fault_vm_fault_get_address(sender->tcbFault)); setMR(receiver, receiveIPCBuffer, 2, diff --git a/src/arch/arm/object/vcpu.c b/src/arch/arm/object/vcpu.c index 23869090e..b9fde5333 100644 --- a/src/arch/arm/object/vcpu.c +++ b/src/arch/arm/object/vcpu.c @@ -145,8 +145,8 @@ vcpu_save(vcpu_t *cpu) int i; dsb(); /* Store VCPU state */ - MRC(SCTLR, cpu->cpx.sctlr); - MRC(ACTLR, cpu->cpx.actlr); + cpu->cpx.sctlr = getSCTLR(); + cpu->cpx.actlr = getACTLR(); /* Store GIC VCPU control state */ cpu->vgic.hcr = gic_vcpu_ctrl->hcr; @@ -164,7 +164,8 @@ vcpu_save(vcpu_t *cpu) } -static uint32_t readVCPUReg(vcpu_t *vcpu, uint32_t field) +static uint32_t +readVCPUReg(vcpu_t *vcpu, uint32_t field) { switch (field) { case 0: @@ -174,7 +175,8 @@ static uint32_t readVCPUReg(vcpu_t *vcpu, uint32_t field) return 0; } -static void writeVCPUReg(vcpu_t *vcpu, uint32_t field, uint32_t value) +static void +writeVCPUReg(vcpu_t *vcpu, uint32_t field, uint32_t value) { switch (field) { case 0: @@ -183,11 +185,9 @@ static void writeVCPUReg(vcpu_t *vcpu, uint32_t field, uint32_t value) } - void vcpu_restore(vcpu_t *cpu) { - uint32_t hcr; dsb(); if (cpu != NULL) { int i; @@ -203,27 +203,22 @@ vcpu_restore(vcpu_t *cpu) } /* Restore VCPU state */ - MCR(SCTLR, cpu->cpx.sctlr); - MCR(ACTLR, cpu->cpx.actlr); + setSCTLR(cpu->cpx.sctlr); + setACTLR(cpu->cpx.actlr); - hcr = HCR_VCPU; - MCR(HCR, hcr); + setHCR(HCR_VCPU); isb(); /* Turn on the VGIC */ gic_vcpu_ctrl->hcr = cpu->vgic.hcr; } else { - uint32_t v; /* Turn off the VGIC */ gic_vcpu_ctrl->hcr = 0; isb(); /* Stage 1 MMU off */ - v = SCTLR_DEFAULT; - MCR(SCTLR, v); - - hcr = HCR_NATIVE; - MCR(HCR, hcr); + setSCTLR(SCTLR_DEFAULT); + setHCR(HCR_NATIVE); isb(); } } diff --git a/src/plat/exynos5/machine/hardware.c b/src/plat/exynos5/machine/hardware.c index 92ab41f14..eb6ae4c33 100644 --- a/src/plat/exynos5/machine/hardware.c +++ b/src/plat/exynos5/machine/hardware.c @@ -299,12 +299,10 @@ isReservedIRQ(irq_t irq) void handleReservedIRQ(irq_t irq) { -#ifdef ARM_HYP - if (irq == INTERRUPT_VGIC_MAINTENANCE) { + if ((config_set(ARM_HYP)) && (irq == INTERRUPT_VGIC_MAINTENANCE)) { VGICMaintenance(); return; } -#endif printf("Received reserved IRQ: %d\n", (int)irq); } @@ -345,18 +343,19 @@ map_kernel_devices(void) false /* armPageCacheable */ ) ); -#if defined(ARM_HYP) - map_kernel_frame( - GIC_VCPUCTRL_PADDR, - GIC_VCPUCTRL_PPTR, - VMKernelOnly, - vm_attributes_new( - false, /* armExecuteNever */ - false, /* armParityEnabled */ - false /* armPageCacheable */ - ) - ); -#endif + + if (config_set(ARM_HYP)) { + map_kernel_frame( + GIC_VCPUCTRL_PADDR, + GIC_VCPUCTRL_PPTR, + VMKernelOnly, + vm_attributes_new( + false, /* armExecuteNever */ + false, /* armParityEnabled */ + false /* armPageCacheable */ + ) + ); + } #if defined DEBUG || defined RELEASE_PRINTF /* map kernel device: UART */