Need multia and sx164 testing for cache size

Richard Henderson rth at twiddle.net
Sat Mar 20 17:46:18 UTC 2004


LCA4 and PCA56/PCA57 are the only processors for which it appears 
that I can get this information without PALcode help.  Can folks
see if I actually got this right?


r~



===== setup.c 1.39 vs edited =====
--- 1.39/arch/alpha/kernel/setup.c	Thu Oct 23 02:57:40 2003
+++ edited/setup.c	Sat Mar 20 09:41:21 2004
@@ -38,8 +38,9 @@
 #include <linux/sysrq.h>
 #include <linux/reboot.h>
 #endif
-
 #include <linux/notifier.h>
+#include <asm/io.h>
+
 extern struct notifier_block *panic_notifier_list;
 static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
 static struct notifier_block alpha_panic_block = {
@@ -64,6 +65,11 @@
 struct hwrpb_struct *hwrpb;
 unsigned long srm_hae;
 
+int alpha_l1i_cacheshape;
+int alpha_l1d_cacheshape;
+int alpha_l2_cacheshape;
+int alpha_l3_cacheshape;
+
 #ifdef CONFIG_VERBOSE_MCHECK
 /* 0=minimum, 1=verbose, 2=all */
 /* These can be overridden via the command line, ie "verbose_mcheck=2") */
@@ -113,6 +119,7 @@
 static struct alpha_machine_vector *get_sysvec_byname(const char *);
 static void get_sysnames(unsigned long, unsigned long, unsigned long,
 			 char **, char **);
+static void determine_cpu_caches (unsigned int);
 
 static char command_line[COMMAND_LINE_SIZE];
 char saved_command_line[COMMAND_LINE_SIZE];
@@ -672,6 +679,9 @@
 	/* Find our memory.  */
 	setup_memory(kernel_end);
 
+	/* First guess at cpu cache sizes.  Do this before init_arch.  */
+	determine_cpu_caches(cpu->type);
+
 	/* Initialize the machine.  Usually has to do with setting up
 	   DMA windows and the like.  */
 	if (alpha_mv.init_arch)
@@ -1156,6 +1166,18 @@
 	return count;
 }
 
+static void
+show_cache_size (struct seq_file *f, const char *which, int shape)
+{
+	if (shape == -1)
+		seq_printf (f, "%s\t\t: n/a\n", which);
+	else if (shape == 0)
+		seq_printf (f, "%s\t\t: unknown\n", which);
+	else
+		seq_printf (f, "%s\t\t: %dK, %d-way, %db line\n",
+			    which, shape >> (8+10), shape & 15,
+			    1 << ((shape >> 4) & 15));
+}
 
 static int
 show_cpuinfo(struct seq_file *f, void *slot)
@@ -1229,9 +1251,137 @@
 		       num_online_cpus(), cpu_present_mask);
 #endif
 
+	show_cache_size (f, "L1 Icache", alpha_l1i_cacheshape);
+	show_cache_size (f, "L1 Dcache", alpha_l1d_cacheshape);
+	show_cache_size (f, "L2 cache", alpha_l2_cacheshape);
+	show_cache_size (f, "L3 cache", alpha_l3_cacheshape);
+
 	return 0;
 }
 
