📄 xenasm.s
字号:
/* * Assembly support routines for Xen/ia64 * * Copyright (C) 2004 Hewlett-Packard Co * Dan Magenheimer <dan.magenheimer@hp.com> * * Copyright (C) 2007 VA Linux Systems Japan K.K. * Isaku Yamahata <yamahata at valinux co jp> * ia64_copy_rbs() */#include <linux/config.h>#include <asm/asmmacro.h>#include <asm/processor.h>#include <asm/pgtable.h>#include <asm/vhpt.h>#include <asm/asm-xsi-offsets.h>#include <asm/vmmu.h>#include <public/xen.h> // Change rr7 to the passed value while ensuring// Xen is mapped into the new region.#define PSR_BITS_TO_CLEAR \ (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \ IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ IA64_PSR_DFL | IA64_PSR_DFH | IA64_PSR_IC)// FIXME? Note that this turns off the DB bit (debug)#define PSR_BITS_TO_SET IA64_PSR_BN//extern void ia64_new_rr7(unsigned long rid, /* in0 */// void *shared_info, /* in1 */// void *shared_arch_info, /* in2 */// unsigned long shared_info_va, /* in3 */// unsigned long va_vhpt) /* in4 *///Local usage:// loc0=rp, loc1=ar.pfs, loc2=percpu_paddr, loc3=psr, loc4=ar.rse// loc5=pal_vaddr, loc6=xen_paddr, loc7=shared_archinfo_paddr,// r16, r19, r20 are used by ia64_switch_mode_{phys, virt}()GLOBAL_ENTRY(ia64_new_rr7) // FIXME? not sure this unwind statement is correct... .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1) alloc loc1 = ar.pfs, 5, 8, 0, 0 movl loc2=PERCPU_ADDR1: { mov loc3 = psr // save psr mov loc0 = rp // save rp mov r8 = ip // save ip to compute branch };; .body tpa loc2=loc2 // grab this BEFORE changing rr7 tpa in1=in1 // grab shared_info BEFORE changing rr7 adds r8 = 1f-1b,r8 // calculate return address for call ;; tpa loc7=in2 // grab arch_vcpu_info BEFORE chg rr7 movl r17=PSR_BITS_TO_SET mov loc4=ar.rsc // save RSE configuration movl r16=PSR_BITS_TO_CLEAR ;; tpa r8=r8 // convert rp to physical mov ar.rsc=0 // put RSE in enforced lazy, LE mode or loc3=loc3,r17 // add in psr the bits to set ;; movl loc5=pal_vaddr // get pal_vaddr ;; ld8 loc5=[loc5] // read pal_vaddr ;; andcm r16=loc3,r16 // removes bits to clear from psr dep loc6=0,r8,0,KERNEL_TR_PAGE_SHIFT // Xen code paddr br.call.sptk.many rp=ia64_switch_mode_phys1: // now in physical mode with psr.i/ic off so do rr7 switch dep r16=-1,r0,61,3 // Note: belong to region 7! ;; mov rr[r16]=in0 ;; srlz.d ;; movl r26=PAGE_KERNEL ;; // re-pin mappings for kernel text and data mov r24=KERNEL_TR_PAGE_SHIFT<<2 movl r17=KERNEL_START ;; ptr.i r17,r24 ptr.d r17,r24 mov r16=IA64_TR_KERNEL mov cr.itir=r24 mov cr.ifa=r17 or r18=loc6,r26 ;; itr.i itr[r16]=r18 ;; itr.d dtr[r16]=r18 ;; /* xen heap is also identity mapped */ mov r16 = IA64_TR_XEN_HEAP_REGS dep r17=-1,loc6,60,4 ;; ptr.d r17,r24 ;; mov cr.ifa=r17 ;; itr.d dtr[r16]=r18 ;; // re-pin mappings for stack (current) // unless overlaps with KERNEL_TR dep r18=0,r13,0,KERNEL_TR_PAGE_SHIFT ;; cmp.eq p7,p0=r17,r18(p7) br.cond.sptk .stack_overlaps mov r25=IA64_GRANULE_SHIFT<<2 dep r21=0,r13,60,4 // physical address of "current" ;; ptr.d r13,r25 or r23=r21,r26 // construct PA | page properties mov cr.itir=r25 mov cr.ifa=r13 // VA of next task... mov r21=IA64_TR_CURRENT_STACK ;; itr.d dtr[r21]=r23 // wire in new mapping... // Per-cpu .stack_overlaps: mov r24=PERCPU_PAGE_SHIFT<<2 movl r22=PERCPU_ADDR ;; ptr.d r22,r24 or r23=loc2,r26 // construct PA | page properties mov cr.itir=r24 mov cr.ifa=r22 mov r25=IA64_TR_PERCPU_DATA ;; itr.d dtr[r25]=r23 // wire in new mapping... // VHPT#if VHPT_ENABLED#if IA64_GRANULE_SHIFT < VHPT_SIZE_LOG2#error "it must be that VHPT_SIZE_LOG2 <= IA64_GRANULE_SHIFT"#endif // unless overlaps with KERNEL_TR and IA64_TR_CURRENT_STACK dep r14=0,in4,0,KERNEL_TR_PAGE_SHIFT dep r15=0,in4,0,IA64_GRANULE_SHIFT dep r21=0,r13,0,IA64_GRANULE_SHIFT ;; cmp.eq p7,p0=r17,r14 cmp.eq p8,p0=r15,r21(p7) br.cond.sptk .vhpt_overlaps(p8) br.cond.sptk .vhpt_overlaps mov r21=IA64_TR_VHPT dep r22=0,r15,60,4 // physical address of // va_vhpt & ~(IA64_GRANULE_SIZE - 1) mov r24=IA64_GRANULE_SHIFT<<2 ;; ptr.d r15,r24 or r23=r22,r26 // construct PA | page properties mov cr.itir=r24 mov cr.ifa=r15 srlz.d ;; itr.d dtr[r21]=r23 // wire in new mapping....vhpt_overlaps: #endif // Shared info mov r24=XSI_SHIFT<<2 movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_PRIV | _PAGE_AR_RW) ;; ptr.d in3,r24 or r23=in1,r25 // construct PA | page properties mov cr.itir=r24 mov cr.ifa=in3 mov r21=IA64_TR_SHARED_INFO ;; itr.d dtr[r21]=r23 // wire in new mapping... // Map mapped_regs mov r22=XMAPPEDREGS_OFS mov r24=XMAPPEDREGS_SHIFT<<2 ;; add r22=r22,in3 ;; ptr.d r22,r24 or r23=loc7,r25 // construct PA | page properties mov cr.itir=r24 mov cr.ifa=r22 mov r21=IA64_TR_MAPPED_REGS ;; itr.d dtr[r21]=r23 // wire in new mapping... // Purge/insert PAL TR mov r24=IA64_TR_PALCODE mov r23=IA64_GRANULE_SHIFT<<2 dep r25=0,loc5,60,4 // convert pal vaddr to paddr ;; ptr.i loc5,r23 or r25=r25,r26 // construct PA | page properties mov cr.itir=r23 mov cr.ifa=loc5 ;; itr.i itr[r24]=r25 // done, switch back to virtual and return mov r16=loc3 // r16= original psr br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode mov psr.l = loc3 // restore init PSR mov ar.pfs = loc1 mov rp = loc0 ;; mov ar.rsc=loc4 // restore RSE configuration srlz.d // seralize restoration of psr.l br.ret.sptk.many rpEND(ia64_new_rr7)#if 0 /* Not used */#include "minstate.h"GLOBAL_ENTRY(ia64_prepare_handle_privop) .prologue /* * r16 = fake ar.pfs, we simply need to make sure privilege is still 0 */ mov r16=r0 DO_SAVE_SWITCH_STACK br.call.sptk.many rp=ia64_handle_privop // stack frame setup in ivt.ret22: .body DO_LOAD_SWITCH_STACK br.cond.sptk.many rp // goes to ia64_leave_kernelEND(ia64_prepare_handle_privop)GLOBAL_ENTRY(ia64_prepare_handle_break) .prologue /* * r16 = fake ar.pfs, we simply need to make sure privilege is still 0 */ mov r16=r0 DO_SAVE_SWITCH_STACK br.call.sptk.many rp=ia64_handle_break // stack frame setup in ivt.ret23: .body DO_LOAD_SWITCH_STACK br.cond.sptk.many rp // goes to ia64_leave_kernelEND(ia64_prepare_handle_break)GLOBAL_ENTRY(ia64_prepare_handle_reflection) .prologue /* * r16 = fake ar.pfs, we simply need to make sure privilege is still 0 */ mov r16=r0 DO_SAVE_SWITCH_STACK br.call.sptk.many rp=ia64_handle_reflection // stack frame setup in ivt.ret24: .body DO_LOAD_SWITCH_STACK br.cond.sptk.many rp // goes to ia64_leave_kernelEND(ia64_prepare_handle_reflection)#endifGLOBAL_ENTRY(__get_domain_bundle) EX(.failure_in_get_bundle,ld8 r8=[r32],8) ;; EX(.failure_in_get_bundle,ld8 r9=[r32]) ;; br.ret.sptk.many rp ;;.failure_in_get_bundle: mov r8=0 ;; mov r9=0 ;; br.ret.sptk.many rp ;;END(__get_domain_bundle)/* derived from linux/arch/ia64/hp/sim/boot/boot_head.S */GLOBAL_ENTRY(pal_emulator_static) mov r8=-1 mov r9=256 ;; cmp.gtu p7,p8=r9,r32 /* r32 <= 255? */(p7) br.cond.sptk.few static ;; mov r9=512 ;; cmp.gtu p7,p8=r9,r32(p7) br.cond.sptk.few stacked ;;static: cmp.eq p7,p8=6,r32 /* PAL_PTCE_INFO */(p8) br.cond.sptk.few 1f ;; mov r8=0 /* status = 0 */ movl r9=0x100000000 /* tc.base */ movl r10=0x0000000200000003 /* count[0], count[1] */ movl r11=0x1000000000002000 /* stride[0], stride[1] */ br.ret.sptk.few rp1: cmp.eq p7,p8=14,r32 /* PAL_FREQ_RATIOS */(p8) br.cond.sptk.few 1f mov r8=0 /* status = 0 */ movl r9 =0x900000002 /* proc_ratio (1/100) */ movl r10=0x100000100 /* bus_ratio<<32 (1/256) */ movl r11=0x900000002 /* itc_ratio<<32 (1/100) */ ;;1: cmp.eq p7,p8=19,r32 /* PAL_RSE_INFO */(p8) br.cond.sptk.few 1f mov r8=0 /* status = 0 */ mov r9=96 /* num phys stacked */ mov r10=0 /* hints */ mov r11=0 br.ret.sptk.few rp1: cmp.eq p7,p8=1,r32 /* PAL_CACHE_FLUSH */(p8) br.cond.sptk.few 1f#if 0 mov r9=ar.lc movl r8=524288 /* flush 512k million cache lines (16MB) */ ;; mov ar.lc=r8 movl r8=0xe000000000000000 ;;.loop: fc r8 add r8=32,r8 br.cloop.sptk.few .loop sync.i ;; srlz.i ;; mov ar.lc=r9 mov r8=r0 ;;1: cmp.eq p7,p8=15,r32 /* PAL_PERF_MON_INFO */(p8) br.cond.sptk.few 1f mov r8=0 /* status = 0 */ movl r9 =0x08122f04 /* generic=4 width=47 retired=8 * cycles=18 */ mov r10=0 /* reserved */ mov r11=0 /* reserved */ mov r16=0xffff /* implemented PMC */ mov r17=0x3ffff /* implemented PMD */ add r18=8,r29 /* second index */ ;; st8 [r29]=r16,16 /* store implemented PMC */ st8 [r18]=r0,16 /* clear remaining bits */ ;; st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ ;; st8 [r29]=r17,16 /* store implemented PMD */ st8 [r18]=r0,16 /* clear remaining bits */ mov r16=0xf0 /* cycles count capable PMC */ ;; st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ mov r17=0xf0 /* retired bundles capable PMC */ ;; st8 [r29]=r16,16 /* store cycles capable */ st8 [r18]=r0,16 /* clear remaining bits */ ;; st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ ;; st8 [r29]=r17,16 /* store retired bundle capable */ st8 [r18]=r0,16 /* clear remaining bits */ ;; st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ ;;1: br.cond.sptk.few rp#else1:#endifstacked: br.ret.sptk.few rpEND(pal_emulator_static)// void ia64_copy_rbs(unsigned long* dst_bspstore, unsigned long* dst_rbs_size,// unsigned long* dst_rnat_p,// unsigned long* src_bsp, unsigned long src_rbs_size,// unsigned long src_rnat);// Caller must mask interrupions.// Caller must ensure that src_rbs_size isn't larger than the number// of physical stacked registers. otherwise loadrs fault with Illegal// Operation fault resulting in panic.//// r14 = r32 = dst_bspstore// r15 = r33 = dst_rbs_size_p // r16 = r34 = dst_rnat_p// r17 = r35 = src_bsp// r18 = r36 = src_rbs_size// r19 = r37 = src_rnat //// r20 = saved ar.rsc// r21 = saved ar.bspstore// // r22 = saved_ar_rnat// r23 = saved_ar_rp// r24 = saved_ar_pfs //// we save the value in this register and store it into [dst_rbs_size_p] and// [dst_rnat_p] after rse opeation is done.// r30 = return value of __ia64_copy_rbs to ia64_copy_to_rbs = dst_rbs_size// r31 = return value of __ia64_copy_rbs to ia64_copy_to_rbs = dst_rnat//#define dst_bspstore r14#define dst_rbs_size_p r15#define dst_rnat_p r16#define src_bsp r17#define src_rbs_size r18#define src_rnat r19#define saved_ar_rsc r20#define saved_ar_bspstore r21#define saved_ar_rnat r22#define saved_rp r23#define saved_ar_pfs r24#define dst_rbs_size r30#define dst_rnat r31ENTRY(__ia64_copy_rbs) .prologue .fframe 0 // Here cfm.{sof, sol, sor, rrb}=0 // // flush current register stack to backing store{ flushrs // must be first isns in group srlz.i} // switch to enforced lazy mode mov saved_ar_rsc = ar.rsc ;; mov ar.rsc = 0 ;; .save ar.bspstore, saved_ar_bspstore mov saved_ar_bspstore = ar.bspstore .save ar.rnat, saved_ar_rnat mov saved_ar_rnat = ar.rnat ;; .body // load from src mov ar.bspstore = src_bsp ;; mov ar.rnat = src_rnat shl src_rbs_size = src_rbs_size,16 ;; mov ar.rsc = src_rbs_size ;;{ loadrs // must be first isns in group ;;} // flush to dst mov ar.bspstore = dst_bspstore ;;{ flushrs // must be first isns in group srlz.i} ;; mov dst_rbs_size = ar.bsp mov dst_rnat = ar.rnat ;; sub dst_rbs_size = dst_rbs_size, dst_bspstore // switch back to the original backing store .restorereg ar.bspstore mov ar.bspstore = saved_ar_bspstore ;; .restorereg ar.rnat mov ar.rnat = saved_ar_rnat ;; // restore rsc mov ar.rsc = saved_ar_rsc ;; br.ret.sptk.many rpEND(__ia64_copy_rbs)GLOBAL_ENTRY(ia64_copy_rbs) .prologue .fframe 0 .save ar.pfs, saved_ar_pfs alloc saved_ar_pfs = ar.pfs, 6, 0, 0, 0 .save.b 0x1, saved_rp mov saved_rp = rp .body // we play with register backing store so that we can't use // stacked registers. // save in0-in5 to static scratch registres mov dst_bspstore = r32 mov dst_rbs_size_p = r33 mov dst_rnat_p = r34 mov src_bsp = r35 mov src_rbs_size = r36 mov src_rnat = r37 ;; // set cfm.{sof, sol, sor, rrb}=0 to avoid nasty stacked register // issues related to cover by calling void __ia64_copy_rbs(void). // cfm.{sof, sol, sor, rrb}=0 makes things easy. br.call.sptk.many rp = __ia64_copy_rbs st8 [dst_rbs_size_p] = dst_rbs_size st8 [dst_rnat_p] = dst_rnat .restorereg ar.pfs mov ar.pfs = saved_ar_pfs .restorereg rp mov rp = saved_rp ;; br.ret.sptk.many rpEND(ia64_copy_rbs)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -