[PATCH] TCE fix for KDB
Ananth N Mavinakayanahalli
ananth at in.ibm.com
Fri Mar 26 22:03:41 EST 2004
Hello,
Here is a patch to fix the handling of TCEs in KDB. I also noticed that the
iommu->it_type was not set to TCE_PCI - patch sets that too.
Thanks,
Ananth
--
Ananth Narayan
Linux Technology Center,
IBM Software Lab, INDIA
diff -Naur temp/ameslab/arch/ppc64/kdb/kdba_bp.c ameslab/arch/ppc64/kdb/kdba_bp.c
--- temp/ameslab/arch/ppc64/kdb/kdba_bp.c 2004-03-22 14:17:52.000000000 +0530
+++ ameslab/arch/ppc64/kdb/kdba_bp.c 2004-03-25 18:23:57.000000000 +0530
@@ -190,8 +190,6 @@
if (rv > 0)
goto handled;
-handle:
-
/*
* Determine which breakpoint was encountered.
*/
diff -Naur temp/ameslab/arch/ppc64/kdb/kdbasupport.c ameslab/arch/ppc64/kdb/kdbasupport.c
--- temp/ameslab/arch/ppc64/kdb/kdbasupport.c 2004-03-22 14:17:52.000000000 +0530
+++ ameslab/arch/ppc64/kdb/kdbasupport.c 2004-03-26 12:02:08.000000000 +0530
@@ -37,6 +37,7 @@
#include <asm/uaccess.h>
#include <asm/machdep.h>
#include <asm/prom.h>
+#include <asm/iommu.h>
#include "../kernel/pci.h" // for traverse_all_pci_devices()
extern const char *kdb_diemsg;
@@ -1617,21 +1618,13 @@
}
}
-
-#ifdef TCE_HAS_CHANGED_FIX_LATER
-
int
kdba_dump_tce_table(int argc, const char **argv, const char **envp, struct pt_regs *regs)
{
- struct TceTable kt;
- long tce_table_address;
- int nr;
- int i,j,k;
- int full,empty;
- int fulldump=0;
- u64 mapentry;
- int totalpages;
- int levelpages;
+ struct iommu_table it;
+ unsigned long tce_table_address;
+ unsigned long bitmap, alloced = 0;
+ int nr, i, j;
if (argc == 0) {
kdb_printf("need address\n");
@@ -1639,75 +1632,52 @@
}
else
kdbgetularg(argv[1], &tce_table_address);
-
- if (argc==2)
- if (strcmp(argv[2], "full") == 0)
- fulldump=1;
-
+
/* with address, read contents of memory and dump tce table. */
- /* possibly making some assumptions on the depth and size of table..*/
+ nr = kdba_readarea_size(tce_table_address + 0, &it.it_busno, 8);
+ if (nr == 0) {
+ kdb_printf("Invalid address\n");
+ return 0;
+ }
- nr = kdba_readarea_size(tce_table_address+0 ,&kt.busNumber,8);
- nr = kdba_readarea_size(tce_table_address+8 ,&kt.size,8);
- nr = kdba_readarea_size(tce_table_address+16,&kt.startOffset,8);
- nr = kdba_readarea_size(tce_table_address+24,&kt.base,8);
- nr = kdba_readarea_size(tce_table_address+32,&kt.index,8);
- nr = kdba_readarea_size(tce_table_address+40,&kt.tceType,8);
- nr = kdba_readarea_size(tce_table_address+48,&kt.lock,8);
+ nr = kdba_readarea_size(tce_table_address, &it, sizeof(struct iommu_table));
kdb_printf("\n");
- kdb_printf("TceTable at address %s:\n",argv[1]);
- kdb_printf("BusNumber: 0x%x \n",(uint)kt.busNumber);
- kdb_printf("size: 0x%x \n",(uint)kt.size);
- kdb_printf("startOffset: 0x%x \n",(uint)kt.startOffset);
- kdb_printf("base: 0x%x \n",(uint)kt.base);
- kdb_printf("index: 0x%x \n",(uint)kt.index);
- kdb_printf("tceType: 0x%x \n",(uint)kt.tceType);
+ kdb_printf("tce_table at address %s:\n",argv[1]);
+ kdb_printf("it_busno: 0x%lx\n", (unsigned long)it.it_busno);
+ kdb_printf("it_size: 0x%lx\n", (unsigned long)it.it_size);
+ kdb_printf("it_offset: 0x%lx\n", (unsigned long)it.it_offset);
+ kdb_printf("it_base: 0x%lx\n", (unsigned long)it.it_base);
+ kdb_printf("it_index: 0x%lx\n", (unsigned long)it.it_index);
+ kdb_printf("it_type: 0x%lx\n", (unsigned long)it.it_type);
+ kdb_printf("it_entrysize: 0x%lx\n", (unsigned long)it.it_entrysize);
+ kdb_printf("it_blocksize: 0x%lx\n", (unsigned long)it.it_blocksize);
+ kdb_printf("it_hint: 0x%lx\n", (unsigned long)it.it_hint);
+ kdb_printf("it_largehint: 0x%lx\n", (unsigned long)it.it_largehint);
+ kdb_printf("it_halfpoint: 0x%lx\n", (unsigned long)it.it_halfpoint);
#ifdef CONFIG_SMP
- kdb_printf("lock: 0x%x \n",(uint)kt.lock.lock);
+ kdb_printf("it_lock: 0x%lx\n", (unsigned long)it.it_lock.lock);
#endif
+ kdb_printf("it_mapsize: 0x%lx\n", (unsigned long)it.it_mapsize);
+ kdb_printf("it_map: 0x%lx\n", (unsigned long)it.it_map);
- nr = kdba_readarea_size(tce_table_address+56,&kt.mlbm.maxLevel,8);
- kdb_printf(" maxLevel: 0x%x \n",(uint)kt.mlbm.maxLevel);
- totalpages=0;
- for (i=0;i<NUM_TCE_LEVELS;i++) {
- nr = kdba_readarea_size(tce_table_address+64+i*24,&kt.mlbm.level[i].numBits,8);
- nr = kdba_readarea_size(tce_table_address+72+i*24,&kt.mlbm.level[i].numBytes,8);
- nr = kdba_readarea_size(tce_table_address+80+i*24,&kt.mlbm.level[i].map,8);
- kdb_printf(" level[%d]\n",i);
- kdb_printf(" numBits: 0x%x\n",(uint)kt.mlbm.level[i].numBits);
- kdb_printf(" numBytes: 0x%x\n",(uint)kt.mlbm.level[i].numBytes);
- kdb_printf(" map*: %p\n",kt.mlbm.level[i].map);
-
- /* if these dont match, this might not be a valid tce table, so
- dont try to iterate the map entries. */
- if (kt.mlbm.level[i].numBits == 8*kt.mlbm.level[i].numBytes) {
- full=0;empty=0;levelpages=0;
- for (j=0;j<kt.mlbm.level[i].numBytes; j++) {
- mapentry=0;
- nr = kdba_readarea_size((long int)(kt.mlbm.level[i].map+j),&mapentry,1);
- if (mapentry)
- full++;
- else
- empty++;
- if (mapentry && fulldump) {
- kdb_printf("0x%lx\n",mapentry);
- }
- for (k=0;(k<=64) && ((0x1UL<<k) <= mapentry);k++) {
- if ((0x1UL<<k) & mapentry) levelpages++;
- }
+ if (it.it_map && (valid_ppc64_kernel_address((unsigned long)it.it_map, 8))) {
+ for (i = 0; i < (it.it_mapsize/64); i++) {
+ nr = kdba_readarea_size((unsigned long)(it.it_map + (i * 8)), &bitmap, 8);
+ if (bitmap) {
+ for (j = 0; j < 64; j++) {
+ if ((bitmap >> j) & 0x01)
+ alloced++;
+ }
+ }
}
- kdb_printf(" full:0x%x empty:0x%x pages:0x%x\n",full,empty,levelpages);
- } else {
- kdb_printf(" numBits/numBytes mismatch..? \n");
- }
- totalpages+=levelpages;
}
- kdb_printf(" Total pages:0x%x\n",totalpages);
+ kdb_printf("TCE entries alloced = %ld\n", alloced);
+ kdb_printf("TCE entries free = %ld\n", it.it_mapsize - alloced);
+
kdb_printf("\n");
return 0;
}
-#endif
int
kdba_kernelversion(int argc, const char **argv, const char **envp, struct pt_regs *regs){
@@ -1732,13 +1702,12 @@
dn->phb = phb;
kdb_printf("dn: %p \n",dn);
- kdb_printf(" phb : %p\n",dn->phb);
- kdb_printf(" name : %s\n",dn->name);
- kdb_printf(" full_name: %s\n",dn->full_name);
- kdb_printf(" busno : 0x%x\n",dn->busno);
- kdb_printf(" devfn : 0x%x\n",dn->devfn);
- // XXX fix me later, bring up to date
- // kdb_printf(" tce_table: %p\n",dn->tce_table);
+ kdb_printf(" phb : %p\n", dn->phb);
+ kdb_printf(" name : %s\n", dn->name);
+ kdb_printf(" full_name : %s\n", dn->full_name);
+ kdb_printf(" busno : 0x%x\n", dn->busno);
+ kdb_printf(" devfn : 0x%x\n", dn->devfn);
+ kdb_printf(" iommu_table : %p\n", dn->iommu_table);
return NULL;
}
@@ -2043,8 +2012,7 @@
kdb_register("superreg", kdba_super_regs, "superreg", "display super_regs", 0);
kdb_register("msr", kdba_dissect_msr, "msr", "dissect msr", 0);
kdb_register("halt", kdba_halt, "halt", "halt machine", 0);
- // XXX fix me later, tce has changed radically
- // kdb_register("tce_table", kdba_dump_tce_table, "tce_table <addr> [full]", "dump the tce table located at <addr>", 0);
+ kdb_register("tce_table", kdba_dump_tce_table, "tce_table <addr>", "dump the tce table located at <addr>", 0);
kdb_register("kernel", kdba_kernelversion, "version", "display running kernel version", 0);
kdb_register("pci_info", kdba_dump_pci_info, "dump_pci_info", "dump pci device info", 0);
kdb_register("dump", kdba_dump, "dump (all|basic)", "dump all info", 0);
diff -Naur temp/ameslab/arch/ppc64/kernel/pSeries_iommu.c ameslab/arch/ppc64/kernel/pSeries_iommu.c
--- temp/ameslab/arch/ppc64/kernel/pSeries_iommu.c 2004-03-22 14:17:52.000000000 +0530
+++ ameslab/arch/ppc64/kernel/pSeries_iommu.c 2004-03-24 15:58:14.000000000 +0530
@@ -210,6 +210,7 @@
tbl->it_index = 0;
tbl->it_entrysize = sizeof(union tce_entry);
tbl->it_blocksize = 16;
+ tbl->it_type = TCE_PCI;
}
/*
@@ -245,6 +246,7 @@
tbl->it_index = dma_window[0];
tbl->it_entrysize = sizeof(union tce_entry);
tbl->it_blocksize = 16;
+ tbl->it_type = TCE_PCI;
}
** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc64-dev
mailing list