ia64/xen-unstable

changeset 12447:2afdc0066df6

[IA64] MCA support - Add percpu data physical addr mca_asm.S

Signed-off-by: Yutaka Ezaki <yutaka.ezaki@jp.fujitsu.com>
Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Kazuhiro Suzuki <kaz@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Sun Oct 29 09:27:11 2006 -0700 (2006-10-29)
parents dc4a352d2143
children efb346a02e70
files xen/arch/ia64/linux-xen/mca_asm.S
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/mca_asm.S	Sun Oct 29 09:27:10 2006 -0700
     1.2 +++ b/xen/arch/ia64/linux-xen/mca_asm.S	Sun Oct 29 09:27:11 2006 -0700
     1.3 @@ -24,6 +24,9 @@
     1.4  #include <asm/processor.h>
     1.5  #include <asm/mca_asm.h>
     1.6  #include <asm/mca.h>
     1.7 +#ifdef XEN
     1.8 +#include <asm/vhpt.h>
     1.9 +#endif
    1.10  
    1.11  /*
    1.12   * When we get a machine check, the kernel stack pointer is no longer
    1.13 @@ -50,8 +53,7 @@
    1.14   */
    1.15  #ifdef XEN
    1.16  #define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)		\
    1.17 -	movl	_tmp=THIS_CPU(ia64_sal_to_os_handoff_state_addr);;	\
    1.18 -	tpa	_tmp=_tmp;;				\
    1.19 +	GET_THIS_PADDR(_tmp, ia64_sal_to_os_handoff_state_addr);;	\
    1.20  	ld8	_tmp=[_tmp];;				\
    1.21  	st8	[_tmp]=r1,0x08;;			\
    1.22  	st8	[_tmp]=r8,0x08;;			\
    1.23 @@ -72,6 +74,7 @@
    1.24  	st8	[_tmp]=r12,0x08;;			\
    1.25  	st8	[_tmp]=r17,0x08;;			\
    1.26  	st8	[_tmp]=r18,0x08
    1.27 +#endif /* XEN */
    1.28  
    1.29  /*
    1.30   * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
    1.31 @@ -101,6 +104,24 @@
    1.32   *	imots_sal_check_ra=Return address to location within SAL_CHECK
    1.33   *
    1.34   */
    1.35 +#ifdef XEN
    1.36 +#define COLD_BOOT_HANDOFF_STATE(sal_to_os_handoff,os_to_sal_handoff,tmp)\
    1.37 +	movl	tmp=IA64_MCA_COLD_BOOT;					\
    1.38 +	GET_THIS_PADDR(r2,ia64_sal_to_os_handoff_state_addr);;		\
    1.39 +	ld8	sal_to_os_handoff=[sal_to_os_handoff];;			\
    1.40 +	movl	os_to_sal_handoff=ia64_os_to_sal_handoff_state;;	\
    1.41 +	dep	os_to_sal_handoff = 0, os_to_sal_handoff, 60, 4;;	\
    1.42 +	/*DATA_VA_TO_PA(os_to_sal_handoff);;*/				\
    1.43 +	st8	[os_to_sal_handoff]=tmp,8;;				\
    1.44 +	ld8	tmp=[sal_to_os_handoff],48;;				\
    1.45 +	st8	[os_to_sal_handoff]=tmp,8;;				\
    1.46 +	movl	tmp=IA64_MCA_SAME_CONTEXT;;				\
    1.47 +	st8	[os_to_sal_handoff]=tmp,8;;				\
    1.48 +	ld8	tmp=[sal_to_os_handoff],-8;;				\
    1.49 +	st8     [os_to_sal_handoff]=tmp,8;;				\
    1.50 +	ld8	tmp=[sal_to_os_handoff];;				\
    1.51 +	st8     [os_to_sal_handoff]=tmp;;
    1.52 +#else	/* XEN */
    1.53  #define COLD_BOOT_HANDOFF_STATE(sal_to_os_handoff,os_to_sal_handoff,tmp)\
    1.54  	movl	tmp=IA64_MCA_COLD_BOOT;					\
    1.55  	movl	sal_to_os_handoff=__pa(ia64_sal_to_os_handoff_state);	\
    1.56 @@ -114,13 +135,13 @@
    1.57  	st8     [os_to_sal_handoff]=tmp,8;;				\
    1.58  	ld8	tmp=[sal_to_os_handoff];;				\
    1.59  	st8     [os_to_sal_handoff]=tmp;;
    1.60 +#endif	/* XEN */
    1.61  
    1.62  #define GET_IA64_MCA_DATA(reg)						\
    1.63  	GET_THIS_PADDR(reg, ia64_mca_data)				\
    1.64  	;;								\
    1.65  	ld8 reg=[reg]
    1.66  
    1.67 -#endif /* XEN */
    1.68  	.global ia64_os_mca_dispatch
    1.69  	.global ia64_os_mca_dispatch_end
    1.70  #ifndef XEN
    1.71 @@ -132,7 +153,40 @@
    1.72  	.text
    1.73  	.align 16
    1.74  
    1.75 -#ifndef XEN
    1.76 +#ifdef	XEN
    1.77 +/*
    1.78 + * void set_per_cpu_data(void)
    1.79 + * {
    1.80 + *   int i;
    1.81 + *   for (i = 0; i < 64; i++) {
    1.82 + *     if (ia64_mca_tlb_list[i].cr_lid == ia64_getreg(_IA64_REG_CR_LID)) {
    1.83 + *       ia64_set_kr(IA64_KR_PER_CPU_DATA, ia64_mca_tlb_list[i].percpu_paddr);
    1.84 + *       return;
    1.85 + *     }
    1.86 + *   }
    1.87 + *   while(1);	// Endless loop on error
    1.88 + * }
    1.89 + */
    1.90 +#define SET_PER_CPU_DATA()					\
    1.91 +	LOAD_PHYSICAL(p0,r2,ia64_mca_tlb_list);;		\
    1.92 +	mov r7 = r0;						\
    1.93 +	mov r6 = r0;;						\
    1.94 +	adds r3 = IA64_MCA_PERCPU_OFFSET, r2;			\
    1.95 +1:	add r4 = r6, r2;					\
    1.96 +	mov r5=cr.lid;;						\
    1.97 +	adds r7 = 1, r7;					\
    1.98 +	ld8 r4 = [r4];;						\
    1.99 +	cmp.ne p6, p7 = r5, r4;					\
   1.100 +	cmp4.lt p8, p9 = NR_CPUS-1, r7;				\
   1.101 +(p7)	br.cond.dpnt 3f;					\
   1.102 +	adds r6 = 16, r6;					\
   1.103 +(p9) 	br.cond.sptk 1b;					\
   1.104 +2:	br 2b;;			/* Endless loop on error */	\
   1.105 +3:	add r4 = r6, r3;;					\
   1.106 +	ld8 r4 = [r4];;						\
   1.107 +	mov ar.k3=r4
   1.108 +#endif	/* XEN */
   1.109 +
   1.110  /*
   1.111   * Just the TLB purge part is moved to a separate function
   1.112   * so we can re-use the code for cpu hotplug code as well
   1.113 @@ -221,6 +275,44 @@ 4:
   1.114  	;;
   1.115  	srlz.i
   1.116  	;;
   1.117 +#ifdef XEN
   1.118 +	// 5. VHPT
   1.119 +#if VHPT_ENABLED
   1.120 +	// r25 = __va_ul(vcpu_vhpt_maddr(v));
   1.121 +	GET_THIS_PADDR(r2,cpu_kr);;
   1.122 +	add r2=IA64_KR_CURRENT_OFFSET,r2;;
   1.123 +	ld8 r2=[r2];;
   1.124 +#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
   1.125 +#define HAS_PERVCPU_VHPT_MASK	0x2
   1.126 +	dep r3=0,r2,60,4;;			// virtual to physical
   1.127 +	add r3=IA64_VCPU_DOMAIN_OFFSET,r3;;
   1.128 +	ld8 r3=[r3];; 
   1.129 +	dep r3=0,r3,60,4;;			// virtual to physical
   1.130 +	add r3=IA64_DOMAIN_FLAGS_OFFSET,r3;;
   1.131 +	ld8 r3=[r3];; 
   1.132 +	and r3=HAS_PERVCPU_VHPT_MASK,r3;;
   1.133 +	cmp.eq p6,p0=r3,r0;;
   1.134 +(p6)	br.cond.sptk	.not_pervcpu_vhpt
   1.135 +	add r2=IA64_VCPU_VHPT_MADDR_OFFSET,r2;;
   1.136 +	dep r2=0,r2,60,4;;			// virtual to physical
   1.137 +	ld8 r2=[r2];; 
   1.138 +	dep r25=-1,r2,60,4;;			// physical to virtual
   1.139 +	br.sptk		.percpu_vhpt_done
   1.140 +#endif
   1.141 +.not_pervcpu_vhpt:
   1.142 +	GET_THIS_PADDR(r2, vhpt_paddr);; 
   1.143 +	ld8 r2=[r2];; 
   1.144 +	dep r25=-1,r2,60,4;;			// physical to virtual
   1.145 +.percpu_vhpt_done:
   1.146 +	dep r20=0,r25,0,IA64_GRANULE_SHIFT
   1.147 +	mov r24=IA64_GRANULE_SHIFT<<2
   1.148 +	;;
   1.149 +	ptr.d r20,r24
   1.150 +	;;
   1.151 +	srlz.d
   1.152 +	;;
   1.153 +#endif
   1.154 +#endif
   1.155  	// Now branch away to caller.
   1.156  	br.sptk.many b1
   1.157  	;;
   1.158 @@ -235,6 +327,9 @@ ia64_os_mca_spin:
   1.159  	cmp.ne	p6,p0=r4,r0
   1.160  (p6)	br ia64_os_mca_spin
   1.161  
   1.162 +#ifdef XEN
   1.163 +	SET_PER_CPU_DATA();;
   1.164 +#endif
   1.165  	// Save the SAL to OS MCA handoff state as defined
   1.166  	// by SAL SPEC 3.0
   1.167  	// NOTE : The order in which the state gets saved
   1.168 @@ -250,7 +345,19 @@ begin_os_mca_dump:
   1.169  
   1.170  ia64_os_mca_done_dump:
   1.171  
   1.172 +#ifdef XEN
   1.173 +	// Set current to ar.k6
   1.174 +	GET_THIS_PADDR(r2,cpu_kr);;
   1.175 +	add r2=IA64_KR_CURRENT_OFFSET,r2;;
   1.176 +	ld8 r2=[r2];;
   1.177 +	mov ar.k6=r2;;
   1.178 +
   1.179 +	GET_THIS_PADDR(r2,ia64_sal_to_os_handoff_state_addr);;
   1.180 +	ld8 r2=[r2];;
   1.181 +	adds r16=56,r2
   1.182 +#else
   1.183  	LOAD_PHYSICAL(p0,r16,ia64_sal_to_os_handoff_state+56)
   1.184 +#endif
   1.185  	;;
   1.186  	ld8 r18=[r16]		// Get processor state parameter on existing PALE_CHECK.
   1.187  	;;
   1.188 @@ -342,6 +449,28 @@ ia64_reload_tr:
   1.189  	;;
   1.190  	srlz.d
   1.191  	;;
   1.192 +#ifdef XEN
   1.193 +	// 5. VHPT
   1.194 +#if VHPT_ENABLED
   1.195 +	// r25 = __va_ul(vcpu_vhpt_maddr(v));
   1.196 +	dep r20=0,r25,0,IA64_GRANULE_SHIFT
   1.197 +	movl r26=PAGE_KERNEL
   1.198 +	;;
   1.199 +	mov r21=IA64_TR_VHPT
   1.200 +	dep r22=0,r20,60,4		// physical address of
   1.201 +	                                // va_vhpt & ~(IA64_GRANULE_SIZE - 1)
   1.202 +	mov r24=IA64_GRANULE_SHIFT<<2
   1.203 +	;;
   1.204 +	or r23=r22,r26			// construct PA | page properties
   1.205 +	mov cr.itir=r24
   1.206 +	mov cr.ifa=r20
   1.207 +	;;
   1.208 +	itr.d dtr[r21]=r23		// wire in new mapping...
   1.209 +	;;
   1.210 +	srlz.d
   1.211 +	;;
   1.212 +#endif
   1.213 +#endif
   1.214  	br.sptk.many done_tlb_purge_and_reload
   1.215  err:
   1.216  	COLD_BOOT_HANDOFF_STATE(r20,r21,r22)
   1.217 @@ -874,12 +1003,6 @@ end_os_mca_restore:
   1.218  	br	ia64_os_mca_done_restore;;
   1.219  
   1.220  //EndStub//////////////////////////////////////////////////////////////////////
   1.221 -#else
   1.222 -ia64_os_mca_dispatch:
   1.223 -1:
   1.224 -	br.sptk 1b
   1.225 -ia64_os_mca_dispatch_end:
   1.226 -#endif /* !XEN */
   1.227  
   1.228  
   1.229  // ok, the issue here is that we need to save state information so
   1.230 @@ -911,6 +1034,15 @@ ia64_os_mca_dispatch_end:
   1.231  
   1.232  GLOBAL_ENTRY(ia64_monarch_init_handler)
   1.233  	.prologue
   1.234 +#ifdef XEN	/* Need in ia64_monarch_init_handler? */
   1.235 +	SET_PER_CPU_DATA();;
   1.236 +
   1.237 +	// Set current to ar.k6
   1.238 +	GET_THIS_PADDR(r2,cpu_kr);;
   1.239 +	add r2=IA64_KR_CURRENT_OFFSET,r2;;
   1.240 +	ld8 r2=[r2];;
   1.241 +	mov ar.k6=r2;;
   1.242 +#endif
   1.243  	// stash the information the SAL passed to os
   1.244  	SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
   1.245  	;;