···11+/*22+ * Declarations for to Hexagon Virtal Machine.33+ *44+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 and88+ * only version 2 as published by the Free Software Foundation.99+ *1010+ * This program is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this program; if not, write to the Free Software1717+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1818+ * 02110-1301, USA.1919+ */2020+2121+#ifndef ASM_HEXAGON_VM_H2222+#define ASM_HEXAGON_VM_H2323+2424+/*2525+ * In principle, a Linux kernel for the VM could2626+ * selectively define the virtual instructions2727+ * as inline assembler macros, but for a first pass,2828+ * we'll use subroutines for both the VM and the native2929+ * kernels. It's costing a subroutine call/return,3030+ * but it makes for a single set of entry points3131+ * for tracing/debugging.3232+ */3333+3434+/*3535+ * Lets make this stuff visible only if configured,3636+ * so we can unconditionally include the file.3737+ */3838+3939+#ifndef __ASSEMBLY__4040+4141+enum VM_CACHE_OPS {4242+ ickill,4343+ dckill,4444+ l2kill,4545+ dccleaninva,4646+ icinva,4747+ idsync,4848+ fetch_cfg4949+};5050+5151+enum VM_INT_OPS {5252+ nop,5353+ globen,5454+ globdis,5555+ locen,5656+ locdis,5757+ affinity,5858+ get,5959+ peek,6060+ status,6161+ post,6262+ clear6363+};6464+6565+extern void _K_VM_event_vector(void);6666+6767+void __vmrte(void);6868+long __vmsetvec(void *);6969+long __vmsetie(long);7070+long __vmgetie(void);7171+long __vmintop(enum VM_INT_OPS, long, long, long, long);7272+long __vmclrmap(void *, unsigned long);7373+long __vmnewmap(void *);7474+long __vmcache(enum VM_CACHE_OPS op, unsigned long addr, unsigned long len);7575+unsigned long long __vmgettime(void);7676+long __vmsettime(unsigned long long);7777+long __vmstart(void *, void *);7878+void __vmstop(void);7979+long __vmwait(void);8080+void __vmyield(void);8181+long __vmvpid(void);8282+8383+static inline long __vmcache_ickill(void)8484+{8585+ return __vmcache(ickill, 0, 0);8686+}8787+8888+static inline long __vmcache_dckill(void)8989+{9090+ return __vmcache(dckill, 0, 0);9191+}9292+9393+static inline long __vmcache_l2kill(void)9494+{9595+ return __vmcache(l2kill, 0, 0);9696+}9797+9898+static inline long __vmcache_dccleaninva(unsigned long addr, unsigned long len)9999+{100100+ return __vmcache(dccleaninva, addr, len);101101+}102102+103103+static inline long __vmcache_icinva(unsigned long addr, unsigned long len)104104+{105105+ return __vmcache(icinva, addr, len);106106+}107107+108108+static inline long __vmcache_idsync(unsigned long addr,109109+ unsigned long len)110110+{111111+ return __vmcache(idsync, addr, len);112112+}113113+114114+static inline long __vmcache_fetch_cfg(unsigned long val)115115+{116116+ return __vmcache(fetch_cfg, val, 0);117117+}118118+119119+/* interrupt operations */120120+121121+static inline long __vmintop_nop(void)122122+{123123+ return __vmintop(nop, 0, 0, 0, 0);124124+}125125+126126+static inline long __vmintop_globen(long i)127127+{128128+ return __vmintop(globen, i, 0, 0, 0);129129+}130130+131131+static inline long __vmintop_globdis(long i)132132+{133133+ return __vmintop(globdis, i, 0, 0, 0);134134+}135135+136136+static inline long __vmintop_locen(long i)137137+{138138+ return __vmintop(locen, i, 0, 0, 0);139139+}140140+141141+static inline long __vmintop_locdis(long i)142142+{143143+ return __vmintop(locdis, i, 0, 0, 0);144144+}145145+146146+static inline long __vmintop_affinity(long i, long cpu)147147+{148148+ return __vmintop(locdis, i, cpu, 0, 0);149149+}150150+151151+static inline long __vmintop_get(void)152152+{153153+ return __vmintop(get, 0, 0, 0, 0);154154+}155155+156156+static inline long __vmintop_peek(void)157157+{158158+ return __vmintop(peek, 0, 0, 0, 0);159159+}160160+161161+static inline long __vmintop_status(long i)162162+{163163+ return __vmintop(status, i, 0, 0, 0);164164+}165165+166166+static inline long __vmintop_post(long i)167167+{168168+ return __vmintop(post, i, 0, 0, 0);169169+}170170+171171+static inline long __vmintop_clear(long i)172172+{173173+ return __vmintop(clear, i, 0, 0, 0);174174+}175175+176176+#else /* Only assembly code should reference these */177177+178178+#define HVM_TRAP1_VMRTE 1179179+#define HVM_TRAP1_VMSETVEC 2180180+#define HVM_TRAP1_VMSETIE 3181181+#define HVM_TRAP1_VMGETIE 4182182+#define HVM_TRAP1_VMINTOP 5183183+#define HVM_TRAP1_VMCLRMAP 10184184+#define HVM_TRAP1_VMNEWMAP 11185185+#define HVM_TRAP1_FORMERLY_VMWIRE 12186186+#define HVM_TRAP1_VMCACHE 13187187+#define HVM_TRAP1_VMGETTIME 14188188+#define HVM_TRAP1_VMSETTIME 15189189+#define HVM_TRAP1_VMWAIT 16190190+#define HVM_TRAP1_VMYIELD 17191191+#define HVM_TRAP1_VMSTART 18192192+#define HVM_TRAP1_VMSTOP 19193193+#define HVM_TRAP1_VMVPID 20194194+#define HVM_TRAP1_VMSETREGS 21195195+#define HVM_TRAP1_VMGETREGS 22196196+197197+#endif /* __ASSEMBLY__ */198198+199199+/*200200+ * Constants for virtual instruction parameters and return values201201+ */202202+203203+/* vmsetie arguments */204204+205205+#define VM_INT_DISABLE 0206206+#define VM_INT_ENABLE 1207207+208208+/* vmsetimask arguments */209209+210210+#define VM_INT_UNMASK 0211211+#define VM_INT_MASK 1212212+213213+#define VM_NEWMAP_TYPE_LINEAR 0214214+#define VM_NEWMAP_TYPE_PGTABLES 1215215+216216+217217+/*218218+ * Event Record definitions useful to both C and Assembler219219+ */220220+221221+/* VMEST Layout */222222+223223+#define HVM_VMEST_UM_SFT 31224224+#define HVM_VMEST_UM_MSK 1225225+#define HVM_VMEST_IE_SFT 30226226+#define HVM_VMEST_IE_MSK 1227227+#define HVM_VMEST_EVENTNUM_SFT 16228228+#define HVM_VMEST_EVENTNUM_MSK 0xff229229+#define HVM_VMEST_CAUSE_SFT 0230230+#define HVM_VMEST_CAUSE_MSK 0xffff231231+232232+/*233233+ * The initial program gets to find a system environment descriptor234234+ * on its stack when it begins exection. The first word is a version235235+ * code to indicate what is there. Zero means nothing more.236236+ */237237+238238+#define HEXAGON_VM_SED_NULL 0239239+240240+/*241241+ * Event numbers for vector binding242242+ */243243+244244+#define HVM_EV_RESET 0245245+#define HVM_EV_MACHCHECK 1246246+#define HVM_EV_GENEX 2247247+#define HVM_EV_TRAP 8248248+#define HVM_EV_INTR 15249249+/* These shoud be nuked as soon as we know the VM is up to spec v0.1.1 */250250+#define HVM_EV_INTR_0 16251251+#define HVM_MAX_INTR 240252252+253253+/*254254+ * Cause values for General Exception255255+ */256256+257257+#define HVM_GE_C_BUS 0x01258258+#define HVM_GE_C_XPROT 0x11259259+#define HVM_GE_C_XUSER 0x14260260+#define HVM_GE_C_INVI 0x15261261+#define HVM_GE_C_PRIVI 0x1B262262+#define HVM_GE_C_XMAL 0x1C263263+#define HVM_GE_C_RMAL 0x20264264+#define HVM_GE_C_WMAL 0x21265265+#define HVM_GE_C_RPROT 0x22266266+#define HVM_GE_C_WPROT 0x23267267+#define HVM_GE_C_RUSER 0x24268268+#define HVM_GE_C_WUSER 0x25269269+#define HVM_GE_C_CACHE 0x28270270+271271+/*272272+ * Cause codes for Machine Check273273+ */274274+275275+#define HVM_MCHK_C_DOWN 0x00276276+#define HVM_MCHK_C_BADSP 0x01277277+#define HVM_MCHK_C_BADEX 0x02278278+#define HVM_MCHK_C_BADPT 0x03279279+#define HVM_MCHK_C_REGWR 0x29280280+281281+#endif
+111
arch/hexagon/include/asm/vm_mmu.h
···11+/*22+ * Hexagon VM page table entry definitions33+ *44+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 and88+ * only version 2 as published by the Free Software Foundation.99+ *1010+ * This program is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this program; if not, write to the Free Software1717+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1818+ * 02110-1301, USA.1919+ */2020+2121+#ifndef _ASM_VM_MMU_H2222+#define _ASM_VM_MMU_H2323+2424+/*2525+ * Shift, mask, and other constants for the Hexagon Virtual Machine2626+ * page tables.2727+ *2828+ * Virtual machine MMU allows first-level entries to either be2929+ * single-level lookup PTEs for very large pages, or PDEs pointing3030+ * to second-level PTEs for smaller pages. If PTE is single-level,3131+ * the least significant bits cannot be used as software bits to encode3232+ * virtual memory subsystem information about the page, and that state3333+ * must be maintained in some parallel data structure.3434+ */3535+3636+/* S or Page Size field in PDE */3737+#define __HVM_PDE_S (0x7 << 0)3838+#define __HVM_PDE_S_4KB 03939+#define __HVM_PDE_S_16KB 14040+#define __HVM_PDE_S_64KB 24141+#define __HVM_PDE_S_256KB 34242+#define __HVM_PDE_S_1MB 44343+#define __HVM_PDE_S_4MB 54444+#define __HVM_PDE_S_16MB 64545+#define __HVM_PDE_S_INVALID 74646+4747+/* Masks for L2 page table pointer, as function of page size */4848+#define __HVM_PDE_PTMASK_4KB 0xfffff0004949+#define __HVM_PDE_PTMASK_16KB 0xfffffc005050+#define __HVM_PDE_PTMASK_64KB 0xffffff005151+#define __HVM_PDE_PTMASK_256KB 0xffffffc05252+#define __HVM_PDE_PTMASK_1MB 0xfffffff05353+5454+/*5555+ * Virtual Machine PTE Bits/Fields5656+ */5757+#define __HVM_PTE_T (1<<4)5858+#define __HVM_PTE_U (1<<5)5959+#define __HVM_PTE_C (0x7<<6)6060+#define __HVM_PTE_CVAL(pte) (((pte) & __HVM_PTE_C) >> 6)6161+#define __HVM_PTE_R (1<<9)6262+#define __HVM_PTE_W (1<<10)6363+#define __HVM_PTE_X (1<<11)6464+6565+/*6666+ * Cache Attributes, to be shifted as necessary for virtual/physical PTEs6767+ */6868+6969+#define __HEXAGON_C_WB 0x0 /* Write-back, no L2 */7070+#define __HEXAGON_C_WT 0x1 /* Write-through, no L2 */7171+#define __HEXAGON_C_DEV 0x4 /* Device register space */7272+#define __HEXAGON_C_WT_L2 0x5 /* Write-through, with L2 */7373+/* this really should be #if CONFIG_HEXAGON_ARCH = 2 but that's not defined */7474+#if defined(CONFIG_HEXAGON_COMET) || defined(CONFIG_QDSP6_ST1)7575+#define __HEXAGON_C_UNC __HEXAGON_C_DEV7676+#else7777+#define __HEXAGON_C_UNC 0x6 /* Uncached memory */7878+#endif7979+#define __HEXAGON_C_WB_L2 0x7 /* Write-back, with L2 */8080+8181+/*8282+ * This can be overriden, but we're defaulting to the most aggressive8383+ * cache policy, the better to find bugs sooner.8484+ */8585+8686+#define CACHE_DEFAULT __HEXAGON_C_WB_L28787+8888+/* Masks for physical page address, as a function of page size */8989+9090+#define __HVM_PTE_PGMASK_4KB 0xfffff0009191+#define __HVM_PTE_PGMASK_16KB 0xffffc0009292+#define __HVM_PTE_PGMASK_64KB 0xffff00009393+#define __HVM_PTE_PGMASK_256KB 0xfffc00009494+#define __HVM_PTE_PGMASK_1MB 0xfff000009595+9696+/* Masks for single-level large page lookups */9797+9898+#define __HVM_PTE_PGMASK_4MB 0xffc000009999+#define __HVM_PTE_PGMASK_16MB 0xff000000100100+101101+/*102102+ * "Big kernel page mappings" (see vm_init_segtable.S)103103+ * are currently 16MB104104+ */105105+106106+#define BIG_KERNEL_PAGE_SHIFT 24107107+#define BIG_KERNEL_PAGE_SIZE (1 << BIG_KERNEL_PAGE_SHIFT)108108+109109+110110+111111+#endif /* _ASM_VM_MMU_H */
+269
arch/hexagon/kernel/vm_entry.S
···11+/*22+ * Event entry/exit for Hexagon33+ *44+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 and88+ * only version 2 as published by the Free Software Foundation.99+ *1010+ * This program is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this program; if not, write to the Free Software1717+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1818+ * 02110-1301, USA.1919+ */2020+2121+#include <asm/asm-offsets.h> /* assembly-safer versions of C defines */2222+#include <asm/mem-layout.h> /* sigh, except for page_offset */2323+#include <asm/hexagon_vm.h>2424+#include <asm/thread_info.h>2525+2626+/*2727+ * Entry into guest-mode Linux under Hexagon Virtual Machine.2828+ * Stack pointer points to event record - build pt_regs on top of it,2929+ * set up a plausible C stack frame, and dispatch to the C handler.3030+ * On return, do vmrte virtual instruction with SP where we started.3131+ *3232+ * VM Spec 0.5 uses a trap to fetch HVM record now.3333+ */3434+3535+/*3636+ * Save full register state, while setting up thread_info struct3737+ * pointer derived from kernel stack pointer in THREADINFO_REG3838+ * register, putting prior thread_info.regs pointer in a callee-save3939+ * register (R24, which had better not ever be assigned to THREADINFO_REG),4040+ * and updating thread_info.regs to point to current stack frame,4141+ * so as to support nested events in kernel mode.4242+ *4343+ * As this is common code, we set the pt_regs system call number4444+ * to -1 for all events. It will be replaced with the system call4545+ * number in the case where we decode a system call (trap0(#1)).4646+ */4747+4848+#define save_pt_regs()\4949+ memd(R0 + #_PT_R3130) = R31:30; \5050+ { memw(R0 + #_PT_R2928) = R28; \5151+ R31 = memw(R0 + #_PT_ER_VMPSP); }\5252+ { memw(R0 + #(_PT_R2928 + 4)) = R31; \5353+ R31 = ugp; } \5454+ { memd(R0 + #_PT_R2726) = R27:26; \5555+ R30 = gp ; } \5656+ memd(R0 + #_PT_R2524) = R25:24; \5757+ memd(R0 + #_PT_R2322) = R23:22; \5858+ memd(R0 + #_PT_R2120) = R21:20; \5959+ memd(R0 + #_PT_R1918) = R19:18; \6060+ memd(R0 + #_PT_R1716) = R17:16; \6161+ memd(R0 + #_PT_R1514) = R15:14; \6262+ memd(R0 + #_PT_R1312) = R13:12; \6363+ { memd(R0 + #_PT_R1110) = R11:10; \6464+ R15 = lc0; } \6565+ { memd(R0 + #_PT_R0908) = R9:8; \6666+ R14 = sa0; } \6767+ { memd(R0 + #_PT_R0706) = R7:6; \6868+ R13 = lc1; } \6969+ { memd(R0 + #_PT_R0504) = R5:4; \7070+ R12 = sa1; } \7171+ { memd(R0 + #_PT_UGPGP) = R31:30; \7272+ R11 = m1; \7373+ R2.H = #HI(_THREAD_SIZE); } \7474+ { memd(R0 + #_PT_LC0SA0) = R15:14; \7575+ R10 = m0; \7676+ R2.L = #LO(_THREAD_SIZE); } \7777+ { memd(R0 + #_PT_LC1SA1) = R13:12; \7878+ R15 = p3:0; \7979+ R2 = neg(R2); } \8080+ { memd(R0 + #_PT_M1M0) = R11:10; \8181+ R14 = usr; \8282+ R2 = and(R0,R2); } \8383+ { memd(R0 + #_PT_PREDSUSR) = R15:14; \8484+ THREADINFO_REG = R2; } \8585+ { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \8686+ memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \8787+ R2 = #-1; } \8888+ { memw(R0 + #_PT_SYSCALL_NR) = R2; \8989+ R30 = #0; }9090+9191+/*9292+ * Restore registers and thread_info.regs state. THREADINFO_REG9393+ * is assumed to still be sane, and R24 to have been correctly9494+ * preserved. Don't restore R29 (SP) until later.9595+ */9696+9797+#define restore_pt_regs() \9898+ { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \9999+ R15:14 = memd(R0 + #_PT_PREDSUSR); } \100100+ { R11:10 = memd(R0 + #_PT_M1M0); \101101+ p3:0 = R15; } \102102+ { R13:12 = memd(R0 + #_PT_LC1SA1); \103103+ usr = R14; } \104104+ { R15:14 = memd(R0 + #_PT_LC0SA0); \105105+ m1 = R11; } \106106+ { R3:2 = memd(R0 + #_PT_R0302); \107107+ m0 = R10; } \108108+ { R5:4 = memd(R0 + #_PT_R0504); \109109+ lc1 = R13; } \110110+ { R7:6 = memd(R0 + #_PT_R0706); \111111+ sa1 = R12; } \112112+ { R9:8 = memd(R0 + #_PT_R0908); \113113+ lc0 = R15; } \114114+ { R11:10 = memd(R0 + #_PT_R1110); \115115+ sa0 = R14; } \116116+ { R13:12 = memd(R0 + #_PT_R1312); \117117+ R15:14 = memd(R0 + #_PT_R1514); } \118118+ { R17:16 = memd(R0 + #_PT_R1716); \119119+ R19:18 = memd(R0 + #_PT_R1918); } \120120+ { R21:20 = memd(R0 + #_PT_R2120); \121121+ R23:22 = memd(R0 + #_PT_R2322); } \122122+ { R25:24 = memd(R0 + #_PT_R2524); \123123+ R27:26 = memd(R0 + #_PT_R2726); } \124124+ R31:30 = memd(R0 + #_PT_UGPGP); \125125+ { R28 = memw(R0 + #_PT_R2928); \126126+ ugp = R31; } \127127+ { R31:30 = memd(R0 + #_PT_R3130); \128128+ gp = R30; }129129+130130+ /*131131+ * Clears off enough space for the rest of pt_regs; evrec is a part132132+ * of pt_regs in HVM mode. Save R0/R1, set handler's address in R1.133133+ * R0 is the address of pt_regs and is the parameter to save_pt_regs.134134+ */135135+136136+/*137137+ * Since the HVM isn't automagically pushing the EVREC onto the stack anymore,138138+ * we'll subract the entire size out and then fill it in ourselves.139139+ * Need to save off R0, R1, R2, R3 immediately.140140+ */141141+142142+#define vm_event_entry(CHandler) \143143+ { \144144+ R29 = add(R29, #-(_PT_REGS_SIZE)); \145145+ memd(R29 + #(_PT_R0100 + -_PT_REGS_SIZE)) = R1:0; \146146+ } \147147+ { \148148+ memd(R29 +#_PT_R0302) = R3:2; \149149+ } \150150+ trap1(#HVM_TRAP1_VMGETREGS); \151151+ { \152152+ memd(R29 + #_PT_ER_VMEL) = R1:0; \153153+ R0 = R29; \154154+ R1.L = #LO(CHandler); \155155+ } \156156+ { \157157+ memd(R29 + #_PT_ER_VMPSP) = R3:2; \158158+ R1.H = #HI(CHandler); \159159+ jump event_dispatch; \160160+ }161161+162162+.text163163+ /*164164+ * Do bulk save/restore in one place.165165+ * Adds a jump to dispatch latency, but166166+ * saves hundreds of bytes.167167+ */168168+169169+event_dispatch:170170+ save_pt_regs()171171+ callr r1172172+173173+ /*174174+ * If we were in kernel mode, we don't need to check scheduler175175+ * or signals if CONFIG_PREEMPT is not set. If set, then it has176176+ * to jump to a need_resched kind of block.177177+ * BTW, CONFIG_PREEMPT is not supported yet.178178+ */179179+180180+#ifdef CONFIG_PREEMPT181181+ R0 = #VM_INT_DISABLE182182+ trap1(#HVM_TRAP1_VMSETIE)183183+#endif184184+185185+ /* "Nested control path" -- if the previous mode was kernel */186186+ R0 = memw(R29 + #_PT_ER_VMEST);187187+ P0 = tstbit(R0, #HVM_VMEST_UM_SFT);188188+ if !P0 jump restore_all;189189+ /*190190+ * Returning from system call, normally coming back from user mode191191+ */192192+return_from_syscall:193193+ /* Disable interrupts while checking TIF */194194+ R0 = #VM_INT_DISABLE195195+ trap1(#HVM_TRAP1_VMSETIE)196196+197197+ /*198198+ * Coming back from the C-world, our thread info pointer199199+ * should be in the designated register (usually R19)200200+ */201201+ R1.L = #LO(_TIF_ALLWORK_MASK)202202+ {203203+ R1.H = #HI(_TIF_ALLWORK_MASK);204204+ R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS);205205+ }206206+207207+ /*208208+ * Compare against the "return to userspace" _TIF_WORK_MASK209209+ */210210+ R1 = and(R1,R0);211211+ { P0 = cmp.eq(R1,#0); if (!P0.new) jump:t work_pending;}212212+ jump restore_all; /* we're outta here! */213213+214214+work_pending:215215+ {216216+ P0 = tstbit(R1, #TIF_NEED_RESCHED);217217+ if (!P0.new) jump:nt work_notifysig;218218+ }219219+ call schedule220220+ jump return_from_syscall; /* check for more work */221221+222222+work_notifysig:223223+ /* this is the part that's kind of fuzzy. */224224+ R1 = and(R0, #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME));225225+ P0 = cmp.eq(R1, #0);226226+ if P0 jump restore_all227227+ R1 = R0; /* unsigned long thread_info_flags */228228+ R0 = R29; /* regs should still be at top of stack */229229+ call do_notify_resume230230+231231+restore_all:232232+ /* Disable interrupts, if they weren't already, before reg restore. */233233+ R0 = #VM_INT_DISABLE234234+ trap1(#HVM_TRAP1_VMSETIE)235235+236236+ /* do the setregs here for VM 0.5 */237237+ /* R29 here should already be pointing at pt_regs */238238+ R1:0 = memd(R29 + #_PT_ER_VMEL);239239+ R3:2 = memd(R29 + #_PT_ER_VMPSP);240240+ trap1(#HVM_TRAP1_VMSETREGS);241241+242242+ R0 = R29243243+ restore_pt_regs()244244+ R1:0 = memd(R29 + #_PT_R0100);245245+ R29 = add(R29, #_PT_REGS_SIZE);246246+ trap1(#HVM_TRAP1_VMRTE)247247+ /* Notreached */248248+249249+ .globl _K_enter_genex250250+_K_enter_genex:251251+ vm_event_entry(do_genex)252252+253253+ .globl _K_enter_interrupt254254+_K_enter_interrupt:255255+ vm_event_entry(arch_do_IRQ)256256+257257+ .globl _K_enter_trap0258258+_K_enter_trap0:259259+ vm_event_entry(do_trap0)260260+261261+ .globl _K_enter_machcheck262262+_K_enter_machcheck:263263+ vm_event_entry(do_machcheck)264264+265265+266266+ .globl ret_from_fork267267+ret_from_fork:268268+ call schedule_tail269269+ jump return_from_syscall
+101
arch/hexagon/kernel/vm_events.c
···11+/*22+ * Mostly IRQ support for Hexagon33+ *44+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 and88+ * only version 2 as published by the Free Software Foundation.99+ *1010+ * This program is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this program; if not, write to the Free Software1717+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1818+ * 02110-1301, USA.1919+ */2020+2121+#include <linux/kernel.h>2222+#include <asm/registers.h>2323+#include <linux/irq.h>2424+#include <linux/hardirq.h>2525+#include <asm/system.h>2626+2727+/*2828+ * show_regs - print pt_regs structure2929+ * @regs: pointer to pt_regs3030+ *3131+ * To-do: add all the accessor definitions to registers.h3232+ *3333+ * Will make this routine a lot easier to write.3434+ */3535+void show_regs(struct pt_regs *regs)3636+{3737+ printk(KERN_EMERG "restart_r0: \t0x%08lx syscall_nr: %ld\n",3838+ regs->restart_r0, regs->syscall_nr);3939+ printk(KERN_EMERG "preds: \t\t0x%08lx\n", regs->preds);4040+ printk(KERN_EMERG "lc0: \t0x%08lx sa0: 0x%08lx m0: 0x%08lx\n",4141+ regs->lc0, regs->sa0, regs->m0);4242+ printk(KERN_EMERG "lc1: \t0x%08lx sa1: 0x%08lx m1: 0x%08lx\n",4343+ regs->lc1, regs->sa1, regs->m1);4444+ printk(KERN_EMERG "gp: \t0x%08lx ugp: 0x%08lx usr: 0x%08lx\n",4545+ regs->gp, regs->ugp, regs->usr);4646+ printk(KERN_EMERG "r0: \t0x%08lx %08lx %08lx %08lx\n", regs->r00,4747+ regs->r01,4848+ regs->r02,4949+ regs->r03);5050+ printk(KERN_EMERG "r4: \t0x%08lx %08lx %08lx %08lx\n", regs->r04,5151+ regs->r05,5252+ regs->r06,5353+ regs->r07);5454+ printk(KERN_EMERG "r8: \t0x%08lx %08lx %08lx %08lx\n", regs->r08,5555+ regs->r09,5656+ regs->r10,5757+ regs->r11);5858+ printk(KERN_EMERG "r12: \t0x%08lx %08lx %08lx %08lx\n", regs->r12,5959+ regs->r13,6060+ regs->r14,6161+ regs->r15);6262+ printk(KERN_EMERG "r16: \t0x%08lx %08lx %08lx %08lx\n", regs->r16,6363+ regs->r17,6464+ regs->r18,6565+ regs->r19);6666+ printk(KERN_EMERG "r20: \t0x%08lx %08lx %08lx %08lx\n", regs->r20,6767+ regs->r21,6868+ regs->r22,6969+ regs->r23);7070+ printk(KERN_EMERG "r24: \t0x%08lx %08lx %08lx %08lx\n", regs->r24,7171+ regs->r25,7272+ regs->r26,7373+ regs->r27);7474+ printk(KERN_EMERG "r28: \t0x%08lx %08lx %08lx %08lx\n", regs->r28,7575+ regs->r29,7676+ regs->r30,7777+ regs->r31);7878+7979+ printk(KERN_EMERG "elr: \t0x%08lx cause: 0x%08lx user_mode: %d\n",8080+ pt_elr(regs), pt_cause(regs), user_mode(regs));8181+ printk(KERN_EMERG "psp: \t0x%08lx badva: 0x%08lx int_enabled: %d\n",8282+ pt_psp(regs), pt_badva(regs), ints_enabled(regs));8383+}8484+8585+void dummy_handler(struct pt_regs *regs)8686+{8787+ unsigned int elr = pt_elr(regs);8888+ printk(KERN_ERR "Unimplemented handler; ELR=0x%08x\n", elr);8989+}9090+9191+9292+void arch_do_IRQ(struct pt_regs *regs)9393+{9494+ int irq = pt_cause(regs);9595+ struct pt_regs *old_regs = set_irq_regs(regs);9696+9797+ irq_enter();9898+ generic_handle_irq(irq);9999+ irq_exit();100100+ set_irq_regs(old_regs);101101+}
···11+/*22+ * Hexagon VM instruction support33+ *44+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 and88+ * only version 2 as published by the Free Software Foundation.99+ *1010+ * This program is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this program; if not, write to the Free Software1717+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1818+ * 02110-1301, USA.1919+ */2020+2121+#include <linux/linkage.h>2222+#include <asm/hexagon_vm.h>2323+2424+/*2525+ * C wrappers for virtual machine "instructions". These2626+ * could be, and perhaps some day will be, handled as in-line2727+ * macros, but for tracing/debugging it's handy to have2828+ * a single point of invocation for each of them.2929+ * Conveniently, they take paramters and return values3030+ * consistent with the ABI calling convention.3131+ */3232+3333+ENTRY(__vmrte)3434+ trap1(#HVM_TRAP1_VMRTE);3535+ jumpr R31;3636+3737+ENTRY(__vmsetvec)3838+ trap1(#HVM_TRAP1_VMSETVEC);3939+ jumpr R31;4040+4141+ENTRY(__vmsetie)4242+ trap1(#HVM_TRAP1_VMSETIE);4343+ jumpr R31;4444+4545+ENTRY(__vmgetie)4646+ trap1(#HVM_TRAP1_VMGETIE);4747+ jumpr R31;4848+4949+ENTRY(__vmintop)5050+ trap1(#HVM_TRAP1_VMINTOP);5151+ jumpr R31;5252+5353+ENTRY(__vmclrmap)5454+ trap1(#HVM_TRAP1_VMCLRMAP);5555+ jumpr R31;5656+5757+ENTRY(__vmnewmap)5858+ r1 = #VM_NEWMAP_TYPE_PGTABLES;5959+ trap1(#HVM_TRAP1_VMNEWMAP);6060+ jumpr R31;6161+6262+ENTRY(__vmcache)6363+ trap1(#HVM_TRAP1_VMCACHE);6464+ jumpr R31;6565+6666+ENTRY(__vmgettime)6767+ trap1(#HVM_TRAP1_VMGETTIME);6868+ jumpr R31;6969+7070+ENTRY(__vmsettime)7171+ trap1(#HVM_TRAP1_VMSETTIME);7272+ jumpr R31;7373+7474+ENTRY(__vmwait)7575+ trap1(#HVM_TRAP1_VMWAIT);7676+ jumpr R31;7777+7878+ENTRY(__vmyield)7979+ trap1(#HVM_TRAP1_VMYIELD);8080+ jumpr R31;8181+8282+ENTRY(__vmstart)8383+ trap1(#HVM_TRAP1_VMSTART);8484+ jumpr R31;8585+8686+ENTRY(__vmstop)8787+ trap1(#HVM_TRAP1_VMSTOP);8888+ jumpr R31;8989+9090+ENTRY(__vmvpid)9191+ trap1(#HVM_TRAP1_VMVPID);9292+ jumpr R31;9393+9494+/* Probably not actually going to use these; see vm_entry.S */9595+9696+ENTRY(__vmsetregs)9797+ trap1(#HVM_TRAP1_VMSETREGS);9898+ jumpr R31;9999+100100+ENTRY(__vmgetregs)101101+ trap1(#HVM_TRAP1_VMGETREGS);102102+ jumpr R31;
+95
arch/hexagon/kernel/vm_switch.S
···11+/*22+ * Context switch support for Hexagon33+ *44+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 and88+ * only version 2 as published by the Free Software Foundation.99+ *1010+ * This program is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this program; if not, write to the Free Software1717+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1818+ * 02110-1301, USA.1919+ */2020+2121+#include <asm/asm-offsets.h>2222+2323+.text2424+2525+/*2626+ * The register used as a fast-path thread information pointer2727+ * is determined as a kernel configuration option. If it happens2828+ * to be a callee-save register, we're going to be saving and2929+ * restoring it twice here.3030+ *3131+ * This code anticipates a revised ABI where R20-23 are added3232+ * to the set of callee-save registers, but this should be3333+ * backward compatible to legacy tools.3434+ */3535+3636+3737+/*3838+ * void switch_to(struct task_struct *prev,3939+ * struct task_struct *next, struct task_struct *last);4040+ */4141+ .p2align 24242+ .globl __switch_to4343+ .type __switch_to, @function4444+4545+/*4646+ * When we exit the wormhole, we need to store the previous task4747+ * in the new R0's pointer. Technically it should be R2, but they should4848+ * be the same; seems like a legacy thing. In short, don't butcher4949+ * R0, let it go back out unmolested.5050+ */5151+5252+__switch_to:5353+ /*5454+ * Push callee-saves onto "prev" stack.5555+ * Here, we're sneaky because the LR and FP5656+ * storage of the thread_stack structure5757+ * is automagically allocated by allocframe,5858+ * so we pass struct size less 8.5959+ */6060+ allocframe(#(_SWITCH_STACK_SIZE - 8));6161+ memd(R29+#(_SWITCH_R2726))=R27:26;6262+ memd(R29+#(_SWITCH_R2524))=R25:24;6363+ memd(R29+#(_SWITCH_R2322))=R23:22;6464+ memd(R29+#(_SWITCH_R2120))=R21:20;6565+ memd(R29+#(_SWITCH_R1918))=R19:18;6666+ memd(R29+#(_SWITCH_R1716))=R17:16;6767+ /* Stash thread_info pointer in task_struct */6868+ memw(R0+#_TASK_THREAD_INFO) = THREADINFO_REG;6969+ memw(R0 +#(_TASK_STRUCT_THREAD + _THREAD_STRUCT_SWITCH_SP)) = R29;7070+ /* Switch to "next" stack and restore callee saves from there */7171+ R29 = memw(R1 + #(_TASK_STRUCT_THREAD + _THREAD_STRUCT_SWITCH_SP));7272+ {7373+ R27:26 = memd(R29+#(_SWITCH_R2726));7474+ R25:24 = memd(R29+#(_SWITCH_R2524));7575+ }7676+ {7777+ R23:22 = memd(R29+#(_SWITCH_R2322));7878+ R21:20 = memd(R29+#(_SWITCH_R2120));7979+ }8080+ {8181+ R19:18 = memd(R29+#(_SWITCH_R1918));8282+ R17:16 = memd(R29+#(_SWITCH_R1716));8383+ }8484+ {8585+ /* THREADINFO_REG is currently one of the callee-saved regs8686+ * above, and so be sure to re-load it last.8787+ */8888+ THREADINFO_REG = memw(R1 + #_TASK_THREAD_INFO);8989+ R31:30 = memd(R29+#_SWITCH_FP);9090+ }9191+ {9292+ R29 = add(R29,#_SWITCH_STACK_SIZE);9393+ jumpr R31;9494+ }9595+ .size __switch_to, .-__switch_to
+48
arch/hexagon/kernel/vm_vectors.S
···11+/*22+ * Event jump tables33+ *44+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License version 2 and88+ * only version 2 as published by the Free Software Foundation.99+ *1010+ * This program is distributed in the hope that it will be useful,1111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313+ * GNU General Public License for more details.1414+ *1515+ * You should have received a copy of the GNU General Public License1616+ * along with this program; if not, write to the Free Software1717+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1818+ * 02110-1301, USA.1919+ */2020+2121+#include <asm/hexagon_vm.h>2222+2323+.text2424+2525+/* This is registered early on to allow angel */2626+.global _K_provisional_vec2727+_K_provisional_vec:2828+ jump 1f;2929+ jump 1f;3030+ jump 1f;3131+ jump 1f;3232+ jump 1f;3333+ trap1(#HVM_TRAP1_VMRTE)3434+ jump 1f;3535+ jump 1f;3636+3737+3838+.global _K_VM_event_vector3939+_K_VM_event_vector:4040+1:4141+ jump 1b; /* Reset */4242+ jump _K_enter_machcheck;4343+ jump _K_enter_genex;4444+ jump 1b; /* 3 Rsvd */4545+ jump 1b; /* 4 Rsvd */4646+ jump _K_enter_trap0;4747+ jump 1b; /* 6 Rsvd */4848+ jump _K_enter_interrupt;