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)
This commit is contained in:
Yanyan Shen 2016-03-03 16:03:22 +11:00
parent 1cdc450cb3
commit 8e2e8db976
9 changed files with 113 additions and 85 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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 */

View file

@ -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)

View file

@ -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

View file

@ -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,

View file

@ -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();
}
}

View file

@ -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 */