+ /* Tell them we did it */
+}
+
+/*
+ * Check check mappings and hash table for consistency
+ *
+ * cm
+ */
+void
+db_check_mappings(db_expr_t addr, boolean_t have_addr, db_expr_t count,
+ char *modif)
+{
+ addr64_t pteg, pca, llva, lnextva;
+ unsigned int xpteg[32], xpca[8], space, hash, pva, seg, api, va, free, free2, xauto, PTEGcnt, wimgkk, wimgxx, slotoff;
+ int i, j, fnderr, slot, slot2, k, s4bit;
+ pmap_t pmap;
+ mapping_t *mp;
+ ppnum_t ppn, pa, aoff;
+ unsigned long long llslot, llseg, llhash;
+
+ s4bit = 0; /* Assume dinky? */
+ if(PerProcTable[0].ppe_vaddr->pf.Available & pf64Bit) s4bit = 1; /* Are we a big guy? */
+
+ PTEGcnt = hash_table_size / 64; /* Get the number of PTEGS */
+ if(s4bit) PTEGcnt = PTEGcnt / 2; /* PTEGs are twice as big */
+
+ pteg = hash_table_base; /* Start of hash table */
+ pca = hash_table_base - 4; /* Start of PCA */
+
+ for(i = 0; i < PTEGcnt; i++) { /* Step through them all */
+
+ fnderr = 0;
+
+ ReadReal(pteg, &xpteg[0]); /* Get first half of the pteg */
+ ReadReal(pteg + 0x20, &xpteg[8]); /* Get second half of the pteg */
+ if(s4bit) { /* See if we need the other half */
+ ReadReal(pteg + 0x40, &xpteg[16]); /* Get third half of the pteg */
+ ReadReal(pteg + 0x60, &xpteg[24]); /* Get fourth half of the pteg */
+ }
+ ReadReal(pca, &xpca[0]); /* Get pca */
+
+ if(xpca[0] & 0x00000001) { /* Is PCA locked? */
+ db_printf("Unexpected locked PCA\n"); /* Yeah, this may be bad */
+ fnderr = 1; /* Remember to print the pca/pteg pair later */
+ }
+
+ free = 0x80000000;
+
+ for(j = 0; j < 7; j++) { /* Search for duplicates */
+ slot = j * 2; /* Point to the slot */
+ if(s4bit) slot = slot * 2; /* Adjust for bigger slots */
+ if(!(xpca[0] & free)) { /* Check more if slot is allocated */
+ for(k = j + 1; k < 8; k++) { /* Search remaining slots */
+ slot2 = k * 2; /* Point to the slot */
+ if(s4bit) slot2 = slot2 * 2; /* Adjust for bigger slots */
+ if((xpteg[slot] == xpteg[slot2])
+ && (!s4bit || (xpteg[slot + 1] == xpteg[slot2 + 1]))) { /* Do we have duplicates? */
+ db_printf("Duplicate tags in pteg, slot %d and slot %d\n", j, k);
+ fnderr = 1;
+ }
+ }
+ }
+ free = free >> 1; /* Move slot over */
+ }
+
+ free = 0x80000000;
+ xauto = 0x00008000;
+
+ for(j = 0; j < 8; j++) { /* Step through the slots */
+
+ slot = j * 2; /* Point to the slot */
+ if(s4bit) slot = slot * 2; /* Hagfish? */
+ if(xpca[0] & free) { /* Check if marked free */
+ if((!s4bit && (xpteg[slot] & 0x80000000)) /* Is a supposedly free slot valid? */
+ || (s4bit && (xpteg[slot + 1] & 1))) {
+ db_printf("Free slot still valid - %d\n", j);
+ fnderr = 1;
+ }
+ }
+ else { /* We have an in use slot here */
+
+ if(!(!s4bit && (xpteg[slot] & 0x80000000)) /* Is a supposedly in use slot valid? */
+ && !(s4bit && (xpteg[slot + 1] & 1))) {
+ db_printf("Inuse slot not valid - %d\n", j);
+ fnderr = 1;
+ }
+ else { /* Slot is valid, check mapping */
+ if(!s4bit) { /* Not Hagfish? */
+ space = (xpteg[slot] >> 7) & (maxAdrSp - 1); /* Extract the space */
+ hash = space | (space << maxAdrSpb) | (space << (2 * maxAdrSpb)); /* Get the hash */
+ pva = i ^ hash; /* Get part of the vaddr */
+ seg = (xpteg[slot] >> 7) ^ hash; /* Get the segment number */
+ api = (xpteg[slot] & 0x3F); /* Get the API */
+ va = ((seg << (28 - maxAdrSpb)) & 0xF0000000) | (api << 22) | ((pva << 12) & 0x003FF000); /* Get the vaddr */
+ llva = (addr64_t)va; /* Make this a long long */
+ wimgxx = xpteg[slot + 1] & 0x7F; /* Get the wimg and pp */
+ ppn = xpteg[slot + 1] >> 12; /* Get physical page number */
+ slotoff = (i * 64) + (j * 8) | 1; /* Get offset to slot and valid bit */
+ }
+ else { /* Yes, Hagfish */
+ llslot = ((long long)xpteg[slot] << 32) | (long long)xpteg[slot + 1]; /* Make a long long version of this */
+ space = (llslot >> 12) & (maxAdrSp - 1); /* Extract the space */
+ llhash = (unsigned long long)space | ((unsigned long long)space << maxAdrSpb) | ((unsigned long long)space << (2 * maxAdrSpb)); /* Get the hash */
+ llhash = llhash & 0x0000001FFFFFFFFFULL; /* Make sure we stay within supported ranges */
+ pva = i ^ llhash; /* Get part of the vaddr */
+ llseg = ((llslot >> 12) ^ llhash); /* Get the segment number */
+ api = (llslot >> 7) & 0x1F; /* Get the API */
+ llva = ((llseg << (28 - maxAdrSpb)) & 0xFFFFFFFFF0000000ULL) | (api << 23) | ((pva << 12) & 0x007FF000); /* Get the vaddr */
+ wimgxx = xpteg[slot + 3] & 0x7F; /* Get the wimg and pp */
+ ppn = (xpteg[slot + 2] << 20) | (xpteg[slot + 3] >> 12); /* Get physical page number */
+ slotoff = (i * 128) + (j * 16) | 1; /* Get offset to slot and valid bit */
+ }
+
+ pmap = pmapTrans[space].pmapVAddr; /* Find the pmap address */
+ if(!pmap) { /* The pmap is not in use */
+ db_printf("The space %08X is not assigned to a pmap, slot = %d\n", space, slot); /* Say we are wrong */
+ fnderr = 1;
+ goto dcmout;
+ }
+
+ if (pmap->pmapFlags & pmapVMgsaa) {
+ unsigned int ret;
+ mapping_t mpcopy;
+ ret = hw_find_map_gv(pmap, llva, &mpcopy);
+ } else {
+ mp = hw_find_map(pmap, llva, &lnextva); /* Try to find the mapping for this address */
+ // db_printf("%08X - %017llX\n", mp, llva);
+ if((unsigned int)mp == mapRtBadLk) { /* Did we lock up ok? */
+ db_printf("Timeout locking mapping for for virtual address %016ll8X, slot = %d\n", llva, j);
+ return;
+ }
+
+ if(!mp) { /* Did we find one? */
+ db_printf("Not mapped, slot = %d, va = %08X\n", j, (unsigned int)llva);
+ fnderr = 1;
+ goto dcmout;
+ }
+
+ if((mp->mpFlags & 0xFF000000) > 0x01000000) { /* Is busy count too high? */
+ db_printf("Busy count too high, slot = %d\n", j);
+ fnderr = 1;
+ }
+
+ if((mp->mpFlags & mpType) == mpBlock) { /* Is this a block map? */
+ if(!(xpca[0] & xauto)) { /* Is it marked as such? */
+ db_printf("mapping marked as block, PCA is not, slot = %d\n", j);
+ fnderr = 1;
+ }
+ }
+ else { /* Is a block */
+ if(xpca[0] & xauto) { /* Is it marked as such? */
+ db_printf("mapping not marked as block, PCA is, slot = %d\n", j);
+ fnderr = 1;
+ }
+ if(mp->mpPte != slotoff) { /* See if mapping PTEG offset is us */
+ db_printf("mapping does not point to PTE, slot = %d\n", j);
+ fnderr = 1;
+ }
+ }
+
+ wimgkk = (unsigned int)mp->mpVAddr; /* Get last half of vaddr where keys, etc are */
+ wimgkk = (wimgkk ^ wimgxx) & 0x7F; /* XOR to find differences from PTE */
+ if(wimgkk) { /* See if key in PTE is what we want */
+ db_printf("key or WIMG does not match, slot = %d\n", j);
+ fnderr = 1;
+ }
+
+ aoff = (ppnum_t)((llva >> 12) - (mp->mpVAddr >> 12)); /* Get the offset from vaddr */
+ pa = aoff + mp->mpPAddr; /* Get the physical page number we expect */
+ if(pa != ppn) { /* Is physical address expected? */
+ db_printf("Physical address does not match, slot = %d\n", j);
+ fnderr = 1;
+ }
+
+ mapping_drop_busy(mp); /* We're done with the mapping */
+ }
+ }
+
+ }
+dcmout:
+ free = free >> 1;
+ xauto = xauto >> 1;
+ }
+
+
+ if(fnderr)db_dumppca(i); /* Print if error */
+
+ pteg = pteg + 64; /* Go to the next one */
+ if(s4bit) pteg = pteg + 64; /* Hagfish? */
+ pca = pca - 4; /* Go to the next one */