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