+#define CSHAPE(totalsize, linesize, assoc) \
+  ((totalsize << 8) | (linesize << 4) | assoc)
+
+static void __init
+determine_cpu_caches (unsigned int cpu_type)
+{
+	int L1I, L1D, L2, L3;
+
+	switch (cpu_type) {
+	case EV4_CPU:
+	case EV45_CPU:
+	  {
+		if (cpu_type == EV4_CPU)
+			L1I = CSHAPE(8*1024, 5, 1);
+		else
+			L1I = CSHAPE(16*1024, 5, 1);
+		L1D = L1I;
+		L3 = -1;
+	
+		/* BIU_CTL is a write-only Abox register.  PALcode has a
+		   shadow copy, and may be available from some versions
+		   of the CSERVE PALcall.  If we can get it, then
+
+			unsigned long biu_ctl, size;
+			size = 128*1024 * (1 << ((biu_ctl >> 28) & 7));
+			L2 = CSHAPE (size, 5, 1);
+		*/
+		L2 = 0;
+		break;
+	  }
+
+	case LCA4_CPU:
+	  {
+		unsigned long car, size;
+
+		L1I = L1D = CSHAPE(8*1024, 5, 1);
+		L3 = -1;
+
+		car = *(vuip) phys_to_virt (0x120000078);
+		size = 64*1024 * (1 << ((car >> 5) & 7));
+		/* No typo -- 8 byte cacheline size.  Whodathunk.  */
+		L2 = (car & 1 ? CSHAPE (size, 3, 1) : -1);
+		break;
+	  }
+
+	case EV5_CPU:
+	case EV56_CPU:
+	  {
+		unsigned long sc_ctl, width;
+
+		L1I = L1D = CSHAPE(8*1024, 5, 1);
+
+		/* Check the line size of the Scache.  */
+		sc_ctl = *(vulp) phys_to_virt (0xfffff000a8);
+		width = sc_ctl & 0x1000 ? 64 : 32;
+		L2 = CSHAPE (96*1024, width, 3);
+
+		/* BC_CONTROL and BC_CONFIG are write-only IPRs.  PALcode
+		   has a shadow copy, and may be available from some versions
+		   of the CSERVE PALcall.  If we can get it, then
+
+			unsigned long bc_control, bc_config, size;
+			size = 1024*1024 * (1 << ((bc_config & 7) - 1));
+			L3 = (bc_control & 1 ? CSHAPE (size, width, 1) : -1);
+		*/
+		L3 = 0;
+		break;
+	  }
+
+	case PCA56_CPU:
+	case PCA57_CPU:
+	  {
+		unsigned long cbox_config, size;
+
+		if (cpu_type == PCA56_CPU) {
+			L1I = CSHAPE(16*1024, 6, 1);
+			L1D = CSHAPE(8*1024, 5, 1);
+		} else {
+			L1I = CSHAPE(32*1024, 6, 2);
+			L1D = CSHAPE(16*1024, 5, 1);
+		}
+		L3 = -1;
+
+		cbox_config = *(vulp) phys_to_virt (0xfffff00008);
+		size = 512*1024 * (1 << ((cbox_config >> 12) & 3));
+
+		L2 = ((cbox_config >> 31) & 1 ? CSHAPE (size, 6, 1) : -1);
+		break;
+	  }
+
+	case EV6_CPU:
+	case EV67_CPU:
+	case EV68CB_CPU:
+	case EV68AL_CPU:
+	case EV68CX_CPU:
+	case EV69_CPU:
+		/* ??? L2 size is hopefully buried in PALcode somewhere,
+		   and accessible via cserve.  The size of the Bcache is
+		   set in the BC_SIZE field of the Cbox WRITE_ONCE chain.  */
+		L1I = L1D = CSHAPE(64*1024, 6, 2);
+		L2 = 0;
+		L3 = -1;
+		break;
+
+	case EV7_CPU:
+	case EV79_CPU:
+		L1I = L1D = CSHAPE(64*1024, 6, 2);
+		L2 = CSHAPE(7*1024*1024/4, 6, 7);
+		L3 = -1;
+		break;
+
+	default:
+		/* Nothing known about this cpu type.  */
+		L1I = L1D = L2 = L3 = 0;
+		break;
+	}
+
+	alpha_l1i_cacheshape = L1I;
+	alpha_l1d_cacheshape = L1D;
+	alpha_l2_cacheshape = L2;
+	alpha_l3_cacheshape = L3;
+}
+
 /*
  * We show only CPU #0 info.
  */





More information about the axp-list mailing list