21 #include <linux/types.h>
22 #include <linux/errno.h>
26 #include <linux/module.h>
35 #include <asm/processor.h>
42 #define PALINFO_VERSION "0.5"
57 static char *cache_types[] = {
64 static const char *cache_mattrib[]={
71 static const char *cache_st_hints[]={
75 "Non-temporal, all levels",
82 static const char *cache_ld_hints[]={
84 "Non-temporal, level 1",
86 "Non-temporal, all levels",
93 static const char *rse_hints[]={
97 "eager loads and stores"
100 #define RSE_HINTS_COUNT ARRAY_SIZE(rse_hints)
102 static const char *mem_attrib[]={
129 const char *
units[]={
"",
"K",
"M",
"G",
"T" };
131 for (i=0, j=0; i < 64; i++ , j=i/10) {
133 p +=
sprintf(p,
"%d%s ", 1 << (i-j*10), units[j]);
155 int i, begin,
skip = 0;
158 value >>= i = begin =
ffs(value) - 1;
160 for(; i <
max; i++ ) {
162 if (i != 0 && (i%64) == 0) value = *++reg_info;
164 if ((value & 0x1) == 0 && skip == 0) {
166 p +=
sprintf(p,
"%d-%d ", begin, i-1);
171 }
else if ((value & 0x1) && skip == 1) {
179 p +=
sprintf(p,
"%d-127", begin);
192 u64 halt_info_buffer[8];
196 status = ia64_pal_halt_info(halt_info);
197 if (status != 0)
return 0;
199 for (i=0; i < 8 ; i++ ) {
200 if (halt_info[i].pal_power_mgmt_info_s.
im == 1) {
201 p +=
sprintf(p,
"Power level %d:\n"
202 "\tentry_latency : %d cycles\n"
203 "\texit_latency : %d cycles\n"
204 "\tpower consumption : %d mW\n"
205 "\tCache+TLB coherency : %s\n", i,
211 p +=
sprintf(p,
"Power level %d: not implemented\n",i);
221 unsigned long i, levels, unique_caches;
226 if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
231 p +=
sprintf(p,
"Cache levels : %ld\nUnique caches : %ld\n\n", levels, unique_caches);
233 for (i=0; i < levels; i++) {
235 for (j=2; j >0 ; j--) {
238 if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) {
242 "%s Cache level %lu:\n"
243 "\tSize : %u bytes\n"
245 cache_types[j+cci.pcci_unified], i+1,
246 cci.pcci_cache_size);
248 if (cci.pcci_unified) p +=
sprintf(p,
"Unified ");
250 p +=
sprintf(p,
"%s\n", cache_mattrib[cci.pcci_cache_attr]);
253 "\tAssociativity : %d\n"
254 "\tLine size : %d bytes\n"
255 "\tStride : %d bytes\n",
256 cci.pcci_assoc, 1<<cci.pcci_line_size, 1<<cci.pcci_stride);
258 p +=
sprintf(p,
"\tStore latency : N/A\n");
260 p +=
sprintf(p,
"\tStore latency : %d cycle(s)\n",
261 cci.pcci_st_latency);
264 "\tLoad latency : %d cycle(s)\n"
265 "\tStore hints : ", cci.pcci_ld_latency);
267 for(k=0; k < 8; k++ ) {
268 if ( cci.pcci_st_hints & 0x1)
269 p +=
sprintf(p,
"[%s]", cache_st_hints[k]);
270 cci.pcci_st_hints >>=1;
272 p +=
sprintf(p,
"\n\tLoad hints : ");
274 for(k=0; k < 8; k++ ) {
275 if (cci.pcci_ld_hints & 0x1)
276 p +=
sprintf(p,
"[%s]", cache_ld_hints[k]);
277 cci.pcci_ld_hints >>=1;
280 "\n\tAlias boundary : %d byte(s)\n"
283 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb,
287 if (cci.pcci_unified)
break;
298 u64 tr_pages =0, vw_pages=0, tc_pages;
308 if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
313 "Physical Address Space : %d bits\n"
314 "Virtual Address Space : %d bits\n"
315 "Protection Key Registers(PKR) : %d\n"
316 "Implemented bits in PKR.key : %d\n"
317 "Hash Tag ID : 0x%x\n"
318 "Size of RR.rid : %d\n"
327 p +=
sprintf(p,
"unlimited\n");
334 if (ia64_pal_mem_attrib(&attrib) == 0) {
335 p +=
sprintf(p,
"Supported memory attributes : ");
337 for (i = 0; i < 8; i++) {
338 if (attrib & (1 << i)) {
339 p +=
sprintf(p,
"%s%s", sep, mem_attrib[i]);
346 if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
351 "\nTLB walker : %simplemented\n"
352 "Number of DTR : %d\n"
353 "Number of ITR : %d\n"
354 "TLB insertable page sizes : ",
360 p = bitvector_process(p, tr_pages);
362 p +=
sprintf(p,
"\nTLB purgeable page sizes : ");
364 p = bitvector_process(p, vw_pages);
366 if ((status=ia64_get_ptce(&ptce)) != 0) {
370 "\nPurge base address : 0x%016lx\n"
371 "Purge outer loop count : %d\n"
372 "Purge inner loop count : %d\n"
373 "Purge outer loop stride : %d\n"
374 "Purge inner loop stride : %d\n",
380 "Unique TC(s) : %d\n",
385 for (j=2; j>0 ; j--) {
390 if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) {
395 "\n%s Translation Cache Level %d:\n"
397 "\tAssociativity : %d\n"
398 "\tNumber of entries : %d\n"
400 cache_types[j+tc_info.tc_unified], i+1,
402 tc_info.tc_associativity,
403 tc_info.tc_num_entries);
406 p +=
sprintf(p,
"PreferredPageSizeOptimized ");
407 if (tc_info.tc_unified)
409 if (tc_info.tc_reduce_tr)
410 p +=
sprintf(p,
"TCReduction");
412 p +=
sprintf(p,
"\n\tSupported page sizes: ");
414 p = bitvector_process(p, tc_pages);
417 if (tc_info.tc_unified)
429 register_info(
char *page)
434 unsigned long phys_stacked;
436 unsigned long iregs, dregs;
437 static const char *
const info_type[] = {
439 "AR(s) with read side-effects",
441 "CR(s) with read side-effects",
444 for(info=0; info < 4; info++) {
446 if (ia64_pal_register_info(info, ®_info[0], ®_info[1]) != 0)
return 0;
448 p +=
sprintf(p,
"%-32s : ", info_type[info]);
450 p = bitregister_process(p, reg_info, 128);
455 if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) {
458 "RSE stacked physical registers : %ld\n"
459 "RSE load/store hints : %ld (%s)\n",
463 if (ia64_pal_debug_info(&iregs, &dregs))
467 "Instruction debug register pairs : %ld\n"
468 "Data debug register pairs : %ld\n", iregs, dregs);
473 static char *proc_features_0[]={
478 "Unimplemented instruction address fault",
479 "INIT, PMI, and LINT pins",
480 "Simple unimplemented instr addresses",
481 "Variable P-state performance",
482 "Virtual machine features implemented",
483 "XIP,XPSR,XFS implemented",
484 "XR1-XR3 implemented",
485 "Disable dynamic predicate prediction",
486 "Disable processor physical number",
487 "Disable dynamic data cache prefetch",
488 "Disable dynamic inst cache prefetch",
489 "Disable dynamic branch prediction",
492 "Enable MCA on Data Poisoning",
493 "Enable vmsw instruction",
494 "Enable extern environmental notification",
495 "Disable BINIT on processor time-out",
496 "Disable dynamic power management (DPM)",
499 "Enable CMCI promotion",
500 "Enable MCA to BINIT promotion",
501 "Enable MCA promotion",
502 "Enable BERR promotion"
505 static char *proc_features_16[]={
508 "Enable MCA on half-way timer",
511 "Enable Fast Deferral",
512 "Disable MCA on memory aliasing",
515 "DP system processor",
518 NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
519 NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
520 NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
521 NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
525 static char **proc_features[]={
527 NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
540 vf = v = proc_features[
set];
541 for(i=0; i < 64; i++, avail >>=1, status >>=1, control >>=1) {
550 p +=
sprintf(p,
"%-40s : %s %s\n", *v,
551 avail & 0x1 ? (status & 0x1 ?
553 avail & 0x1 ? (control & 0x1 ?
554 "Ctrl" :
"NoCtrl"):
"");
556 p +=
sprintf(p,
"Feature set %2ld bit %2d\t\t\t"
559 avail & 0x1 ? (status & 0x1 ?
561 avail & 0x1 ? (control & 0x1 ?
562 "Ctrl" :
"NoCtrl"):
"");
569 processor_info(
char *page)
572 u64 avail=1, status=1, control=1, feature_set=0;
576 ret = ia64_pal_proc_get_features(&avail, &status, &control,
586 p = feature_set_info(p, avail, status, control, feature_set);
594 static const char *bus_features[]={
599 "Request Bus Parking",
601 "Enable Half Transfer",
605 "Enable Cache Line Repl. Shared",
606 "Enable Cache Line Repl. Exclusive",
607 "Disable Transaction Queuing",
608 "Disable Response Error Checking",
609 "Disable Bus Error Checking",
610 "Disable Bus Requester Internal Error Signalling",
611 "Disable Bus Requester Error Signalling",
612 "Disable Bus Initialization Event Checking",
613 "Disable Bus Initialization Event Signalling",
614 "Disable Bus Address Error Checking",
615 "Disable Bus Address Error Signalling",
616 "Disable Bus Data Error Checking"
624 const char **v = bus_features;
630 if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0)
return 0;
636 for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) {
637 if ( ! *v )
continue;
638 p +=
sprintf(p,
"%-48s : %s%s %s\n", *v,
639 avail & 0x1 ?
"" :
"NotImpl",
640 avail & 0x1 ? (status & 0x1 ?
"On" :
"Off"):
"",
641 avail & 0x1 ? (control & 0x1 ?
"Ctrl" :
"NoCtrl"):
"");
652 if (ia64_pal_version(&min_ver, &cur_ver) != 0)
656 "PAL_vendor : 0x%02x (min=0x%02x)\n"
657 "PAL_A : %02x.%02x (min=%02x.%02x)\n"
658 "PAL_B : %02x.%02x (min=%02x.%02x)\n",
673 perfmon_info(
char *page)
679 if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0)
return 0;
682 "PMC/PMD pairs : %d\n"
683 "Counter width : %d bits\n"
684 "Cycle event number : %d\n"
685 "Retired event number : %d\n"
686 "Implemented PMC : ",
690 p = bitregister_process(p, pm_buffer, 256);
691 p +=
sprintf(p,
"\nImplemented PMD : ");
692 p = bitregister_process(p, pm_buffer+4, 256);
693 p +=
sprintf(p,
"\nCycles count capable : ");
694 p = bitregister_process(p, pm_buffer+8, 256);
695 p +=
sprintf(p,
"\nRetired bundles count capable : ");
697 #ifdef CONFIG_ITANIUM
702 if (pm_buffer[12] == 0x10) pm_buffer[12]=0x30;
705 p = bitregister_process(p, pm_buffer+12, 256);
713 frequency_info(
char *page)
719 if (ia64_pal_freq_base(&base) == -1)
720 p +=
sprintf(p,
"Output clock : not implemented\n");
722 p +=
sprintf(p,
"Output clock : %ld ticks/s\n", base);
724 if (ia64_pal_freq_ratios(&proc, &
bus, &itc) != 0)
return 0;
727 "Processor/Clock ratio : %d/%d\n"
728 "Bus/Clock ratio : %d/%d\n"
729 "ITC/Clock ratio : %d/%d\n",
730 proc.num, proc.den,
bus.num,
bus.den, itc.num, itc.den);
745 unsigned long max[3], pgm;
747 unsigned long valid:1;
749 unsigned long vpn:52;
754 unsigned long key:24;
755 unsigned long rv2:32;
765 unsigned long ppn:38;
774 unsigned long rid:24;
775 unsigned long rv2:32;
778 if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
785 for (i=0; i < 2; i++ ) {
786 for (j=0; j < max[
i]; j++) {
788 status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid);
795 ifa_reg = (
struct ifa_reg *)&tr_buffer[2];
797 if (ifa_reg->valid == 0)
continue;
799 gr_reg = (
struct gr_reg *)tr_buffer;
800 itir_reg = (
struct itir_reg *)&tr_buffer[1];
801 rid_reg = (
struct rid_reg *)&tr_buffer[3];
803 pgm = -1 << (itir_reg->ps - 12);
805 "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n"
814 (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12);
816 p = bitvector_process(p, 1<< itir_reg->ps);
825 gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma,
839 {
"vm_info", vm_info, },
842 {
"register_info", register_info, },
843 {
"processor_info", processor_info, },
844 {
"perfmon_info", perfmon_info, },
845 {
"frequency_info", frequency_info, },
847 {
"tr_info", tr_info, }
850 #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries)
860 #define NR_PALINFO_PROC_ENTRIES (NR_CPUS*(NR_PALINFO_ENTRIES+1))
880 #define req_cpu pal_func_cpu.req_cpu
881 #define func_id pal_func_cpu.func_id
892 } palinfo_smp_data_t;
900 palinfo_smp_call(
void *info)
902 palinfo_smp_data_t *
data = (palinfo_smp_data_t *)info;
903 data->ret = (*data->func)(data->page);
915 palinfo_smp_data_t
ptr;
925 printk(
KERN_ERR "palinfo: remote CPU call from %d to %d on function %d: "
935 printk(
KERN_ERR "palinfo: should not be called with non SMP kernel\n");
944 palinfo_read_entry(
char *page,
char **
start,
off_t off,
int count,
int *eof,
void *data)
956 len = palinfo_handle_smp(f, page);
960 if (len <= off+count) *eof = 1;
965 if (len>count) len =
count;
972 create_palinfo_proc_entries(
unsigned int cpu)
974 # define CPUSTR "cpu%d"
980 char cpustr[
sizeof(
CPUSTR)];
1002 *pdir = create_proc_read_entry(
1003 palinfo_entries[j].
name, 0, cpu_dir,
1004 palinfo_read_entry, (
void *)f.
value);
1010 remove_palinfo_proc_entries(
unsigned int hcpu)
1015 pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)];
1031 unsigned long action,
void *hcpu)
1033 unsigned int hotcpu = (
unsigned long)hcpu;
1038 create_palinfo_proc_entries(hotcpu);
1042 remove_palinfo_proc_entries(hotcpu);
1050 .notifier_call = palinfo_cpu_callback,
1064 create_palinfo_proc_entries(i);
1080 remove_palinfo_proc_entries(i);