Ejemplo n.º 1
0
static void
get_max_cacheline_size (void)
{
	unsigned long line_size, max = 1;
	u64 l, levels, unique_caches;
        pal_cache_config_info_t cci;
        s64 status;

        status = ia64_pal_cache_summary(&levels, &unique_caches);
        if (status != 0) {
                printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
                       __FUNCTION__, status);
                max = SMP_CACHE_BYTES;
		goto out;
        }

	for (l = 0; l < levels; ++l) {
		status = ia64_pal_cache_config_info(l, /* cache_type (data_or_unified)= */ 2,
						    &cci);
		if (status != 0) {
			printk(KERN_ERR
			       "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n",
			       __FUNCTION__, l, status);
			max = SMP_CACHE_BYTES;
		}
		line_size = 1 << cci.pcci_line_size;
		if (line_size > max)
			max = line_size;
        }
  out:
	if (max > ia64_max_cacheline_size)
		ia64_max_cacheline_size = max;
}
Ejemplo n.º 2
0
/**
 * pci_cacheline_size - determine cacheline size for PCI devices
 * @dev: void
 *
 * We want to use the line-size of the outer-most cache.  We assume
 * that this line-size is the same for all CPUs.
 *
 * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
 *
 * RETURNS: An appropriate -ERRNO error value on eror, or zero for success.
 */
static unsigned long
pci_cacheline_size (void)
{
	u64 levels, unique_caches;
	s64 status;
	pal_cache_config_info_t cci;
	static u8 cacheline_size;

	if (cacheline_size)
		return cacheline_size;

	status = ia64_pal_cache_summary(&levels, &unique_caches);
	if (status != 0) {
		printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
		       __FUNCTION__, status);
		return SMP_CACHE_BYTES;
	}

	status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2,
					    &cci);
	if (status != 0) {
		printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n",
		       __FUNCTION__, status);
		return SMP_CACHE_BYTES;
	}
	cacheline_size = 1 << cci.pcci_line_size;
	return cacheline_size;
}
Ejemplo n.º 3
0
/*
 * Calculate the max. cache line size.
 *
 * In addition, the minimum of the i-cache stride sizes is calculated for
 * "flush_icache_range()".
 */
static void __cpuinit
get_max_cacheline_size (void)
{
	unsigned long line_size, max = 1;
	unsigned int cache_size = 0;
	u64 l, levels, unique_caches;
        pal_cache_config_info_t cci;
        s64 status;

        status = ia64_pal_cache_summary(&levels, &unique_caches);
        if (status != 0) {
                printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
                       __FUNCTION__, status);
                max = SMP_CACHE_BYTES;
		/* Safest setup for "flush_icache_range()" */
		ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
		goto out;
        }

	for (l = 0; l < levels; ++l) {
		status = ia64_pal_cache_config_info(l, /* cache_type (data_or_unified)= */ 2,
						    &cci);
		if (status != 0) {
			printk(KERN_ERR
			       "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",
			       __FUNCTION__, l, status);
			max = SMP_CACHE_BYTES;
			/* The safest setup for "flush_icache_range()" */
			cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
			cci.pcci_unified = 1;
		}
		line_size = 1 << cci.pcci_line_size;
		if (line_size > max)
			max = line_size;
		if (cache_size < cci.pcci_cache_size)
			cache_size = cci.pcci_cache_size;
		if (!cci.pcci_unified) {
			status = ia64_pal_cache_config_info(l,
						    /* cache_type (instruction)= */ 1,
						    &cci);
			if (status != 0) {
				printk(KERN_ERR
				"%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",
					__FUNCTION__, l, status);
				/* The safest setup for "flush_icache_range()" */
				cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
			}
		}
		if (cci.pcci_stride < ia64_i_cache_stride_shift)
			ia64_i_cache_stride_shift = cci.pcci_stride;
	}
  out:
#ifdef CONFIG_SMP
	max_cache_size = max(max_cache_size, cache_size);
#endif
	if (max > ia64_max_cacheline_size)
		ia64_max_cacheline_size = max;
}
Ejemplo n.º 4
0
/**
 * set_pci_cacheline_size - determine cacheline size for PCI devices
 *
 * We want to use the line-size of the outer-most cache.  We assume
 * that this line-size is the same for all CPUs.
 *
 * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
 */
static void __init set_pci_cacheline_size(void)
{
	u64 levels, unique_caches;
	s64 status;
	pal_cache_config_info_t cci;

	status = ia64_pal_cache_summary(&levels, &unique_caches);
	if (status != 0) {
		printk(KERN_ERR "%s: ia64_pal_cache_summary() failed "
			"(status=%ld)\n", __func__, status);
		return;
	}

	status = ia64_pal_cache_config_info(levels - 1,
				/* cache_type (data_or_unified)= */ 2, &cci);
	if (status != 0) {
		printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed "
			"(status=%ld)\n", __func__, status);
		return;
	}
	pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
}
Ejemplo n.º 5
0
static int
cache_info(char *page)
{
	char *p = page;
	unsigned long i, levels, unique_caches;
	pal_cache_config_info_t cci;
	int j, k;
	long status;

	if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
		printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
		return 0;
	}

	p += sprintf(p, "Cache levels  : %ld\nUnique caches : %ld\n\n", levels, unique_caches);

	for (i=0; i < levels; i++) {

		for (j=2; j >0 ; j--) {

			/* even without unification some level may not be present */
			if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) {
				continue;
			}
			p += sprintf(p,
				     "%s Cache level %lu:\n"
				     "\tSize           : %u bytes\n"
				     "\tAttributes     : ",
				     cache_types[j+cci.pcci_unified], i+1,
				     cci.pcci_cache_size);

			if (cci.pcci_unified) p += sprintf(p, "Unified ");

			p += sprintf(p, "%s\n", cache_mattrib[cci.pcci_cache_attr]);

			p += sprintf(p,
				     "\tAssociativity  : %d\n"
				     "\tLine size      : %d bytes\n"
				     "\tStride         : %d bytes\n",
				     cci.pcci_assoc, 1<<cci.pcci_line_size, 1<<cci.pcci_stride);
			if (j == 1)
				p += sprintf(p, "\tStore latency  : N/A\n");
			else
				p += sprintf(p, "\tStore latency  : %d cycle(s)\n",
						cci.pcci_st_latency);

			p += sprintf(p,
				     "\tLoad latency   : %d cycle(s)\n"
				     "\tStore hints    : ", cci.pcci_ld_latency);

			for(k=0; k < 8; k++ ) {
				if ( cci.pcci_st_hints & 0x1)
					p += sprintf(p, "[%s]", cache_st_hints[k]);
				cci.pcci_st_hints >>=1;
			}
			p += sprintf(p, "\n\tLoad hints     : ");

			for(k=0; k < 8; k++ ) {
				if (cci.pcci_ld_hints & 0x1)
					p += sprintf(p, "[%s]", cache_ld_hints[k]);
				cci.pcci_ld_hints >>=1;
			}
			p += sprintf(p,
				     "\n\tAlias boundary : %d byte(s)\n"
				     "\tTag LSB        : %d\n"
				     "\tTag MSB        : %d\n",
				     1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb,
				     cci.pcci_tag_msb);

			/* when unified, data(j=2) is enough */
			if (cci.pcci_unified) break;
		}
	}
	return p - page;
}