ivt.s
来自「xen虚拟机源代码安装包」· S 代码 · 共 873 行 · 第 1/2 页
S
873 行
/* * Copyright (c) 2007 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com> * Description: ia64 specific trap handling. * **************************************************************************** * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */#include "asm.h"#include "page.h"#include "ia64_cpu.h"#include "privop.h"#include "offsets.h"/* General register usage in interrupt handling: * r16, r17, ... are used for input parameters of sub-routines * r29: used to access memory which may raise nested TLB fault * r30: b0 save register * r31: predicates save register * p30,p31: used for TLB stuff: (0,1)=data, (1,0)=instruction */#define FILL_FP_PAIR(f1, f2, b1, b2) \ ldf.fill f1=[b1],32 ;\ ldf.fill f2=[b2],32 ;\ ;;#define SPILL_FP_PAIR(f1, f2, b1, b2) \ stf.spill [b1]=f1,32 ;\ stf.spill [b2]=f2,32 ;\ ;;#define FILL_REG_PAIR(r1, r2, b1, b2) \ ld8.fill r1=[b1],16 ;\ ld8.fill r2=[b2],16 ;\ ;;#define SPILL_REG_PAIR(r1, r2, b1, b2) \ .mem.offset 0,0 ;\ st8.spill [b1]=r1,16 ;\ .mem.offset 8,0 ;\ st8.spill [b2]=r2,16 ;\ ;;/** * The function does a store of the current processor context * to the given exception frame address. * These are some special and the scratch registers for calling * C-functions later. * The bspstore will be the same. A clean RSE is made with the * cover instruction. * * The return is done through a jump to the next bundle after ip (r16). * * Used register: r16, r18, r19, r20, r21, r22 of bank 0 * * @param: r16 ip of the bundle with the jump. * @param: r18 pointer to the trap frame. * @param: r23 trap number/err val * */ENTRY(save_tf_rse_switch) movl r21=XSI_IPSR // XEN !! movl r22=XSI_IIP // XEN !! ;; ld8 r21=[r21] // XEN.ipsr ld8 r22=[r22];; // XEN.iip#if defined(BIG_ENDIAN) mux1 r21=r21,@rev // swap because mini-os is in BE mux1 r22=r22,@rev // swap because mini-os is in BE ;;#endif add r19=TF_IPSR,r18 add r20=TF_IIP,r18 ;; st8 [r19]=r21 // store cr.ipsr st8 [r20]=r22 // store cr.iip ;; //// r16 return jump pointer, r18 - trap frame base, add r19=TF_UNAT,r18 mov r20=ar.unat ;; st8 [r19]=r20 // store scratch unat ;; add r19=TF_GP,r18 add r20=TF_SP,r18 ;; st8 [r19]=gp,TF_TP-TF_GP // store gp st8 [r20]=sp,TF_PR-TF_SP // store sp mov r21=pr ;; st8 [r19]=r13 // store tp st8 [r20]=r21 // store pr ;; add r19=TF_GREG2,r18 // Now first general regs. add r20=TF_GREG3,r18 ;; SPILL_REG_PAIR( r2, r3,r19,r20) SPILL_REG_PAIR( r8, r9,r19,r20) SPILL_REG_PAIR(r10,r11,r19,r20) SPILL_REG_PAIR(r14,r15,r19,r20) ;; mov r14=r18 // move trap frame base for bsw mov r15=r16 // save return address ;; //bsw.1 // switch to bank 1 for saving these registers. movl r30=XSI_BANKNUM // Switch to bank 1. mov r31=1;;#if defined(BIG_ENDIAN) mux1 r31=r31,@rev // swap because mini-os is in BE ;;#endif st4 [r30]=r31 ;; /* * On XEN the hypervisor has stored the bank 1 registers * r16-r31. I must reload these registers here to get * access. */ movl r30=XSI_BANK1_R16; movl r31=XSI_BANK1_R16+8;; ld8 r16=[r30],16; ld8 r17=[r31],16;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r16=r16,@rev; mux1 r17=r17,@rev;;#endif ld8 r18=[r30],16; ld8 r19=[r31],16;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r18=r18,@rev; mux1 r19=r19,@rev;;#endif ld8 r20=[r30],16; ld8 r21=[r31],16;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r20=r20,@rev; mux1 r21=r21,@rev;;#endif ld8 r22=[r30],16; ld8 r23=[r31],16;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r22=r22,@rev; mux1 r23=r23,@rev;;#endif ld8 r24=[r30],16; ld8 r25=[r31],16;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r24=r24,@rev; mux1 r25=r25,@rev;;#endif ld8 r26=[r30],16; ld8 r27=[r31],16;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r26=r26,@rev; mux1 r27=r27,@rev;;#endif ld8 r28=[r30],16; ld8 r29=[r31],16;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r28=r28,@rev; mux1 r29=r29,@rev;;#endif ld8 r30=[r30]; ld8 r31=[r31];;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r30=r30,@rev; mux1 r31=r31,@rev;;#endif add r2=TF_GREG16,r14 add r3=TF_GREG17,r14 ;; SPILL_REG_PAIR(r16,r17,r2,r3) SPILL_REG_PAIR(r18,r19,r2,r3) SPILL_REG_PAIR(r20,r21,r2,r3) SPILL_REG_PAIR(r22,r23,r2,r3) SPILL_REG_PAIR(r24,r25,r2,r3) SPILL_REG_PAIR(r26,r27,r2,r3) SPILL_REG_PAIR(r28,r29,r2,r3) SPILL_REG_PAIR(r30,r31,r2,r3) ;; //bsw.0 // back to interrupt bank 0 movl r2=XSI_BANKNUM;; st4 [r2]=r0 ;; mov r18=r14 // restore context pointer mov r16=r15 // restore return address ;; //// r16 return jump pointer, r18 - trap frame base, add r19=TF_CCV,r18 add r20=TF_CSD,r18 mov r21=ar.ccv mov r22=ar.csd ;; st8 [r19]=r21 // ar.ccv st8 [r20]=r22 // ar.csd ;; add r19=TF_SSD,r18 mov r21=ar.ssd ;; st8 [r19]=r21 // ar.ssd ;; add r19=TF_FREG6,r18 add r20=TF_FREG7,r18 ;; SPILL_FP_PAIR(f6, f7, r19, r20) SPILL_FP_PAIR(f8, f9, r19, r20) SPILL_FP_PAIR(f10, f11, r19, r20) add r19=TF_BREG0,r18 // b0, b6, b7 add r20=TF_BREG6,r18 mov r21=b0 mov r22=b6 ;; st8 [r19]=r21,TF_BREG7-TF_BREG0 // store b0 st8 [r20]=r22,16 // store b6 ;; mov r21=b7 ;; st8 [r19]=r21 // store b7 //// r16 return jump pointer, r18 - trap frame base, // Read and save RSC, PFS add r19=TF_PFS,r18 add r20=TF_RSC,r18 mov r21=ar.pfs mov r22=ar.rsc ;;{ .mmb st8 [r19]=r21 // store ar.pfs st8 [r20]=r22 // store ar.rsc // Issue cover instruction cover // must be the last instruction in bundle //XEN_HYPER_COVER ;;} // Read and save IFS add r19=TF_IFS,r18 add r20=TF_CFM,r18 /* xen special handling for possibly lazy cover */ movl r8=XSI_PRECOVER_IFS; ;; ld8 r21=[r8] ;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r21=r21,@rev ;;#endif st8 [r19]=r21 // store cr.ifs dep.z r22=r21,0,38 // copy ifm part from ifs.ifm ;; st8 [r20]=r22 // store cfm // RSE in enforced lazy mode mov ar.rsc=IA64_RSE_LAZY ;; // Read and save BSPSTORE and RNAT add r19=TF_BSP,r18 add r20=TF_RNAT,r18 mov r21=ar.bspstore mov r22=ar.rnat ;; st8 [r19]=r21 // store ar.bspstore st8 [r20]=r22 // store ar.rnat ;; // Write new BSPSTORE //mov r21=ar.bsp //;; mov r22=r21 // new bspstore equal to old ;; mov ar.bspstore=r22 // the new bspstore ;; // Read and save the new BSP for calculating number of dirty regs. mov r21=ar.bsp ;; sub r21=r21,r22 // r21 -> ndirty add r19=TF_NDIRTY-TF_BSP,r19 // TF_NDIRTY pos in r19 ;; st8 [r19]=r21 // store ndirty ;; mov ar.rsc=IA64_RSE_EAGER // RSE on again ;; add r19=TF_FPSR,r18 ;; mov r21=ar.fpsr ;; st8 [r19]=r21 // ar.fpsr ;; //// r16 return jump pointer, r18 - trap frame base, // Load the gp with our module __gp movl gp=__gp ;; add r16=16,r16 // for jump to next bundle ;; mov b7=r16 ;;{ .mfb srlz.d nop 0 br.sptk b7 ;;}END(save_tf_rse_switch)/** * The function reloads the processor context stored in * save_tf_rse_switch(). * * On calling the function the bank 0 must be activ. * The return is done through a rfi. * Used register: b7, r16, r18, r19, r20, r21, r22 of bank 0 * * @param: r18 pointer to the exception frame * */ENTRY(restore_tf_rse_switch) add r19=TF_IPSR,r18 add r20=TF_IIP,r18 ;; ld8 r21=[r19] // load cr.ipsr ld8 r22=[r20] // load cr.iip#if defined(BIG_ENDIAN) // swap because mini-os is in BE ;; mux1 r21=r21,@rev mux1 r22=r22,@rev ;;#endif movl r16=XSI_IPSR // XEN !! ;; st8 [r16]=r21,XSI_IIP_OFS-XSI_IPSR_OFS // XEN.ipsr mov r2=r21 // save for fp stuff below ;; st8 [r16]=r22 // XEN.iip ;; //// r18 - trap frame base // Allocate a zero sized frame alloc r30=ar.pfs,0,0,0,0 // discard current frame ;; // calc number of dirty regs and put this into rsc.loardrs add r19=TF_NDIRTY,r18 ;; ld8 r22=[r19] // ndirty ;; shl r21=r22,16 // value for ar.rsc //mov r19=(MOS_IA64_RSC_BE << IA64_RSC_BE) ;; or r21=(MOS_IA64_RSC_BE << IA64_RSC_BE),r21 ;; mov ar.rsc=r21 // setup for loadrs ;; // Issue a loadrs instruction{ .mmi loadrs // must be the first instruction ;; nop 0x0 nop 0x0} // Restore BSPSTORE from interrupted context add r19=TF_BSP,r18 add r20=TF_RNAT,r18 ;; ld8 r21=[r19] // load ar.bspstore ld8 r22=[r20] // load ar.rnat ;; mov ar.bspstore=r21 // set ar.bspstore ;; // Restore RNAT mov ar.rnat=r22 // set ar.rnat ;; // Restore PFS and IFS add r19=TF_PFS,r18 add r20=TF_IFS,r18 movl r16=XSI_IFS // XEN !! ;; ld8 r21=[r19] // load ar.pfs ld8 r22=[r20] // load cr.ifs ;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r22=r22,@rev ;;#endif add r19=TF_RSC,r18 mov ar.pfs=r21 st8 [r16]=r22 // XEN.ifs ;; // Restore RSC ld8 r21=[r19] // load ar.rsc ;; mov ar.rsc=r21 // set ar.rsc //// r18 - trap frame base add r19=TF_GP,r18 add r20=TF_SP,r18 ;; ld8 gp=[r19],TF_TP-TF_GP // load gp ld8 sp=[r20],TF_PR-TF_SP // load sp ;; ld8 r13=[r19] // load tp ld8 r21=[r20] // load pr ;; mov pr=r21,-1 // set pr ;; add r19=TF_BREG0,r18 add r20=TF_BREG6,r18 ;; ld8 r21=[r19],TF_BREG7-TF_BREG0 // load b0 ld8 r22=[r20],16 // load b6 ;; mov b0=r21 mov b6=r22 ;; ld8 r21=[r19] // load b7 ld8 r22=[r20],16 // load b3 ;; mov b7=r21 //// r18 - trap frame base mov r14=r18 // Save the context pointer ;; // bsw.1 movl r30=XSI_BANKNUM // Switch to bank 1. mov r31=1;;#if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r31=r31,@rev ;;#endif st4 [r30]=r31 ;;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?