ia64/xen-unstable

changeset 9485:3b3a5588baca

[IA64] cache flush

domain_cache_flush added.
SAL_CACHE_FLUSH implemented.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Mon Apr 03 08:33:35 2006 -0600 (2006-04-03)
parents ddc279c91502
children 2da06d15d0f1
files xen/arch/ia64/linux-xen/setup.c xen/arch/ia64/xen/Makefile xen/arch/ia64/xen/dom_fw.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/flushd.S xen/include/asm-ia64/domain.h xen/include/asm-ia64/vhpt.h xen/include/asm-ia64/xenpage.h
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/setup.c	Fri Mar 31 14:04:16 2006 -0700
     1.2 +++ b/xen/arch/ia64/linux-xen/setup.c	Mon Apr 03 08:33:35 2006 -0600
     1.3 @@ -105,6 +105,11 @@ extern void early_cmdline_parse(char **)
     1.4  #define	I_CACHE_STRIDE_SHIFT	5	/* Safest way to go: 32 bytes by 32 bytes */
     1.5  unsigned long ia64_i_cache_stride_shift = ~0;
     1.6  
     1.7 +#ifdef XEN
     1.8 +#define D_CACHE_STRIDE_SHIFT	5	/* Safest.  */
     1.9 +unsigned long ia64_d_cache_stride_shift = ~0;
    1.10 +#endif
    1.11 +
    1.12  /*
    1.13   * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
    1.14   * mask specifies a mask of address bits that must be 0 in order for two buffers to be
    1.15 @@ -718,6 +723,9 @@ get_max_cacheline_size (void)
    1.16                  max = SMP_CACHE_BYTES;
    1.17  		/* Safest setup for "flush_icache_range()" */
    1.18  		ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
    1.19 +#ifdef XEN
    1.20 +		ia64_d_cache_stride_shift = D_CACHE_STRIDE_SHIFT;
    1.21 +#endif
    1.22  		goto out;
    1.23          }
    1.24  
    1.25 @@ -733,6 +741,10 @@ get_max_cacheline_size (void)
    1.26  			cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
    1.27  			cci.pcci_unified = 1;
    1.28  		}
    1.29 +#ifdef XEN
    1.30 +		if (cci.pcci_stride < ia64_d_cache_stride_shift)
    1.31 +			ia64_d_cache_stride_shift = cci.pcci_stride;
    1.32 +#endif
    1.33  		line_size = 1 << cci.pcci_line_size;
    1.34  		if (line_size > max)
    1.35  			max = line_size;
    1.36 @@ -754,6 +766,11 @@ get_max_cacheline_size (void)
    1.37    out:
    1.38  	if (max > ia64_max_cacheline_size)
    1.39  		ia64_max_cacheline_size = max;
    1.40 +#ifdef XEN
    1.41 +	if (ia64_d_cache_stride_shift > ia64_i_cache_stride_shift)
    1.42 +		ia64_d_cache_stride_shift = ia64_i_cache_stride_shift;
    1.43 +#endif
    1.44 +
    1.45  }
    1.46  
    1.47  /*
     2.1 --- a/xen/arch/ia64/xen/Makefile	Fri Mar 31 14:04:16 2006 -0700
     2.2 +++ b/xen/arch/ia64/xen/Makefile	Mon Apr 03 08:33:35 2006 -0600
     2.3 @@ -24,6 +24,7 @@ obj-y += xenmem.o
     2.4  obj-y += xenmisc.o
     2.5  obj-y += xensetup.o
     2.6  obj-y += xentime.o
     2.7 +obj-y += flushd.o
     2.8  
     2.9  obj-$(crash_debug) += gdbstub.o
    2.10  
     3.1 --- a/xen/arch/ia64/xen/dom_fw.c	Fri Mar 31 14:04:16 2006 -0700
     3.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Mon Apr 03 08:33:35 2006 -0600
     3.3 @@ -176,7 +176,9 @@ sal_emulator (long index, unsigned long 
     3.4  		printf("*** CALLED SAL_MC_SET_PARAMS.  IGNORED...\n");
     3.5  		break;
     3.6  	    case SAL_CACHE_FLUSH:
     3.7 -		printf("*** CALLED SAL_CACHE_FLUSH.  IGNORED...\n");
     3.8 +	        /*  The best we can do is to flush with fc all the domain.  */
     3.9 +	        domain_cache_flush (current->domain, in1 == 4 ? 1 : 0);
    3.10 +		status = 0;
    3.11  		break;
    3.12  	    case SAL_CACHE_INIT:
    3.13  		printf("*** CALLED SAL_CACHE_INIT.  IGNORED...\n");
     4.1 --- a/xen/arch/ia64/xen/domain.c	Fri Mar 31 14:04:16 2006 -0700
     4.2 +++ b/xen/arch/ia64/xen/domain.c	Mon Apr 03 08:33:35 2006 -0600
     4.3 @@ -674,6 +674,61 @@ tryagain:
     4.4  	return 0;
     4.5  }
     4.6  
     4.7 +/* Flush cache of domain d.  */
     4.8 +void domain_cache_flush (struct domain *d, int sync_only)
     4.9 +{
    4.10 +	struct mm_struct *mm = d->arch.mm;
    4.11 +	pgd_t *pgd = mm->pgd;
    4.12 +	unsigned long maddr;
    4.13 +	int i,j,k, l;
    4.14 +	int nbr_page = 0;
    4.15 +	void (*flush_func)(unsigned long start, unsigned long end);
    4.16 +	extern void flush_dcache_range (unsigned long, unsigned long);
    4.17 +
    4.18 +	if (sync_only)
    4.19 +		flush_func = &flush_icache_range;
    4.20 +	else
    4.21 +		flush_func = &flush_dcache_range;
    4.22 +
    4.23 +#ifdef CONFIG_DOMAIN0_CONTIGUOUS
    4.24 +	if (d == dom0) {
    4.25 +		/* This is not fully correct (because of hole), but it should
    4.26 +		   be enough for now.  */
    4.27 +		(*flush_func)(__va_ul (dom0_start),
    4.28 +			      __va_ul (dom0_start + dom0_size));
    4.29 +		return;
    4.30 +	}
    4.31 +#endif
    4.32 +	for (i = 0; i < PTRS_PER_PGD; pgd++, i++) {
    4.33 +		pud_t *pud;
    4.34 +		if (!pgd_present(*pgd))
    4.35 +			continue;
    4.36 +		pud = pud_offset(pgd, 0);
    4.37 +		for (j = 0; j < PTRS_PER_PUD; pud++, j++) {
    4.38 +			pmd_t *pmd;
    4.39 +			if (!pud_present(*pud))
    4.40 +				continue;
    4.41 +			pmd = pmd_offset(pud, 0);
    4.42 +			for (k = 0; k < PTRS_PER_PMD; pmd++, k++) {
    4.43 +				pte_t *pte;
    4.44 +				if (!pmd_present(*pmd))
    4.45 +					continue;
    4.46 +				pte = pte_offset_map(pmd, 0);
    4.47 +				for (l = 0; l < PTRS_PER_PTE; pte++, l++) {
    4.48 +					if (!pte_present(*pte))
    4.49 +						continue;
    4.50 +					/* Convert PTE to maddr.  */
    4.51 +					maddr = __va_ul (pte_val(*pte)
    4.52 +							 & _PAGE_PPN_MASK);
    4.53 +					(*flush_func)(maddr, maddr+ PAGE_SIZE);
    4.54 +					nbr_page++;
    4.55 +				}
    4.56 +			}
    4.57 +		}
    4.58 +	}
    4.59 +	//printf ("domain_cache_flush: %d %d pages\n", d->domain_id, nbr_page);
    4.60 +}
    4.61 +
    4.62  // FIXME: ONLY USE FOR DOMAIN PAGE_SIZE == PAGE_SIZE
    4.63  #if 1
    4.64  unsigned long domain_mpa_to_imva(struct domain *d, unsigned long mpaddr)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/arch/ia64/xen/flushd.S	Mon Apr 03 08:33:35 2006 -0600
     5.3 @@ -0,0 +1,62 @@
     5.4 +/*
     5.5 + * Cache flushing routines.
     5.6 + *
     5.7 + * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
     5.8 + *	David Mosberger-Tang <davidm@hpl.hp.com>
     5.9 + *
    5.10 + * 05/28/05 Zoltan Menyhart	Dynamic stride size
    5.11 + * 03/31/06 Tristan Gingold     copied and modified for dcache.
    5.12 + */
    5.13 +
    5.14 +#include <asm/asmmacro.h>
    5.15 +
    5.16 +
    5.17 +	/*
    5.18 +	 * flush_dcache_range(start,end)
    5.19 +	 *
    5.20 +	 *	Flush cache.
    5.21 +	 *
    5.22 +	 *	Must deal with range from start to end-1 but nothing else (need to
    5.23 +	 *	be careful not to touch addresses that may be unmapped).
    5.24 +	 *
    5.25 +	 *	Note: "in0" and "in1" are preserved for debugging purposes.
    5.26 +	 */
    5.27 +GLOBAL_ENTRY(flush_dcache_range)
    5.28 +
    5.29 +	.prologue
    5.30 +	alloc	r2=ar.pfs,2,0,0,0
    5.31 +	movl	r3=ia64_d_cache_stride_shift
    5.32 + 	mov	r21=1
    5.33 +	;;
    5.34 +	ld8	r20=[r3]		// r20: stride shift
    5.35 +	sub	r22=in1,r0,1		// last byte address
    5.36 +	;;
    5.37 +	shr.u	r23=in0,r20		// start / (stride size)
    5.38 +	shr.u	r22=r22,r20		// (last byte address) / (stride size)
    5.39 +	shl	r21=r21,r20		// r21: stride size of the i-cache(s)
    5.40 +	;;
    5.41 +	sub	r8=r22,r23		// number of strides - 1
    5.42 +	shl	r24=r23,r20		// r24: addresses for "fc" =
    5.43 +					//	"start" rounded down to stride boundary
    5.44 +	.save	ar.lc,r3
    5.45 +	mov	r3=ar.lc		// save ar.lc
    5.46 +	;;
    5.47 +
    5.48 +	.body
    5.49 +	mov	ar.lc=r8
    5.50 +	;;
    5.51 +	/*
    5.52 +	 * 32 byte aligned loop, even number of (actually 2) bundles
    5.53 +	 */
    5.54 +.Loop:	fc	r24			// issuable on M0 only
    5.55 +	add	r24=r21,r24		// we flush "stride size" bytes per iteration
    5.56 +	nop.i	0
    5.57 +	br.cloop.sptk.few .Loop
    5.58 +	;;
    5.59 +	sync.i
    5.60 +	;;
    5.61 +	srlz.i
    5.62 +	;;
    5.63 +	mov	ar.lc=r3		// restore ar.lc
    5.64 +	br.ret.sptk.many rp
    5.65 +END(flush_dcache_range)
     6.1 --- a/xen/include/asm-ia64/domain.h	Fri Mar 31 14:04:16 2006 -0700
     6.2 +++ b/xen/include/asm-ia64/domain.h	Mon Apr 03 08:33:35 2006 -0600
     6.3 @@ -13,6 +13,11 @@
     6.4  
     6.5  extern void domain_relinquish_resources(struct domain *);
     6.6  
     6.7 +/* Flush cache of domain d.
     6.8 +   If sync_only is true, only synchronize I&D caches,
     6.9 +   if false, flush and invalidate caches.  */
    6.10 +extern void domain_cache_flush (struct domain *d, int sync_only);
    6.11 +
    6.12  struct arch_domain {
    6.13      struct mm_struct *mm;
    6.14      unsigned long metaphysical_rr0;
     7.1 --- a/xen/include/asm-ia64/vhpt.h	Fri Mar 31 14:04:16 2006 -0700
     7.2 +++ b/xen/include/asm-ia64/vhpt.h	Mon Apr 03 08:33:35 2006 -0600
     7.3 @@ -127,6 +127,7 @@ extern void vhpt_multiple_insert(unsigne
     7.4  extern void vhpt_insert (unsigned long vadr, unsigned long ptr,
     7.5  			 unsigned logps);
     7.6  extern void vhpt_flush(void);
     7.7 +extern void smp_vhpt_flush_all(void);
     7.8  
     7.9  /* Currently the VHPT is allocated per CPU.  */
    7.10  DECLARE_PER_CPU (unsigned long, vhpt_paddr);
     8.1 --- a/xen/include/asm-ia64/xenpage.h	Fri Mar 31 14:04:16 2006 -0700
     8.2 +++ b/xen/include/asm-ia64/xenpage.h	Mon Apr 03 08:33:35 2006 -0600
     8.3 @@ -55,6 +55,9 @@ static inline int get_order_from_pages(u
     8.4  #define __pa(x)		({xen_va _v; _v.l = (long) (x); _v.f.reg = 0; _v.l;})
     8.5  #define __va(x)		({xen_va _v; _v.l = (long) (x); _v.f.reg = -1; _v.p;})
     8.6  
     8.7 +/* It is sometimes very useful to have unsigned long as result.  */
     8.8 +#define __va_ul(x)	({xen_va _v; _v.l = (long) (x); _v.f.reg = -1; _v.l;})
     8.9 +
    8.10  #undef PAGE_OFFSET
    8.11  #define PAGE_OFFSET	__IA64_UL_CONST(0xf000000000000000)
    8.12