From 3abf177c5b2119df1f61efe997c944e8cb96e8e6 Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Thu, 3 Mar 2016 13:49:45 +1100 Subject: [PATCH 1/7] arm_hyp: add file to contain hyp mode inline funcs machine_pl2.h: new place for hyp mode inline functions. boot.c: replace #ifdef ARM_HYP with config_set(ARM_HYP). vcpu.h, machine_pl2.h: add empty functions when ARM_HYP is not defined to pass compilation. --- include/arch/arm/arch/32/mode/machine.h | 179 ++++---------------- include/arch/arm/arch/32/mode/machine_pl2.h | 144 ++++++++++++++++ include/arch/arm/arch/object/vcpu.h | 8 +- src/arch/arm/kernel/boot.c | 18 +- 4 files changed, 192 insertions(+), 157 deletions(-) create mode 100644 include/arch/arm/arch/32/mode/machine_pl2.h diff --git a/include/arch/arm/arch/32/mode/machine.h b/include/arch/arm/arch/32/mode/machine.h index bc4e415e3..9c2d4a0e7 100644 --- a/include/arch/arm/arch/32/mode/machine.h +++ b/include/arch/arm/arch/32/mode/machine.h @@ -23,6 +23,7 @@ #include #include +#include #define MRC(cpreg, v) asm volatile("mrc " cpreg : "=r"(v)) #define MRRC(cpreg, v) asm volatile("mrrc " cpreg : "=r"(v)) @@ -57,10 +58,6 @@ #define ID_DFR0 " p15, 0, %0, c0, c1, 2" /* 32-bit RO Debug feature register */ #define ID_PFR1 " p15, 0, %0, c0, c1, 1" /* 32-bit RO CPU feature register */ -#ifdef ARM_HYP -#include -#endif - word_t PURE getRestartPC(tcb_t *thread); void setNextPC(tcb_t *thread, word_t v); @@ -122,27 +119,14 @@ static inline void flushBTAC(void) /** DONT_TRANSLATE */ static inline void writeContextID(word_t id) { -#ifndef ARM_HYP - asm volatile("mcr p15, 0, %0, c13, c0, 1" : : "r"(id)); -#else - word_t pd, vmid; - asm volatile("mrrc p15, 4, %0, %1, c2" : "=r"(pd), "=r"(vmid)); - asm volatile("mcrr p15, 4, %0, %1, c2" : : "r"(pd), "r"(id << (48-32))); -#endif - isb(); + if (config_set(ARM_HYP)) { + writeContextIDPL2(id); + } else { + asm volatile("mcr p15, 0, %0, c13, c0, 1" : : "r"(id)); + isb(); + } } -#ifdef ARM_HYP -/** MODIFIES: [*] */ -static inline void writeContextIDAndPD(word_t id, word_t pd) -{ - asm volatile("mcrr p15, 6, %0, %1, c2" : : "r"(pd), "r"(id << (48-32))); - isb(); -} -#endif - - -#ifndef ARM_HYP /* Address space control */ /** MODIFIES: [*] */ /** DONT_TRANSLATE */ @@ -154,73 +138,23 @@ static inline void writeTTBR0(paddr_t addr) asm volatile("mcr p15, 0, %0, c2, c0, 0" : : "r"((addr & 0xffffe000) | 0x18)); } -#endif /* ARM_HYP */ static inline void setCurrentPD(paddr_t addr) { -#ifndef ARM_HYP /* Mask supplied address (retain top 19 bits). Set the lookup cache bits: * outer write-back cacheable, no allocate on write, inner non-cacheable. */ /* Before changing the PD ensure all memory stores have completed */ - dsb(); - writeTTBR0(addr); - /* Ensure the PD switch completes before we do anything else */ - isb(); -#else - word_t pd, vmid; - asm volatile("mrrc p15, 6, %0, %1, c2" : "=r"(pd), "=r"(vmid)); - dsb(); - asm volatile("mcrr p15, 6, %0, %1, c2" : : "r"(addr), "r"(vmid)); - isb(); -#endif + if (config_set(ARM_HYP)) { + setCurrentPDPL2(addr); + } else { + dsb(); + writeTTBR0(addr); + /* Ensure the PD switch completes before we do anything else */ + isb(); + } } -/** MODIFIES: [*] */ -static inline void setCurrentHypPD(paddr_t addr) -{ - word_t zero = 0; - dsb(); - asm volatile("mcrr p15, 4, %0, %1, c2" : : "r"(addr), "r"(zero)); - isb(); -} - -/** MODIFIES: [*] */ -static inline void setVTCR(word_t r) -{ - dsb(); - asm volatile("mcr p15, 4, %0, c2, c1, 2" : : "r"(r)); - isb(); -} - -/** MODIFIES: [*] */ -static inline void setHCR(word_t r) -{ - dsb(); - asm volatile("mcr p15, 4, %0, c1, c1, 0" : : "r"(r)); - isb(); -} - - - - -/** MODIFIES: [*] */ -static inline void setHMAIR(word_t hmair0, word_t hmair1) -{ - asm volatile("mcr p15, 4, %0, c10, c2, 0" : : "r"(hmair0)); - asm volatile("mcr p15, 4, %0, c10, c2, 1" : : "r"(hmair1)); - isb(); -} -/** MODIFIES: [*] */ -static inline void setMAIR(word_t hmair0, word_t hmair1) -{ - asm volatile("mcr p15, 0, %0, c10, c2, 0" : : "r"(hmair0)); - asm volatile("mcr p15, 0, %0, c10, c2, 1" : : "r"(hmair1)); - isb(); -} - - - /* TLB control */ /** MODIFIES: [*] */ /** DONT_TRANSLATE */ @@ -236,35 +170,28 @@ static inline void invalidateTLB(void) /** DONT_TRANSLATE */ static inline void invalidateTLB_ASID(hw_asid_t hw_asid) { -#ifdef ARM_HYP - invalidateTLB(); -#else - dsb(); - asm volatile("mcr p15, 0, %0, c8, c7, 2" : : "r"(hw_asid)); - dsb(); - isb(); -#endif + if (config_set(ARM_HYP)) { + invalidateTLB(); + } else { + dsb(); + asm volatile("mcr p15, 0, %0, c8, c7, 2" : : "r"(hw_asid)); + dsb(); + isb(); + } } + /** MODIFIES: [*] */ /** DONT_TRANSLATE */ static inline void invalidateTLB_VAASID(word_t mva_plus_asid) { -#ifdef ARM_HYP - invalidateTLB(); -#else - dsb(); - asm volatile("mcr p15, 0, %0, c8, c7, 1" : : "r"(mva_plus_asid)); - dsb(); - isb(); -#endif -} -/** MODIFIES: [*] */ -static inline void invalidateHypTLB(void) -{ - dsb(); - asm volatile("mcr p15, 4, %0, c8, c7, 0" : : "r"(0)); - dsb(); - isb(); + if (config_set(ARM_HYP)) { + invalidateTLB(); + } else { + dsb(); + asm volatile("mcr p15, 0, %0, c8, c7, 1" : : "r"(mva_plus_asid)); + dsb(); + isb(); + } } /** MODIFIES: [*] */ @@ -395,48 +322,6 @@ static inline word_t PURE getFAR(void) return FAR; } -#ifdef ARM_HYP -/** MODIFIES: */ -static inline paddr_t PURE addressTranslateS1CPR(vptr_t vaddr) -{ - uint64_t ipa; - asm volatile ("mcr p15, 0, %0, c7, c8, 0" :: "r"(vaddr)); - isb(); - asm volatile ("mrrc p15, 0, %Q0, %R0, c7" : "=r"(ipa)); - - return ipa; -} -/** MODIFIES: */ -static inline word_t PURE getHSR(void) -{ - word_t HSR; - asm volatile("mrc p15, 4, %0, c5, c2, 0" : "=r"(HSR)); - return HSR; -} -/** MODIFIES: */ -static inline word_t PURE getHDFAR(void) -{ - word_t HDFAR; - asm volatile("mrc p15, 4, %0, c6, c0, 0" : "=r"(HDFAR)); - return HDFAR; -} -/** MODIFIES: */ -static inline word_t PURE getHIFAR(void) -{ - word_t HIFAR; - asm volatile("mrc p15, 4, %0, c6, c0, 2" : "=r"(HIFAR)); - return HIFAR; -} -/** MODIFIES: */ -static inline word_t PURE getHPFAR(void) -{ - word_t HPFAR; - asm volatile("mrc p15, 4, %0, c6, c0, 4" : "=r"(HPFAR)); - return HPFAR; -} - -#endif - #endif /* __ASSEMBLER__ */ #endif /* __ARCH_MACHINE_32_H */ diff --git a/include/arch/arm/arch/32/mode/machine_pl2.h b/include/arch/arm/arch/32/mode/machine_pl2.h new file mode 100644 index 000000000..f34477668 --- /dev/null +++ b/include/arch/arm/arch/32/mode/machine_pl2.h @@ -0,0 +1,144 @@ +/* + * Copyright 2014, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#ifndef __ARCH_MACHINE_PL2_32_H +#define __ARCH_MACHINE_PL2_32_H + +#include + +#ifdef ARM_HYP + +/** MODIFIES: [*] */ +/** DONT_TRANSLATE */ +static inline void writeContextIDPL2(word_t id) +{ + word_t pd, vmid; + asm volatile("mrrc p15, 4, %0, %1, c2" : "=r"(pd), "=r"(vmid)); + asm volatile("mcrr p15, 4, %0, %1, c2" : : "r"(pd), "r"(id << (48-32))); + isb(); +} + +/** MODIFIES: [*] */ +static inline void writeContextIDAndPD(word_t id, word_t pd) +{ + asm volatile("mcrr p15, 6, %0, %1, c2" : : "r"(pd), "r"(id << (48-32))); + isb(); +} + +static inline void setCurrentPDPL2(paddr_t addr) +{ + word_t pd, vmid; + asm volatile("mrrc p15, 6, %0, %1, c2" : "=r"(pd), "=r"(vmid)); + dsb(); + asm volatile("mcrr p15, 6, %0, %1, c2" : : "r"(addr), "r"(vmid)); + isb(); +} + +/** MODIFIES: [*] */ +static inline void setCurrentHypPD(paddr_t addr) +{ + word_t zero = 0; + dsb(); + asm volatile("mcrr p15, 4, %0, %1, c2" : : "r"(addr), "r"(zero)); + isb(); +} + +/** MODIFIES: [*] */ +static inline void setVTCR(word_t r) +{ + dsb(); + asm volatile("mcr p15, 4, %0, c2, c1, 2" : : "r"(r)); + isb(); +} + +/** MODIFIES: [*] */ +static inline void setHCR(word_t r) +{ + dsb(); + asm volatile("mcr p15, 4, %0, c1, c1, 0" : : "r"(r)); + isb(); +} + +/** MODIFIES: [*] */ +static inline void setHMAIR(word_t hmair0, word_t hmair1) +{ + asm volatile("mcr p15, 4, %0, c10, c2, 0" : : "r"(hmair0)); + asm volatile("mcr p15, 4, %0, c10, c2, 1" : : "r"(hmair1)); + isb(); +} +/** MODIFIES: [*] */ +static inline void setMAIR(word_t hmair0, word_t hmair1) +{ + asm volatile("mcr p15, 0, %0, c10, c2, 0" : : "r"(hmair0)); + asm volatile("mcr p15, 0, %0, c10, c2, 1" : : "r"(hmair1)); + isb(); +} + +/** MODIFIES: [*] */ +static inline void invalidateHypTLB(void) +{ + dsb(); + asm volatile("mcr p15, 4, %0, c8, c7, 0" : : "r"(0)); + dsb(); + isb(); +} + +/** MODIFIES: */ +static inline paddr_t PURE addressTranslateS1CPR(vptr_t vaddr) +{ + uint64_t ipa; + asm volatile ("mcr p15, 0, %0, c7, c8, 0" :: "r"(vaddr)); + isb(); + asm volatile ("mrrc p15, 0, %Q0, %R0, c7" : "=r"(ipa)); + + return ipa; +} + +/** MODIFIES: */ +static inline word_t PURE getHSR(void) +{ + word_t HSR; + asm volatile("mrc p15, 4, %0, c5, c2, 0" : "=r"(HSR)); + return HSR; +} + +/** MODIFIES: */ +static inline word_t PURE getHDFAR(void) +{ + word_t HDFAR; + asm volatile("mrc p15, 4, %0, c6, c0, 0" : "=r"(HDFAR)); + return HDFAR; +} + +/** MODIFIES: */ +static inline word_t PURE getHIFAR(void) +{ + word_t HIFAR; + asm volatile("mrc p15, 4, %0, c6, c0, 2" : "=r"(HIFAR)); + return HIFAR; +} + +/** MODIFIES: */ +static inline word_t PURE getHPFAR(void) +{ + word_t HPFAR; + asm volatile("mrc p15, 4, %0, c6, c0, 4" : "=r"(HPFAR)); + return HPFAR; +} + +#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; } + +#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 e9a0b64e2..5621ed474 100644 --- a/include/arch/arm/arch/object/vcpu.h +++ b/include/arch/arm/arch/object/vcpu.h @@ -69,5 +69,11 @@ exception_t invokeVCPUReadReg(vcpu_t *vcpu, uint32_t field); exception_t invokeVCPUInjectIRQ(vcpu_t *vcpu, int index, int group, int priority, int irq); exception_t invokeVCPUSetTCB(vcpu_t *vcpu, tcb_t *tcb); -#endif /* ARM_HYP */ +#else /* end of ARM_HYP */ + +/* used in boot.c with a guard, use a marco to avoid exposing vcpu_t */ +#define vcpu_restore(x) + +#endif /* end of !ARM_HYP */ + #endif /* __ARCH_OBJECT_VCPU_H */ diff --git a/src/arch/arm/kernel/boot.c b/src/arch/arm/kernel/boot.c index 60b964001..c98090aa9 100644 --- a/src/arch/arm/kernel/boot.c +++ b/src/arch/arm/kernel/boot.c @@ -131,9 +131,9 @@ init_irqs(cap_t root_cnode_cap) setIRQState(IRQInactive, i); } setIRQState(IRQTimer, KERNEL_TIMER_IRQ); -#ifdef ARM_HYP - setIRQState(IRQReserved, INTERRUPT_VGIC_MAINTENANCE); -#endif + if (config_set(ARM_HYP)) { + setIRQState(IRQReserved, INTERRUPT_VGIC_MAINTENANCE); + } /* provide the IRQ control cap */ write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IRQ_CTRL), cap_irq_control_cap_new()); @@ -146,9 +146,9 @@ BOOT_CODE static void init_cpu(void) { activate_global_pd(); -#ifdef ARM_HYP - vcpu_restore(NULL); -#endif + if (config_set(ARM_HYP)) { + vcpu_restore(NULL); + } } /* This and only this function initialises the platform. It does NOT initialise any kernel state. */ @@ -326,9 +326,9 @@ try_init_kernel( * everything to PoC */ cleanInvalidateL1Caches(); invalidateTLB(); -#ifdef ARM_HYP - invalidateHypTLB(); -#endif + if (config_set(ARM_HYP)) { + invalidateHypTLB(); + } #if CONFIG_MAX_NUM_TRACE_POINTS > 0 armv_init_ccnt(); From 1cdc450cb38896db9ededeaa888bb1ab2f62bdd1 Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Thu, 3 Mar 2016 15:57:13 +1100 Subject: [PATCH 2/7] arm_hyp: remove unused function declaration. remove map_hypervisor_devices function declaration. --- include/plat/apq8064/plat/machine/hardware.h | 3 --- include/plat/exynos5/plat/machine/hardware.h | 3 --- 2 files changed, 6 deletions(-) diff --git a/include/plat/apq8064/plat/machine/hardware.h b/include/plat/apq8064/plat/machine/hardware.h index 9ece2b4dd..c4cfab5a7 100644 --- a/include/plat/apq8064/plat/machine/hardware.h +++ b/include/plat/apq8064/plat/machine/hardware.h @@ -65,9 +65,6 @@ p_region_t get_avail_p_reg(word_t i); int get_num_dev_p_regs(void); p_region_t get_dev_p_reg(word_t i); void map_kernel_devices(void); -#ifdef ARM_HYP -void map_hypervisor_devices(void); -#endif /* ARM_HYP */ bool_t CONST isReservedIRQ(irq_t irq); void handleReservedIRQ(irq_t irq); diff --git a/include/plat/exynos5/plat/machine/hardware.h b/include/plat/exynos5/plat/machine/hardware.h index b152253d2..04164fcea 100644 --- a/include/plat/exynos5/plat/machine/hardware.h +++ b/include/plat/exynos5/plat/machine/hardware.h @@ -73,9 +73,6 @@ p_region_t get_avail_p_reg(word_t i); int get_num_dev_p_regs(void); p_region_t get_dev_p_reg(word_t i); void map_kernel_devices(void); -#ifdef ARM_HYP -void map_hypervisor_devices(void); -#endif /* ARM_HYP */ bool_t CONST isReservedIRQ(irq_t irq); void handleReservedIRQ(irq_t irq); From 8e2e8db9763fdaa54f20ac7c6a215db77bc2d4c2 Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Thu, 3 Mar 2016 16:03:22 +1100 Subject: [PATCH 3/7] 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 */ From 24747dc5591302eb81065951400b4e8806d6a01a Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Thu, 3 Mar 2016 16:23:21 +1100 Subject: [PATCH 4/7] arm_hyp: remove unused macros --- src/arch/arm/object/vcpu.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/arch/arm/object/vcpu.c b/src/arch/arm/object/vcpu.c index b9fde5333..b3c6fc0d5 100644 --- a/src/arch/arm/object/vcpu.c +++ b/src/arch/arm/object/vcpu.c @@ -51,30 +51,6 @@ | HCR_TAC | HCR_SWIO) #define HCR_VCPU (HCR_COMMON) - -/* 1471 */ -#define SCTLR "p15, 0, %0, c1, c0, 0" -#define ACTLR "p15, 0, %0, c1, c0, 1" -#define HSCTLR "p15, 4, %0, c1, c0, 0" -#define HCR "p15, 4, %0, c1, c1, 0" - -/* VA->IPA */ -#define ATS1CPR "p15, 0, %0, c7, c8, 0" -#define ATS1CPW "p15, 0, %0, c7, c8, 1" -#define ATS1CUR "p15, 0, %0, c7, c8, 2" -#define ATS1CUW "p15, 0, %0, c7, c8, 3" -/* VA->PA */ -#define ATS12NSOPR "p15, 0, %0, c7, c8, 4" -#define ATS12NSOPW "p15, 0, %0, c7, c8, 5" -#define ATS12NSOUR "p15, 0, %0, c7, c8, 6" -#define ATS12NSOUW "p15, 0, %0, c7, c8, 7" -/* VA(hyp)-> PA */ -#define ATS1HR "p15, 4, %0, c7, c8, 0" -#define ATS1HW "p15, 4, %0, c7, c8, 1" - -#define PAR32 "p15, 0, %0, c7, c4, 0" -#define PAR64 "p15, 0, %Q, %R, c7" - #define SCTLR_DEFAULT 0xc5187c #define ACTLR_DEFAULT 0x40 From b0b5d5aaab9406ce9a1ab92baf39b462807c0f90 Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Mon, 14 Mar 2016 15:54:00 +1100 Subject: [PATCH 5/7] arm/tk1: add support for Nvidia Tegra K1 board --- Kconfig | 8 + Makefile | 2 +- include/arch/arm/arch/32/mode/machine.h | 2 + include/plat/tk1/autoconf.h | 94 +++++++ include/plat/tk1/plat/Makefile | 11 + include/plat/tk1/plat/machine.h | 226 +++++++++++++++++ include/plat/tk1/plat/machine/Makefile | 13 + include/plat/tk1/plat/machine/debug_helpers.h | 17 ++ include/plat/tk1/plat/machine/devices.h | 108 ++++++++ include/plat/tk1/plat/machine/hardware.bf | 12 + include/plat/tk1/plat/machine/hardware.h | 87 +++++++ include/plat/tk1/plat/machine/io.h | 26 ++ src/plat/tk1/Makefile | 11 + src/plat/tk1/linker.lds | 84 +++++++ src/plat/tk1/machine/Makefile | 21 ++ src/plat/tk1/machine/hardware.c | 231 ++++++++++++++++++ src/plat/tk1/machine/io.c | 48 ++++ src/plat/tk1/machine/l2cache.c | 18 ++ 18 files changed, 1018 insertions(+), 1 deletion(-) create mode 100644 include/plat/tk1/autoconf.h create mode 100644 include/plat/tk1/plat/Makefile create mode 100644 include/plat/tk1/plat/machine.h create mode 100644 include/plat/tk1/plat/machine/Makefile create mode 100644 include/plat/tk1/plat/machine/debug_helpers.h create mode 100644 include/plat/tk1/plat/machine/devices.h create mode 100644 include/plat/tk1/plat/machine/hardware.bf create mode 100644 include/plat/tk1/plat/machine/hardware.h create mode 100644 include/plat/tk1/plat/machine/io.h create mode 100644 src/plat/tk1/Makefile create mode 100644 src/plat/tk1/linker.lds create mode 100644 src/plat/tk1/machine/Makefile create mode 100644 src/plat/tk1/machine/hardware.c create mode 100644 src/plat/tk1/machine/io.c create mode 100644 src/plat/tk1/machine/l2cache.c diff --git a/Kconfig b/Kconfig index 0649887fd..61310b08a 100644 --- a/Kconfig +++ b/Kconfig @@ -218,6 +218,14 @@ menu "seL4 System" depends on ARM_CORTEX_A15 help Support for ALLWINNERA20 platform (CUBIETRUCK). + + config PLAT_TK1 + bool "Jetson (Tegra K1)" + depends on ARCH_ARM + depends on ARM_CORTEX_A15 + help + Support for Tegra K1 platform + endchoice source "$KERNEL_PATH/src/arch/arm/Kconfig" diff --git a/Makefile b/Makefile index bc18d69fb..c01f71f78 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ SEL4_ARCH_LIST:=aarch32 ia32 ARCH_LIST:=arm x86 CPU_LIST:=arm1136jf-s ixp420 cortex-a7 cortex-a8 cortex-a9 cortex-a15 -PLAT_LIST:=imx31 pc99 ixp420 omap3 am335x exynos4 exynos5 imx6 imx7 apq8064 zynq7000 allwinnerA20 +PLAT_LIST:=imx31 pc99 ixp420 omap3 am335x exynos4 exynos5 imx6 imx7 apq8064 zynq7000 allwinnerA20 tk1 ARMV_LIST:=armv6 armv7-a ifndef SOURCE_ROOT diff --git a/include/arch/arm/arch/32/mode/machine.h b/include/arch/arm/arch/32/mode/machine.h index 5e4b9b5be..b5eea1201 100644 --- a/include/arch/arm/arch/32/mode/machine.h +++ b/include/arch/arm/arch/32/mode/machine.h @@ -209,6 +209,8 @@ static inline void cleanByVA_PoU(vptr_t vaddr, paddr_t paddr) asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r"(vaddr)); #elif defined(PLAT_IMX7) asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r"(vaddr)); +#elif defined(PLAT_TK1) + asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r"(vaddr)); #else asm volatile("mcr p15, 0, %0, c7, c11, 1" : : "r"(vaddr)); #endif diff --git a/include/plat/tk1/autoconf.h b/include/plat/tk1/autoconf.h new file mode 100644 index 000000000..f5253c6f9 --- /dev/null +++ b/include/plat/tk1/autoconf.h @@ -0,0 +1,94 @@ +/* + * Automatically generated C config: don't edit + * Project Configuration + * Mon Mar 14 15:34:46 2016 + */ +#define AUTOCONF_INCLUDED +#define CONFIG_LIB_SEL4_SIMPLE 1 +#define CONFIG_IRQ_REPORTING 1 +#define CONFIG_HAVE_ARCH_TIMER 1 +#define CONFIG_HAVE_CACHE 1 +#define CONFIG_LIB_SEL4_DEBUG 1 +#define CONFIG_LIB_ELF 1 +#define CONFIG_USER_DEBUG_BUILD 1 +#define CONFIG_HAVE_LIB_SEL4_MUSLC_SYS 1 +#define CONFIG_HAVE_LIB_SEL4 1 +#define CONFIG_LIB_SEL4_VKA 1 +#define CONFIG_HAVE_CRT 1 +#define CONFIG_TESTPRINTER_HALT_ON_TEST_FAILURE 1 +#define CONFIG_TIMER_TICK_MS 2 +#define CONFIG_KERNEL_CFLAGS "" +#define CONFIG_LIB_SEL4_PLAT_SUPPORT_SEL4_START 1 +#define CONFIG_COLOUR_PRINTING 1 +#define CONFIG_IMAGE_ELF 1 +#define CONFIG_HAVE_LIBC 1 +#define CONFIG_USER_COMPILER "" +#define CONFIG_LIB_SEL4_PLAT_SUPPORT 1 +#define CONFIG_WORD_SIZE 32 +#define CONFIG_MAX_NUM_BOOTINFO_DEVICE_REGIONS 199 +#define CONFIG_APP_TESTS 1 +#define CONFIG_MAX_NUM_TRACE_POINTS 0 +#define CONFIG_SEL4UTILS_STACK_SIZE 65536 +#define CONFIG_HAVE_LIB_SEL4_ALLOCMAN 1 +#define CONFIG_PLAT_TK1 1 +#define CONFIG_FASTPATH 1 +#define CONFIG_ARM_CORTEX_A15 1 +#define CONFIG_LIB_SEL4_VKA_DEBUG_LIVE_OBJS_SZ 0 +#define CONFIG_SEL4UTILS_CSPACE_SIZE_BITS 16 +#define CONFIG_DOMAIN_SCHEDULE "" +#define CONFIG_LIB_SEL4 1 +#define CONFIG_LIBSEL4DEBUG_FUNCTION_INSTRUMENTATION_NONE 1 +#define CONFIG_LIB_SEL4_UTILS 1 +#define CONFIG_LIB_SEL4_VSPACE 1 +#define CONFIG_LIB_PLATSUPPORT 1 +#define CONFIG_LIB_SEL4_ALLOCMAN 1 +#define CONFIG_HAVE_LIB_SEL4_SIMPLE_DEFAULT 1 +#define CONFIG_LIB_SEL4_TEST 1 +#define CONFIG_LIB_ELFLOADER 1 +#define CONFIG_HAVE_LIB_SEL4_VSPACE 1 +#define CONFIG_MAX_NUM_BOOTINFO_UNTYPED_CAPS 167 +#define CONFIG_LIB_SEL4_VKA_DEBUG_LIVE_SLOTS_SZ 0 +#define CONFIG_CROSS_COMPILER_PREFIX "arm-none-eabi-" +#define CONFIG_LIB_SEL4_INLINE_INVOCATIONS 1 +#define CONFIG_LIB_SEL4_MUSLC_SYS 1 +#define CONFIG_HAVE_LIB_SEL4_TEST 1 +#define CONFIG_LIB_MUSL_C 1 +#define CONFIG_MAX_NUM_WORK_UNITS_PER_PREEMPTION 100 +#define CONFIG_ARCH_ARM_V7A 1 +#define CONFIG_USER_CFLAGS "" +#define CONFIG_HAVE_LIB_SEL4_DEBUG 1 +#define CONFIG_HAVE_LIB_SEL4_SIMPLE_STABLE 1 +#define CONFIG_LIB_SEL4_SIMPLE_DEFAULT 1 +#define CONFIG_DEBUG_BUILD 1 +#define CONFIG_LIB_UTILS 1 +#define CONFIG_OPTIMISATION_O2 1 +#define CONFIG_HAVE_LIB_CPIO 1 +#define CONFIG_HAVE_LIB_SEL4_VKA 1 +#define CONFIG_LIB_SEL4_HAVE_REGISTER_STUBS 1 +#define CONFIG_HAVE_LIB_SEL4_PLAT_SUPPORT 1 +#define CONFIG_USER_EXTRA_CFLAGS "" +#define CONFIG_HAVE_LIB_SEL4_SIMPLE 1 +#define CONFIG_ARCH_ARM 1 +#define CONFIG_HAVE_LIB_ELF 1 +#define CONFIG_HAVE_LIB_PLATSUPPORT 1 +#define CONFIG_ARM_MONITOR_MODE 1 +#define CONFIG_NUM_DOMAINS 1 +#define CONFIG_USER_DEBUG_INFO 1 +#define CONFIG_HAVE_LIB_UTILS 1 +#define CONFIG_USER_OPTIMISATION_O2 1 +#define CONFIG_LIB_CPIO 1 +#define CONFIG_RETYPE_FAN_OUT_LIMIT 256 +#define CONFIG_ROOT_CNODE_SIZE_BITS 12 +#define CONFIG_NUM_PRIORITIES 256 +#define CONFIG_TESTPRINTER_REGEX ".*" +#define CONFIG_APP_SEL4TEST 1 +#define CONFIG_HAVE_LIB_SEL4_UTILS 1 +#define CONFIG_LIB_SEL4_PLAT_SUPPORT_USE_SEL4_DEBUG_PUTCHAR 1 +#define CONFIG_KERNEL_COMPILER "" +#define CONFIG_TIME_SLICE 5 +#define CONFIG_ARCH_AARCH32 1 +#define CONFIG_KERNEL_EXTRA_CPPFLAGS "" +#define CONFIG_LIBSEL4DEBUG_ALLOC_BUFFER_ENTRIES 128 +#define CONFIG_LIB_SEL4_SIMPLE_STABLE 1 +#define CONFIG_LIB_SEL4_MUSLC_SYS_MORECORE_BYTES 1048576 +#define CONFIG_ARM_MONITOR_HOOK 1 diff --git a/include/plat/tk1/plat/Makefile b/include/plat/tk1/plat/Makefile new file mode 100644 index 000000000..0612070ab --- /dev/null +++ b/include/plat/tk1/plat/Makefile @@ -0,0 +1,11 @@ +# +# Copyright 2016, General Dynamics C4 Systems +# +# This software may be distributed and modified according to the terms of +# the GNU General Public License version 2. Note that NO WARRANTY is provided. +# See "LICENSE_GPLv2.txt" for details. +# +# @TAG(GD_GPL) +# + +include ${SOURCE_ROOT}/include/plat/${PLAT}/plat/machine/Makefile diff --git a/include/plat/tk1/plat/machine.h b/include/plat/tk1/plat/machine.h new file mode 100644 index 000000000..5e74df6f2 --- /dev/null +++ b/include/plat/tk1/plat/machine.h @@ -0,0 +1,226 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#ifndef __PLAT_MACHINE_H +#define __PLAT_MACHINE_H + +#include + +#define N_INTERRUPTS 192 + +enum IRQConstants { + INTERRUPT_SGI_0 = 0, + INTERRUPT_SGI_1 = 1, + INTERRUPT_SGI_2 = 2, + INTERRUPT_SGI_3 = 3, + INTERRUPT_SGI_4 = 4, + INTERRUPT_SGI_5 = 5, + INTERRUPT_SGI_6 = 6, + INTERRUPT_SGI_7 = 7, + INTERRUPT_SGI_8 = 8, + INTERRUPT_SGI_9 = 9, + INTERRUPT_SGI_10 = 10, + INTERRUPT_SGI_11 = 11, + INTERRUPT_SGI_12 = 12, + INTERRUPT_SGI_13 = 13, + INTERRUPT_SGI_14 = 14, + INTERRUPT_SGI_15 = 15, + INTERRUPT_PPI_0 = 16, + INTERRUPT_PPI_1 = 17, + INTERRUPT_PPI_2 = 18, + INTERRUPT_PPI_3 = 19, + INTERRUPT_PPI_4 = 20, + INTERRUPT_PPI_5 = 21, + INTERRUPT_PPI_6 = 22, + INTERRUPT_PPI_7 = 23, + INTERRUPT_PPI_8 = 24, + INTERRUPT_PPI_9 = 25, + INTERRUPT_PPI_10 = 26, + INTERRUPT_PPI_11 = 27, + INTERRUPT_PPI_12 = 28, + INTERRUPT_PPI_13 = 29, + INTERRUPT_PPI_14 = 30, + INTERRUPT_PPI_15 = 31, + INTERRUPT_TMR2 = 32, + INTERRUPT_TMR1 = 33, + INTERRUPT_RTC = 34, + INTERRUPT_CEC = 35, + INTERRUPT_SHR_SEM_INBOX_FULL = 36, + INTERRUPT_SHR_SEM_INBOX_EMPTY = 37, + INTERRUPT_SHR_SEM_OUTBOX_FULL = 38, + INTERRUPT_SHR_SEM_OUTBOX_EMPTY = 39, + INTERRUPT_VDE_UCQ = 40, + INTERRUPT_VDE_SYNC_TOKEN = 41, + INTERRUPT_VDE_BSEV = 42, + INTERRUPT_VDE_BSEA = 43, + INTERRUPT_VDE_SXE = 44, + INTERRUPT_SATA_RX_STAT = 45, + INTERRUPT_SDMMC1 = 46, + INTERRUPT_SDMMC2 = 47, +// RESERVED = 48, + INTERRUPT_VDE = 49, + INTERRUPT_AVP_UCQ = 50, + INTERRUPT_SDMMC3 = 51, + INTERRUPT_USB = 52, + INTERRUPT_KEYPAD = 53, + INTERRUPT_USB2 = 54, +// RESERVED = 55, + INTERRUPT_SATA_CTL = 56, +// RESERVED = 57, + INTERRUPT_VCP = 58, + INTERRUPT_APB_DMA_CPU = 59, + INTERRUPT_AHB_DMA_CPU = 60, + INTERRUPT_ARB_SEM_GNT_CPU = 61, + INTERRUPT_OWR = 62, + INTERRUPT_SDMMC4 = 63, + INTERRUPT_GPIO1 = 64, + INTERRUPT_GPIO2 = 65, + INTERRUPT_GPIO3 = 66, + INTERRUPT_GPIO4 = 67, + INTERRUPT_UARTA = 68, + INTERRUPT_UARTB = 69, + INTERRUPT_I2C = 70, + INTERRUPT_USB3_HOST = 71, + INTERRUPT_USB3_HOST_SMI = 72, + INTERRUPT_TMR3 = 73, + INTERRUPT_TMR4 = 74, + INTERRUPT_USB3_HOST_PME = 75, + INTERRUPT_USB3_DEV_HOST = 76, + INTERRUPT_ACTMON = 77, + INTERRUPT_UARTC = 78, + INTERRUPT_HSI = 79, + INTERRUPT_THERMAL = 80, + INTERRUPT_XUSB_PADCTL = 81, + INTERRUPT_TSEC = 82, + INTERRUPT_EDP = 83, + INTERRUPT_VFIR = 84, + INTERRUPT_I2C5 = 85, + INTERRUPT_STAT_MON = 86, + INTERRUPT_GPIO5 = 87, + INTERRUPT_USB3_DEV_SMI = 88, + INTERRUPT_USB3_DEV_PME = 89, + INTERRUPT_SE = 90, + INTERRUPT_SPI1 = 91, + INTERRUPT_APB_DMA_COP = 92, + INTERRUPT_AHB_DMA_COP = 93, + INTERRUPT_CLDVFS = 94, + INTERRUPT_I2C6 = 95, + INTERRUPT_HOST1X_SYNCPT_COP = 96, + INTERRUPT_HOST1X_SYNCPT_CPU = 97, + INTERRUPT_HOST1X_GEN_COP = 98, + INTERRUPT_HOST1X_GEN_CPU = 99, + INTERRUPT_MSENC = 100, + INTERRUPT_VI = 101, + INTERRUPT_ISPB = 102, + INTERRUPT_ISP = 103, + INTERRUPT_VIC = 104, + INTERRUPT_DISPLAY = 105, + INTERRUPT_DISPLAYB = 106, + INTERRUPT_HDMI = 107, + INTERRUPT_SOR = 108, + INTERRUPT_MC = 109, + INTERRUPT_EMC = 110, + INTERRUPT_SPI6 = 111, +// RESERVED = 112, + INTERRUPT_HDA = 113, + INTERRUPT_SPI2 = 114, + INTERRUPT_SPI3 = 115, + INTERRUPT_I2C2 = 116, +// RESERVED = 117, + INTERRUPT_PMU_EXT = 118, + INTERRUPT_GPIO6 = 119, +// RESERVED = 120, + INTERRUPT_GPIO7 = 121, + INTERRUPT_UARTD = 122, +// RESERVED = 123, + INTERRUPT_I2C3 = 124, +// RESERVED = 125, +// RESERVED = 126, + INTERRUPT_SW = 127, + INTERRUPT_SNOR = 128, + INTERRUPT_USB3 = 129, + INTERRUPT_PCIE_INT = 130, + INTERRUPT_PCIE_MSI = 131, + INTERRUPT_PCIE_WAKE = 132, + INTERRUPT_AVP_CACHE = 133, +// RESERVED = 134, + INTERRUPT_AUDIO_CLUSTER = 135, + INTERRUPT_APB_DMA_CH0 = 136, + INTERRUPT_APB_DMA_CH1 = 137, + INTERRUPT_APB_DMA_CH2 = 138, + INTERRUPT_APB_DMA_CH3 = 139, + INTERRUPT_APB_DMA_CH4 = 140, + INTERRUPT_APB_DMA_CH5 = 141, + INTERRUPT_APB_DMA_CH6 = 142, + INTERRUPT_APB_DMA_CH7 = 143, + INTERRUPT_APB_DMA_CH8 = 144, + INTERRUPT_APB_DMA_CH9 = 145, + INTERRUPT_APB_DMA_CH10 = 146, + INTERRUPT_APB_DMA_CH11 = 147, + INTERRUPT_APB_DMA_CH12 = 148, + INTERRUPT_APB_DMA_CH13 = 149, + INTERRUPT_APB_DMA_CH14 = 150, + INTERRUPT_APB_DMA_CH15 = 151, + INTERRUPT_I2C4 = 152, + INTERRUPT_TMR5 = 153, + INTERRUPT_HIER_GROUP1_COP = 154, + INTERRUPT_WDT_CPU = 155, + INTERRUPT_WDT_AVP = 156, + INTERRUPT_GPIO8 = 157, + INTERRUPT_CAR = 158, + INTERRUPT_HIER_GROUP1_CPU = 159, + INTERRUPT_APB_DMA_CH16 = 160, + INTERRUPT_APB_DMA_CH17 = 161, + INTERRUPT_APB_DMA_CH18 = 162, + INTERRUPT_APB_DMA_CH19 = 163, + INTERRUPT_APB_DMA_CH20 = 164, + INTERRUPT_APB_DMA_CH21 = 165, + INTERRUPT_APB_DMA_CH22 = 166, + INTERRUPT_APB_DMA_CH23 = 167, + INTERRUPT_APB_DMA_CH24 = 168, + INTERRUPT_APB_DMA_CH25 = 169, + INTERRUPT_APB_DMA_CH26 = 170, + INTERRUPT_APB_DMA_CH27 = 171, + INTERRUPT_APB_DMA_CH28 = 172, + INTERRUPT_APB_DMA_CH29 = 173, + INTERRUPT_APB_DMA_CH30 = 174, + INTERRUPT_APB_DMA_CH31 = 175, + INTERRUPT_CPU0_PMU = 176, + INTERRUPT_CPU1_PMU = 177, + INTERRUPT_CPU2_PMU = 178, + INTERRUPT_CPU3_PMU = 179, + INTERRUPT_SDMMC1_SYS = 180, + INTERRUPT_SDMMC2_SYS = 181, + INTERRUPT_SDMMC3_SYS = 182, + INTERRUPT_SDMMC4_SYS = 183, + INTERRUPT_TMR6 = 184, + INTERRUPT_TMR7 = 185, + INTERRUPT_TMR8 = 186, + INTERRUPT_TMR9 = 187, + INTERRUPT_TMR0 = 188, + INTERRUPT_GPU = 189, + INTERRUPT_GPU_NONSTALL = 190, + ARDPAUX = 191, + maxIRQ = 192 +} platform_interrupt_t; + +#define INTERRUPT_S_PGPT INTERRUPT_PPI_13 +#define INTERRUPT_NS_PGPT INTERRUPT_PPI_14 +#define INTERRUPT_VGPT INTERRUPT_PPI_11 +#define INTERRUPT_HGPT INTERRUPT_PPI_10 + +/* the kernel runs in secure supervisor mode by default */ +#define KERNEL_TIMER_IRQ INTERRUPT_S_PGPT + +enum irqNumbers { + irqInvalid = 255 +}; + +#endif /* ! __PLAT_MACHINE_H */ diff --git a/include/plat/tk1/plat/machine/Makefile b/include/plat/tk1/plat/machine/Makefile new file mode 100644 index 000000000..04583ad17 --- /dev/null +++ b/include/plat/tk1/plat/machine/Makefile @@ -0,0 +1,13 @@ +# +# Copyright 2016, General Dynamics C4 Systems +# +# This software may be distributed and modified according to the terms of +# the GNU General Public License version 2. Note that NO WARRANTY is provided. +# See "LICENSE_GPLv2.txt" for details. +# +# @TAG(GD_GPL) +# + +DIRECTORIES += plat/machine + +BF_SOURCES += plat/machine/hardware.bf diff --git a/include/plat/tk1/plat/machine/debug_helpers.h b/include/plat/tk1/plat/machine/debug_helpers.h new file mode 100644 index 000000000..785dfbc24 --- /dev/null +++ b/include/plat/tk1/plat/machine/debug_helpers.h @@ -0,0 +1,17 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#ifndef __PLAT_MACHINE_DEBUG_HELPERS_H +#define __PLAT_MACHINE_DEBUG_HELPERS_H + +#include + +#endif + diff --git a/include/plat/tk1/plat/machine/devices.h b/include/plat/tk1/plat/machine/devices.h new file mode 100644 index 000000000..109b90320 --- /dev/null +++ b/include/plat/tk1/plat/machine/devices.h @@ -0,0 +1,108 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + + +#ifndef __PLAT_MACHINE_DEVICES_H +#define __PLAT_MACHINE_DEVICES_H + +/* These devices are used by the seL4 kernel. */ +#define UARTA_PPTR 0xfff01000 +#define UARTB_PPTR 0xfff01040 +#define UARTC_PPTR 0xfff01200 +#define UARTD_PPTR 0xfff01300 +#define GIC_DISTRIBUTOR_PPTR 0xfff03000 +#define GIC_CONTROLLER_PPTR 0xfff04000 + +#define GIC_PL390_CONTROLLER_PPTR GIC_CONTROLLER_PPTR +#define GIC_PL390_DISTRIBUTOR_PPTR GIC_DISTRIBUTOR_PPTR + +#define GIC_DISTRIBUTOR_PADDR GICD_PADDR +#define GIC_CONTROLLER0_PADDR GICI_PADDR + +/* + * many of the device regions are not 4K page aligned, so some regions may contain more than + * one devices. it is the user's responsibilty to figure out how to use these regions + * */ + +#define ARM_PERIPHBASE (0x50040000) /* 128 KB */ +#define GICD_PADDR (ARM_PERIPHBASE + 0x1000) /* interrupt distributor */ +#define GICI_PADDR (ARM_PERIPHBASE + 0x2000) /* GIC CPU interface */ +#define VGICI_REQ_PADDR (ARM_PERIPHBASE + 0x4000) /* hyp view for requesting CPU */ +#define VGICI_ALL_PADDR (ARM_PERIPHBASE + 0x5000) /* hyp view for all CPUs */ +#define VGICI_VM_PADDR (ARM_PERIPHBASE + 0x6000) /* hyp view for VM view */ +#define GRAPH_HOST_PADDR (0x54000000) /* 16 MB */ +#define GPU_PADDR (0x57000000) /* 144 MB */ +#define UP_TAG_PADDR (0x60000000) /* 4 KB */ +#define RSEM_PADDR (0x60001000) /* 4 KB */ +#define ASEM_PADDR (0x60002000) /* 4 KB */ +#define ARB_PRI_PADDR (0x60003000) /* 4 KB */ +#define ICTLR_PADDR (0x60004000) /* 4 KB, includes several */ +#define TMR_PADDR (0x60005000) /* 4 Kb, 1 KB */ +#define CLK_RESET_PADDR (0x60006000) /* 4 KB */ +#define FLOW_CTRL_PADDR (0x60007000) /* 4 KB */ +#define AHB_DMA_PADDR (0x60008000) /* 8 KB */ +#define AHB_DMA_CH_PADDR (0x60009000) /* 4 KB 4 channels, 32 bytes */ +#define APB_DMA_PADDR (0x60020000) /* 16 KB */ +#define APB_DMA_CH_PADDR (0x60021000) /* 4KB 32 channels, 64 bytes */ +#define SYS_REGS_PADDR (0x6000c000) /* 768 bytes + 2 KB */ +#define GPIO_PADDR (0x6000d000) /* 8 GPIOs, 265 bytes each */ +#define VCP_PADDR (0x6000e000) /* 4 KB */ +#define VPUCQ_PADDR (0x60010000) /* 256 Bytes */ +#define BSEA_PADDR (0x60011000) /* 4 KB */ +#define IPATCH_PADDR (0x6001d000) /* 4 KB offset 0xc00, 1 KB */ +#define VDE_FRAMEID_PADDR (0x60030000) /* 16 KB, multiple */ +#define MISC_PINMUX_PADDR (0x70000000) /* 16 KB */ +#define UARTA_SYNC_PADDR (0x70006000) /* 12 KB, multiple */ +#define SYNC_NOR_PADDR (0x70009000) /* 4 KB */ +#define PWM_PADDR (0x7000a000) /* 4 KB, 256 bytes */ +#define MIPIHSI_PADDR (0x7000b000) /* 4 KB */ +#define I2C_I2C4_PADDR (0x7000c000) /* 4 KB */ +#define I2C5_SPI2B_6_PADDR (0x7000d000) /* 4 KB */ +#define RTC_KFUSE_PADDR (0x7000e000) /* 4 KB */ +#define LA_PADDR (0x70010000) /* 8 KB */ +#define SE_PADDR (0x70012000) /* 8 KB */ +#define TSENSOR_PADDR (0x70014000) /* 4 KB */ +#define CEC_PADDR (0x70015000) /* 4 KB */ +#define ATOMICS_PADDR (0x70016000) /* 8 KB */ +#define MC_PADDR (0x70019000) /* 4 KB */ +#define EMC_PADDR (0x7001b000) /* 4 KB */ +#define SATA_PADDR (0x70020000) /* 64 KB */ +#define HDA_PADDR (0x70030000) /* 64 KB */ +#define MIOBFM_PADDR (0x70200000) /* 64 KB */ +#define AUDIO_PADDR (0x70300000) /* 64 KB */ +#define XUSB_HOST_PADDR (0x70090000) /* 40 KB */ +#define XUSB_DEV_PADDR (0x700d0000) /* 40 KB */ +#define DDS_PADDR (0x700a0000) /* 8KB 4608 bytes */ +#define SDMMC_1_PADDR (0x700b0000) /* 4KB 512 bytes */ +#define SDMMC_1B_4_PADDR (0x700b1000) /* 60KB 512 bytes each */ +#define SPEEDO_PADDR (0x700c0000) /* 32 KB */ +#define SPEEDO_PMON_PADDR (0x700c8000) /* 32 KB */ +#define SYSCTR0_PADDR (0x700f0000) /* 64 KB */ +#define SYSCTR1_PADDR (0x70100000) /* 64 KB */ +#define DP2_PADDR (0x700e0000) /* 256 Bytes */ +#define APB2JTAG_PADDR (0x700e1000) /* 512 Bytes */ +#define SOC_THERM_PADDR (0x700e2000) /* 4 KB */ +#define MIPI_CAL_PADDR (0x700e3000) /* 265 Bytes */ +#define DVFS_PADDR (0x70110000) /* 1 KB */ +#define CLUSTER_CLK_PADDR (0x70040000) /* 256 KB */ +#define CSITE_PADDR (0x70800000) /* 2 MB */ +#define PPCS_PADDR (0x7c000000) /* 64 KB */ +#define TZRAM_PADDR (0x7c010000) /* 64 KB */ +#define USB_PADDR (0x7d000000) /* 8 KB region, 6 KB */ +#define USB2_PADDR (0x7d004000) /* 8 KB region, 6 KB */ +#define USB3_PADDR (0x7d008000) /* 8 KB region, 6 KB */ + + + + + +#define UARTA_PADDR 0x70006000 + +#endif diff --git a/include/plat/tk1/plat/machine/hardware.bf b/include/plat/tk1/plat/machine/hardware.bf new file mode 100644 index 000000000..f2b53f07d --- /dev/null +++ b/include/plat/tk1/plat/machine/hardware.bf @@ -0,0 +1,12 @@ +-- +-- Copyright 2016, General Dynamics C4 Systems +-- +-- This software may be distributed and modified according to the terms of +-- the GNU General Public License version 2. Note that NO WARRANTY is provided. +-- See "LICENSE_GPLv2.txt" for details. +-- +-- @TAG(GD_GPL) +-- + +base 32 + diff --git a/include/plat/tk1/plat/machine/hardware.h b/include/plat/tk1/plat/machine/hardware.h new file mode 100644 index 000000000..98f3d6756 --- /dev/null +++ b/include/plat/tk1/plat/machine/hardware.h @@ -0,0 +1,87 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#ifndef __PLAT_MACHINE_HARDWARE_H +#define __PLAT_MACHINE_HARDWARE_H + +#define physBase 0x80000000 +#define kernelBase 0xe0000000 +#define physMappingOffset (kernelBase - physBase) +#define BASE_OFFSET physMappingOffset +#define PPTR_TOP 0xfff00000 +#define PADDR_TOP (PPTR_TOP - BASE_OFFSET) + + +#ifndef __ASSEMBLER__ + +#include +#include +#include +#include + +static inline void* CONST +ptrFromPAddr(paddr_t paddr) +{ + return (void*)(paddr + physMappingOffset); +} + +static inline paddr_t CONST +addrFromPPtr(void* pptr) +{ + return (paddr_t)pptr - physMappingOffset; +} + +#define paddr_to_pptr ptrFromPAddr +#define pptr_to_paddr addrFromPPtr + +static inline region_t CONST +paddr_to_pptr_reg(p_region_t p_reg) +{ + return (region_t) { + p_reg.start + physMappingOffset, p_reg.end + physMappingOffset + }; +} + +static inline p_region_t CONST +pptr_to_paddr_reg(region_t reg) +{ + return (p_region_t) { + reg.start - physMappingOffset, reg.end - physMappingOffset + }; +} + +int get_num_avail_p_regs(void); +p_region_t get_avail_p_reg(word_t i); +int get_num_dev_p_regs(void); +p_region_t get_dev_p_reg(word_t i); +void map_kernel_devices(void); + +bool_t CONST isReservedIRQ(irq_t irq); +void handleReservedIRQ(irq_t irq); + +/** MODIFIES: [*] */ +void resetTimer(void); +/** MODIFIES: [*] */ +void initTimer(void); + +/* L2 cache control */ +/** MODIFIES: [*] */ +void initL2Cache(void); + +/** MODIFIES: [*] */ +static inline void plat_cleanL2Range(paddr_t start, paddr_t end) {} +/** MODIFIES: [*] */ +static inline void plat_invalidateL2Range(paddr_t start, paddr_t end) {} +/** MODIFIES: [*] */ +static inline void plat_cleanInvalidateL2Range(paddr_t start, paddr_t end) {} + +#endif /* !__ASSEMBLER__ */ + +#endif diff --git a/include/plat/tk1/plat/machine/io.h b/include/plat/tk1/plat/machine/io.h new file mode 100644 index 000000000..14445efec --- /dev/null +++ b/include/plat/tk1/plat/machine/io.h @@ -0,0 +1,26 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#ifndef __PLAT_IO_H +#define __PLAT_IO_H + +#include + +#if defined DEBUG || defined RELEASE_PRINTF +void tk1_uart_putchar(char c); +void putDebugChar(unsigned char c); +unsigned char getDebugChar(void); + +#define kernel_putchar(c) tk1_uart_putchar(c) +#else /* !DEBUG */ +#define kernel_putchar(c) ((void)(0)) +#endif + +#endif diff --git a/src/plat/tk1/Makefile b/src/plat/tk1/Makefile new file mode 100644 index 000000000..9dd81efab --- /dev/null +++ b/src/plat/tk1/Makefile @@ -0,0 +1,11 @@ +# +# Copyright 2016, General Dynamics C4 Systems +# +# This software may be distributed and modified according to the terms of +# the GNU General Public License version 2. Note that NO WARRANTY is provided. +# See "LICENSE_GPLv2.txt" for details. +# +# @TAG(GD_GPL) +# + +include ${SOURCE_ROOT}/src/plat/$(PLAT)/machine/Makefile diff --git a/src/plat/tk1/linker.lds b/src/plat/tk1/linker.lds new file mode 100644 index 000000000..70b7d8231 --- /dev/null +++ b/src/plat/tk1/linker.lds @@ -0,0 +1,84 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +ENTRY(_start) + +/* WARNING: constants also defined in plat/machine/hardware.h */ +KERNEL_BASE = 0xe0000000; +PHYS_BASE = 0x80000000; +KERNEL_OFFSET = KERNEL_BASE - PHYS_BASE; + +SECTIONS +{ + . = KERNEL_BASE; + + .boot . : AT(ADDR(.boot) - KERNEL_OFFSET) + { + *(.boot.text) + *(.boot.rodata) + *(.boot.data) + . = ALIGN(64K); + } + + ki_boot_end = .; + + .text . : AT(ADDR(.text) - KERNEL_OFFSET) + { + /* Sit inside a large frame */ + . = ALIGN(64K); + *(.vectors) + + /* Fastpath code */ + *(.vectors.fastpath_call) + *(.vectors.fastpath_reply_recv) + *(.vectors.text) + + /* Anything else that should be in the vectors page. */ + *(.vectors.*) + + /* Hopefully all that fits into 4K! */ + + /* Standard kernel */ + *(.text) + } + + .rodata . : AT(ADDR(.rodata) - KERNEL_OFFSET) + { + *(.rodata) + *(.rodata.*) + } + + .data . : AT(ADDR(.data) - KERNEL_OFFSET) + { + *(.data) + } + + .bss . : AT(ADDR(.bss) - KERNEL_OFFSET) + { + *(.bss) + + /* 4k breakpoint stack */ + _breakpoint_stack_bottom = .; + . = . + 4K; + _breakpoint_stack_top = .; + + /* large data such as the globals frame and global PD */ + *(.bss.aligned) + } + + . = ALIGN(4K); + ki_end = .; + + /DISCARD/ : + { + *(.note.gnu.build-id) + *(.comment) + } +} diff --git a/src/plat/tk1/machine/Makefile b/src/plat/tk1/machine/Makefile new file mode 100644 index 000000000..1af784eaf --- /dev/null +++ b/src/plat/tk1/machine/Makefile @@ -0,0 +1,21 @@ +# +# Copyright 2016, General Dynamics C4 Systems +# +# This software may be distributed and modified according to the terms of +# the GNU General Public License version 2. Note that NO WARRANTY is provided. +# See "LICENSE_GPLv2.txt" for details. +# +# @TAG(GD_GPL) +# + +DIRECTORIES += src/plat/$(PLAT)/machine + +PLAT_C_SOURCES += machine/hardware.c \ + machine/l2cache.c + +ifdef DEBUG + PLAT_C_SOURCES += machine/io.c +endif +ifdef RELEASE_PRINTF + PLAT_C_SOURCES += machine/io.c +endif diff --git a/src/plat/tk1/machine/hardware.c b/src/plat/tk1/machine/hardware.c new file mode 100644 index 000000000..2249f2ce1 --- /dev/null +++ b/src/plat/tk1/machine/hardware.c @@ -0,0 +1,231 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Available physical memory regions on platform (RAM minus kernel image). */ +/* NOTE: Regions are not allowed to be adjacent! */ + +const p_region_t BOOT_RODATA avail_p_regs[] = { + { .start = 0x80000000, .end = 0xf0000000 } +}; + +BOOT_CODE int get_num_avail_p_regs(void) +{ + return sizeof(avail_p_regs) / sizeof(p_region_t); +} + +BOOT_CODE p_region_t get_avail_p_reg(word_t i) +{ + return avail_p_regs[i]; +} + +#define SECTION_BITS 20 +#define PAGE_SIZE (1 << PAGE_BITS) +#define SECTION_SIZE (1 << SECTION_BITS) + +const p_region_t BOOT_RODATA dev_p_regs[] = { + + { GRAPH_HOST_PADDR, GRAPH_HOST_PADDR + (SECTION_SIZE * 16) }, /* 16 MB */ + { GPU_PADDR, GPU_PADDR + (SECTION_SIZE * 144) }, /* 144 MB */ + { UP_TAG_PADDR, UP_TAG_PADDR + PAGE_SIZE }, /* 4 KB */ + { RSEM_PADDR, RSEM_PADDR + PAGE_SIZE }, /* 4 KB */ + { ASEM_PADDR, ASEM_PADDR + PAGE_SIZE }, /* 4 KB */ + { ARB_PRI_PADDR, ARB_PRI_PADDR + PAGE_SIZE }, /* 4 KB */ + { ICTLR_PADDR, ICTLR_PADDR + PAGE_SIZE }, /* 4 KB, includes several */ + { TMR_PADDR, TMR_PADDR + PAGE_SIZE }, /* 4 Kb, 1 KB */ + { CLK_RESET_PADDR, CLK_RESET_PADDR + PAGE_SIZE }, /* 4 KB */ + { FLOW_CTRL_PADDR, FLOW_CTRL_PADDR + PAGE_SIZE }, /* 4 KB */ + { AHB_DMA_PADDR, AHB_DMA_PADDR + (PAGE_SIZE * 2) }, /* 8 KB */ + { AHB_DMA_CH_PADDR, AHB_DMA_CH_PADDR + PAGE_SIZE }, /* 4 KB 4 channels, 32 bytes */ + { APB_DMA_PADDR, APB_DMA_PADDR + (PAGE_SIZE * 4) }, /* 16 KB */ + { APB_DMA_CH_PADDR, APB_DMA_CH_PADDR + PAGE_SIZE }, /* 4KB 32 channels, 64 bytes */ + { SYS_REGS_PADDR, SYS_REGS_PADDR + PAGE_SIZE }, /* 768 bytes + 2 KB */ + { GPIO_PADDR, GPIO_PADDR + PAGE_SIZE }, /* 8 GPIOs, 265 bytes each */ + { VCP_PADDR, VCP_PADDR + PAGE_SIZE }, /* 4 KB */ + { VPUCQ_PADDR, VPUCQ_PADDR + PAGE_SIZE }, /* 256 Bytes */ + { BSEA_PADDR, BSEA_PADDR + PAGE_SIZE }, /* 4 KB */ + { IPATCH_PADDR, IPATCH_PADDR + PAGE_SIZE }, /* 4 KB offset 0xc00, 1 KB */ + { VDE_FRAMEID_PADDR, VDE_FRAMEID_PADDR + (PAGE_SIZE * 4) }, /* 16 KB, multiple */ + { MISC_PINMUX_PADDR, MISC_PINMUX_PADDR + (PAGE_SIZE * 4) }, /* 16 KB */ + { UARTA_SYNC_PADDR, UARTA_SYNC_PADDR + (PAGE_SIZE * 3 ) }, /* 12 KB, multiple */ + { SYNC_NOR_PADDR, SYNC_NOR_PADDR + PAGE_SIZE }, /* 4 KB */ + { PWM_PADDR, PWM_PADDR + PAGE_SIZE }, /* 4 KB, 256 bytes */ + { MIPIHSI_PADDR, MIPIHSI_PADDR + PAGE_SIZE }, /* 4 KB */ + { I2C_I2C4_PADDR, I2C_I2C4_PADDR + PAGE_SIZE }, /* 4 KB */ + { I2C5_SPI2B_6_PADDR, I2C5_SPI2B_6_PADDR + PAGE_SIZE }, /* 4 KB */ + { RTC_KFUSE_PADDR, RTC_KFUSE_PADDR + PAGE_SIZE }, /* 4 KB */ + { LA_PADDR, LA_PADDR + (PAGE_SIZE * 2) }, /* 8 KB */ + { SE_PADDR, SE_PADDR + (PAGE_SIZE * 2) }, /* 8 KB */ + { TSENSOR_PADDR, TSENSOR_PADDR + PAGE_SIZE }, /* 4 KB */ + { CEC_PADDR, CEC_PADDR + PAGE_SIZE }, /* 4 KB */ + { ATOMICS_PADDR, ATOMICS_PADDR + (PAGE_SIZE * 2) }, /* 8 KB */ + { MC_PADDR, MC_PADDR + PAGE_SIZE }, /* 4 KB */ + { EMC_PADDR, EMC_PADDR + PAGE_SIZE }, /* 4 KB */ + { SATA_PADDR, SATA_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { HDA_PADDR, HDA_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { MIOBFM_PADDR, MIOBFM_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { AUDIO_PADDR, AUDIO_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { XUSB_HOST_PADDR, XUSB_HOST_PADDR + (PAGE_SIZE * 10) }, /* 40 KB */ + { XUSB_DEV_PADDR, XUSB_DEV_PADDR + (PAGE_SIZE * 10) }, /* 40 KB */ + { DDS_PADDR, DDS_PADDR + (PAGE_SIZE * 2) }, /* 8KB 4608 bytes */ + { SDMMC_1_PADDR, SDMMC_1_PADDR + PAGE_SIZE }, /* 4KB 512 bytes */ + { SDMMC_1B_4_PADDR, SDMMC_1B_4_PADDR + (PAGE_SIZE * 15) }, /* 60KB 512 bytes each */ + { SPEEDO_PADDR, SPEEDO_PADDR + (PAGE_SIZE * 8) }, /* 32 KB */ + { SPEEDO_PMON_PADDR, SPEEDO_PMON_PADDR + (PAGE_SIZE * 8) }, /* 32 KB */ + { SYSCTR0_PADDR, SYSCTR0_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { SYSCTR1_PADDR, SYSCTR1_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { DP2_PADDR, DP2_PADDR + PAGE_SIZE }, /* 4 KB 256 Bytes */ + { APB2JTAG_PADDR, APB2JTAG_PADDR + PAGE_SIZE }, /* 4 Kb 512 Bytes */ + { SOC_THERM_PADDR, SOC_THERM_PADDR + PAGE_SIZE }, /* 4 KB */ + { MIPI_CAL_PADDR, MIPI_CAL_PADDR + PAGE_SIZE }, /* 4 KB 265 Bytes */ + { DVFS_PADDR, DVFS_PADDR + PAGE_SIZE }, /* 4 KB 1 KB */ + { CLUSTER_CLK_PADDR, CLUSTER_CLK_PADDR + (PAGE_SIZE * 64) }, /* 256 KB */ + { CSITE_PADDR, CSITE_PADDR + (SECTION_SIZE * 2) }, /* 2 MB */ + { PPCS_PADDR, PPCS_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { TZRAM_PADDR, TZRAM_PADDR + (PAGE_SIZE * 16) }, /* 64 KB */ + { USB_PADDR, USB_PADDR + (PAGE_SIZE * 2) }, /* 8 KB region, 6 KB */ + { USB2_PADDR, USB2_PADDR + (PAGE_SIZE * 2) }, /* 8 KB region, 6 KB */ + { USB3_PADDR, USB3_PADDR + (PAGE_SIZE * 2) }, /* 8 KB region, 6 KB */ +}; + +BOOT_CODE int get_num_dev_p_regs(void) +{ + return sizeof(dev_p_regs) / sizeof(p_region_t); +} + +BOOT_CODE p_region_t get_dev_p_reg(word_t i) +{ + return dev_p_regs[i]; +} + + +/* Determine if the given IRQ should be reserved by the kernel. */ +bool_t CONST +isReservedIRQ(irq_t irq) +{ + return irq == KERNEL_TIMER_IRQ; +} + +/* Handle a platform-reserved IRQ. */ +void +handleReservedIRQ(irq_t irq) +{ + printf("Received reserved IRQ: %d\n", (int)irq); +} + +BOOT_CODE void +map_kernel_devices(void) +{ + /* map kernel device: GIC */ + map_kernel_frame( + GIC_CONTROLLER0_PADDR, + GIC_CONTROLLER_PPTR, + VMKernelOnly, + vm_attributes_new( + true, /* armExecuteNever */ + false, /* armParityEnabled */ + false /* armPageCacheable */ + ) + ); + map_kernel_frame( + GIC_DISTRIBUTOR_PADDR, + GIC_DISTRIBUTOR_PPTR, + VMKernelOnly, + vm_attributes_new( + true, /* armExecuteNever */ + false, /* armParityEnabled */ + false /* armPageCacheable */ + ) + ); + +#if defined DEBUG || defined RELEASE_PRINTF + /* map kernel device: UART */ + map_kernel_frame( + UARTA_PADDR, + UARTA_PPTR, + VMKernelOnly, + vm_attributes_new( + true, /* armExecuteNever */ + false, /* armParityEnabled */ + false /* armPageCacheable */ + ) + ); +#endif +} + + +/* co-processor code to read and write GPT */ + +static void +write_cntp_ctl(uint32_t v) +{ + asm volatile ("mcr p15, 0, %0, c14, c2, 1" ::"r"(v)); +} + +static void +write_cntp_tval(uint32_t v) +{ + asm volatile ("mcr p15, 0, %0, c14, c2, 0" :: "r"(v)); +} + +static uint32_t +read_cntfrq(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val)); + return val; +} + +#define GPT_DEFAULT_HZ 12000000 +static uint32_t gpt_cntp_tval = 0; + +/** + DONT_TRANSLATE + */ +void +resetTimer(void) +{ + write_cntp_tval(gpt_cntp_tval); +} + +/** + DONT_TRANSLATE + */ + +/* we use the physical count-down timer of the GPT as the kernel preemption timer */ +BOOT_CODE void +initTimer(void) +{ + uint32_t freq = read_cntfrq(); + uint64_t tval = 0; + if (freq != GPT_DEFAULT_HZ) { + printf("Default timer has a different frequency %x\n", freq); + } + tval = (uint64_t)CONFIG_TIMER_TICK_MS * (freq / 1000); + if (tval > 0xffffffff) { + printf("timer interval value out of range \n"); + halt(); + } + gpt_cntp_tval = (uint32_t)tval; + + /* write the value */ + write_cntp_tval(gpt_cntp_tval); + + /* enable the timer */ + write_cntp_ctl(0x1); +} diff --git a/src/plat/tk1/machine/io.c b/src/plat/tk1/machine/io.c new file mode 100644 index 000000000..28b141253 --- /dev/null +++ b/src/plat/tk1/machine/io.c @@ -0,0 +1,48 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#include +#include +#include +#include + +#if defined DEBUG || defined RELEASE_PRINTF + +#define UTHR 0x0 +#define ULSR 0x14 +#define ULSR_THRE (1 << 5) + +#define UART_REG(x) ((volatile uint32_t *)(UARTD_PPTR + (x))) + +void +tk1_uart_putchar(char c) +{ + while ((*UART_REG(ULSR) & ULSR_THRE) == 0); + + *UART_REG(UTHR) = (c & 0xff); + + if (c == '\n') { + tk1_uart_putchar('\r'); + } +} + +void putDebugChar(unsigned char c) +{ + while ((*UART_REG(ULSR) & ULSR_THRE) == 0); + + *UART_REG(UTHR) = c; +} + +unsigned char getDebugChar(void) +{ + return 0; +} + +#endif diff --git a/src/plat/tk1/machine/l2cache.c b/src/plat/tk1/machine/l2cache.c new file mode 100644 index 000000000..f71b330b6 --- /dev/null +++ b/src/plat/tk1/machine/l2cache.c @@ -0,0 +1,18 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#include + +void +initL2Cache(void) +{ + +} + From 4178a9e79f9e0f101b189efacbd50ed953f82c76 Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Mon, 14 Mar 2016 16:47:40 +1100 Subject: [PATCH 6/7] arm/arm_hyp: replace macros with explicit inline --- include/arch/arm/arch/32/mode/machine.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/arch/arm/arch/32/mode/machine.h b/include/arch/arm/arch/32/mode/machine.h index 9c2d4a0e7..2c4172510 100644 --- a/include/arch/arm/arch/32/mode/machine.h +++ b/include/arch/arm/arch/32/mode/machine.h @@ -68,7 +68,7 @@ void setNextPC(tcb_t *thread, word_t v); static inline word_t getProcessorID(void) { word_t processor_id; - MRC("p15, 0, %0, c0, c0, 0", processor_id); + asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r"(processor_id)); return processor_id; } @@ -76,28 +76,28 @@ static inline word_t getProcessorID(void) static inline word_t readSystemControlRegister(void) { word_t scr; - MRC("p15, 0, %0, c1, c0, 0", scr); + asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r"(scr)); return scr; } /** DONT_TRANSLATE */ static inline void writeSystemControlRegister(word_t scr) { - MCR("p15, 0, %0, c1, c0, 0", scr); + asm volatile ("mcr p15, 0, %0, c1, c0, 0" :: "r"(scr)); } /** DONT_TRANSLATE */ static inline word_t readAuxiliaryControlRegister(void) { word_t acr; - MRC("p15, 0, %0, c1, c0, 1", acr); + asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r"(acr)); return acr; } /** DONT_TRANSLATE */ static inline void writeAuxiliaryControlRegister(word_t acr) { - MCR("p15, 0, %0, c1, c0, 1", acr); + asm volatile ("mcr p15, 0, %0, c1, c0, 1" :: "r"(acr)); } /** MODIFIES: [*] */ From 96222bfce796fca16337fc756ed2e0f9bcb7482d Mon Sep 17 00:00:00 2001 From: Yanyan Shen Date: Mon, 14 Mar 2016 16:48:45 +1100 Subject: [PATCH 7/7] arm/arm_hyp: remove #ifdef ARM_HYPs --- src/arch/arm/32/kernel/vspace.c | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/arch/arm/32/kernel/vspace.c b/src/arch/arm/32/kernel/vspace.c index e8242ca92..89c50d913 100644 --- a/src/arch/arm/32/kernel/vspace.c +++ b/src/arch/arm/32/kernel/vspace.c @@ -1140,11 +1140,11 @@ setVMRoot(tcb_t *tcb) if (cap_get_capType(threadRoot) != cap_page_directory_cap || !cap_page_directory_cap_get_capPDIsMapped(threadRoot)) { -#ifndef ARM_HYP - setCurrentPD(addrFromPPtr(armKSGlobalPD)); -#else - setCurrentPD(addrFromPPtr(0)); -#endif + if (config_set(ARM_HYP)) { + setCurrentPD(addrFromPPtr(0)); + } else { + setCurrentPD(addrFromPPtr(armKSGlobalPD)); + } return; } @@ -1152,18 +1152,18 @@ setVMRoot(tcb_t *tcb) asid = cap_page_directory_cap_get_capPDMappedASID(threadRoot); find_ret = findPDForASID(asid); if (unlikely(find_ret.status != EXCEPTION_NONE || find_ret.pd != pd)) { -#ifndef ARM_HYP - setCurrentPD(addrFromPPtr(armKSGlobalPD)); -#else - setCurrentPD(addrFromPPtr(0)); -#endif + if (config_set(ARM_HYP)) { + setCurrentPD(addrFromPPtr(0)); + } else { + setCurrentPD(addrFromPPtr(armKSGlobalPD)); + } return; } armv_contextSwitch(pd, asid); -#ifdef ARM_HYP - vcpu_switch(tcb->tcbArch.vcpu); -#endif + if (config_set(ARM_HYP)) { + vcpu_switch(tcb->tcbArch.vcpu); + } } static bool_t @@ -1894,12 +1894,12 @@ doFlush(int invLabel, vptr_t start, vptr_t end, paddr_t pstart) /** GHOSTUPD: "((gs_get_assn cap_get_capSizeBits_'proc \ghost'state = 0 \ \end - \start <= gs_get_assn cap_get_capSizeBits_'proc \ghost'state) \ \start <= \end, id)" */ -#ifdef ARM_HYP - /* The hypervisor does not share an AS with userspace so we must flush - * by kernel MVA instead. ARMv7 caches are PIPT so it makes no difference */ - end = (vptr_t)paddr_to_pptr(pstart) + (end - start); - start = (vptr_t)paddr_to_pptr(pstart); -#endif + if (config_set(ARM_HYP)) { + /* The hypervisor does not share an AS with userspace so we must flush + * by kernel MVA instead. ARMv7 caches are PIPT so it makes no difference */ + end = (vptr_t)paddr_to_pptr(pstart) + (end - start); + start = (vptr_t)paddr_to_pptr(pstart); + } switch (invLabel) { case ARMPDClean_Data: case ARMPageClean_Data: @@ -2055,9 +2055,9 @@ performPageInvocationRemapPTE(asid_t asid, pte_t pte, pte_range_t pte_entries) for (i = 0; i < pte_entries.length; i++) { pte_entries.base[i] = pte; -#ifdef ARM_HYP - pte.words[0] += BIT(pageBitsForSize(ARMLargePage)); -#endif + if (config_set(ARM_HYP)) { + pte.words[0] += BIT(pageBitsForSize(ARMLargePage)); + } } cleanCacheRange_PoU((word_t)pte_entries.base, LAST_BYTE_PTE(pte_entries.base, pte_entries.length), @@ -2084,9 +2084,9 @@ performPageInvocationRemapPDE(asid_t asid, pde_t pde, pde_range_t pde_entries) for (i = 0; i < pde_entries.length; i++) { pde_entries.base[i] = pde; -#ifdef ARM_HYP - pde.words[0] += BIT(pageBitsForSize(ARMSection)); -#endif + if (config_set(ARM_HYP)) { + pde.words[0] += BIT(pageBitsForSize(ARMSection)); + } } cleanCacheRange_PoU((word_t)pde_entries.base, LAST_BYTE_PDE(pde_entries.base, pde_entries.length),