📄 xmon.c
字号:
nr = mread(codeaddr, &flags, 8); if (nr != 8) return 0; /* Bad read or no tb table. */ tab->flags = flags; version = (flags >> 56) & 0xff; if (version != 0) continue; /* No tb table here. */ /* Now, like the version, some of the flags are values that are more conveniently extracted... */ tab->fp_saved = (flags >> 24) & 0x3f; tab->gpr_saved = (flags >> 16) & 0x3f; tab->fixedparms = (flags >> 8) & 0xff; tab->floatparms = (flags >> 1) & 0x7f; codeaddr += 8; num_parms = tab->fixedparms + tab->floatparms; if (num_parms) { unsigned int parminfo; int parm; if (num_parms > 32) return 1; /* incomplete */ nr = mread(codeaddr, &parminfo, 4); if (nr != 4) return 1; /* incomplete */ /* decode parminfo...32 bits. A zero means fixed. A one means float and the following bit determines single (0) or double (1). */ for (parm = 0; parm < num_parms; parm++) { if (parminfo & 0x80000000) { parminfo <<= 1; if (parminfo & 0x80000000) tab->parminfo[parm] = TBTAB_PARMDFLOAT; else tab->parminfo[parm] = TBTAB_PARMSFLOAT; } else { tab->parminfo[parm] = TBTAB_PARMFIXED; } parminfo <<= 1; } codeaddr += 4; } if (flags & TBTAB_FLAGSHASTBOFF) { nr = mread(codeaddr, &tab->tb_offset, 4); if (nr != 4) return 1; /* incomplete */ if (tab->tb_offset > 0) { tab->funcstart = tbtab_start - tab->tb_offset; } codeaddr += 4; } /* hand_mask appears to be always be omitted. */ if (flags & TBTAB_FLAGSHASCTL) { /* Assume this will never happen for C or asm */ return 1; /* incomplete */ } if (flags & TBTAB_FLAGSNAMEPRESENT) { short namlen; nr = mread(codeaddr, &namlen, 2); if (nr != 2) return 1; /* incomplete */ if (namlen >= sizeof(tab->name)) namlen = sizeof(tab->name)-1; codeaddr += 2; nr = mread(codeaddr, tab->name, namlen); tab->name[namlen] = '\0'; codeaddr += namlen; } return 1; } } return 0; /* hit max...sorry. */}voidmem_translate(){ int c; unsigned long ea, va, vsid, vpn, page, hpteg_slot_primary, hpteg_slot_secondary, primary_hash, i, *steg, esid, stabl; HPTE * hpte; struct mm_struct * mm; pte_t *ptep = NULL; void * pgdir; c = inchar(); if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') termch = c; scanhex((void *)&ea); if ((ea >= KRANGE_START) && (ea <= (KRANGE_START + (1UL<<60)))) { ptep = 0; vsid = get_kernel_vsid(ea); va = ( vsid << 28 ) | ( ea & 0x0fffffff ); } else { // if in vmalloc range, use the vmalloc page directory if ( ( ea >= VMALLOC_START ) && ( ea <= VMALLOC_END ) ) { mm = &init_mm; vsid = get_kernel_vsid( ea ); } // if in ioremap range, use the ioremap page directory else if ( ( ea >= IMALLOC_START ) && ( ea <= IMALLOC_END ) ) { mm = &ioremap_mm; vsid = get_kernel_vsid( ea ); } // if in user range, use the current task's page directory else if ( ( ea >= USER_START ) && ( ea <= USER_END ) ) { mm = current->mm; vsid = get_vsid(mm->context, ea ); } pgdir = mm->pgd; va = ( vsid << 28 ) | ( ea & 0x0fffffff ); ptep = find_linux_pte( pgdir, ea ); } vpn = ((vsid << 28) | (((ea) & 0xFFFF000))) >> 12; page = vpn & 0xffff; esid = (ea >> 28) & 0xFFFFFFFFF; // Search the primary group for an available slot primary_hash = ( vsid & 0x7fffffffff ) ^ page; hpteg_slot_primary = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP; hpteg_slot_secondary = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP; printf("ea : %.16lx\n", ea); printf("esid : %.16lx\n", esid); printf("vsid : %.16lx\n", vsid); printf("\nSoftware Page Table\n-------------------\n"); printf("ptep : %.16lx\n", ((unsigned long *)ptep)); if(ptep) { printf("*ptep : %.16lx\n", *((unsigned long *)ptep)); } hpte = htab_data.htab + hpteg_slot_primary; printf("\nHardware Page Table\n-------------------\n"); printf("htab base : %.16lx\n", htab_data.htab); printf("slot primary : %.16lx\n", hpteg_slot_primary); printf("slot secondary : %.16lx\n", hpteg_slot_secondary); printf("\nPrimary Group\n"); for (i=0; i<8; ++i) { if ( hpte->dw0.dw0.v != 0 ) { printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1); printf(" vsid: %.13lx api: %.2lx hash: %.1lx\n", (hpte->dw0.dw0.avpn)>>5, (hpte->dw0.dw0.avpn) & 0x1f, (hpte->dw0.dw0.h)); printf(" rpn: %.13lx \n", (hpte->dw1.dw1.rpn)); printf(" pp: %.1lx \n", ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp)); printf(" wimgn: %.2lx reference: %.1lx change: %.1lx\n", ((hpte->dw1.dw1.w)<<4)| ((hpte->dw1.dw1.i)<<3)| ((hpte->dw1.dw1.m)<<2)| ((hpte->dw1.dw1.g)<<1)| ((hpte->dw1.dw1.n)<<0), hpte->dw1.dw1.r, hpte->dw1.dw1.c); } hpte++; } printf("\nSecondary Group\n"); // Search the secondary group hpte = htab_data.htab + hpteg_slot_secondary; for (i=0; i<8; ++i) { if(hpte->dw0.dw0.v) { printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1); printf(" vsid: %.13lx api: %.2lx hash: %.1lx\n", (hpte->dw0.dw0.avpn)>>5, (hpte->dw0.dw0.avpn) & 0x1f, (hpte->dw0.dw0.h)); printf(" rpn: %.13lx \n", (hpte->dw1.dw1.rpn)); printf(" pp: %.1lx \n", ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp)); printf(" wimgn: %.2lx reference: %.1lx change: %.1lx\n", ((hpte->dw1.dw1.w)<<4)| ((hpte->dw1.dw1.i)<<3)| ((hpte->dw1.dw1.m)<<2)| ((hpte->dw1.dw1.g)<<1)| ((hpte->dw1.dw1.n)<<0), hpte->dw1.dw1.r, hpte->dw1.dw1.c); } hpte++; } printf("\nHardware Segment Table\n-----------------------\n"); stabl = (unsigned long)(KERNELBASE+(_ASR&0xFFFFFFFFFFFFFFFE)); steg = (unsigned long *)((stabl) | ((esid & 0x1f) << 7)); printf("stab base : %.16lx\n", stabl); printf("slot : %.16lx\n", steg); for (i=0; i<8; ++i) { printf("%d: (ste) %.16lx %.16lx\n", i, *((unsigned long *)(steg+i*2)),*((unsigned long *)(steg+i*2+1)) ); }}void mem_check(){ unsigned long htab_size_bytes; unsigned long htab_end; unsigned long last_rpn; HPTE *hpte1, *hpte2; htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG htab_end = (unsigned long)htab_data.htab + htab_size_bytes; // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT; last_rpn = 0xfffff; printf("\nHardware Page Table Check\n-------------------\n"); printf("htab base : %.16lx\n", htab_data.htab); printf("htab size : %.16lx\n", htab_size_bytes);#if 1 for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) { if ( hpte1->dw0.dw0.v != 0 ) { if ( hpte1->dw1.dw1.rpn <= last_rpn ) { for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) { if ( hpte2->dw0.dw0.v != 0 ) { if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) { printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn)); printf(" hpte1: %16.16lx *hpte1: %16.16lx %16.16lx\n", hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1); printf(" hpte2: %16.16lx *hpte2: %16.16lx %16.16lx\n", hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1); } } } } else { printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn)); printf(" hpte: %16.16lx *hpte: %16.16lx %16.16lx\n", hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1); } } }#endif printf("\nDone -------------------\n");}void mem_find_real(){ unsigned long htab_size_bytes; unsigned long htab_end; unsigned long last_rpn; HPTE *hpte1; unsigned long pa, rpn; int c; c = inchar(); if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') termch = c; scanhex((void *)&pa); rpn = pa >> 12; htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG htab_end = (unsigned long)htab_data.htab + htab_size_bytes; // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT; last_rpn = 0xfffff; printf("\nMem Find RPN\n-------------------\n"); printf("htab base : %.16lx\n", htab_data.htab); printf("htab size : %.16lx\n", htab_size_bytes); for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) { if ( hpte1->dw0.dw0.v != 0 ) { if ( hpte1->dw1.dw1.rpn == rpn ) { printf(" Found rpn: %.13lx \n", (hpte1->dw1.dw1.rpn)); printf(" hpte: %16.16lx *hpte1: %16.16lx %16.16lx\n", hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1); } } } printf("\nDone -------------------\n");}void mem_find_vsid(){ unsigned long htab_size_bytes; unsigned long htab_end; HPTE *hpte1; unsigned long vsid; int c; c = inchar(); if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') termch = c; scanhex((void *)&vsid); htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG htab_end = (unsigned long)htab_data.htab + htab_size_bytes; printf("\nMem Find VSID\n-------------------\n"); printf("htab base : %.16lx\n", htab_data.htab); printf("htab size : %.16lx\n", htab_size_bytes); for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) { if ( hpte1->dw0.dw0.v != 0 ) { if ( ((hpte1->dw0.dw0.avpn)>>5) == vsid ) { printf(" Found vsid: %.16lx \n", ((hpte1->dw0.dw0.avpn) >> 5)); printf(" hpte: %16.16lx *hpte1: %16.16lx %16.16lx\n", hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1); } } } printf("\nDone -------------------\n");}void mem_map_check_slab(){ int i, slab_count; i = max_mapnr; slab_count = 0; while (i-- > 0) { if (PageSlab(mem_map+i)){ printf(" slab entry - mem_map entry =%p \n", mem_map+i); slab_count ++; } } printf(" count of pages for slab = %d \n", slab_count);}void mem_map_lock_pages(){ int i, lock_count; i = max_mapnr; lock_count = 0; while (i-- > 0) { if (PageLocked(mem_map+i)){ printf(" locked entry - mem_map entry =%p \n", mem_map+i); lock_count ++; } } printf(" count of locked pages = %d \n", lock_count); }void mem_map_check_hash(){ int i = max_mapnr; while (i-- > 0) { /* skip the reserved */ if (!PageReserved(mem_map+i)) { if (((mem_map+i)->next_hash) != NULL) { if ( REGION_ID((mem_map+i)->next_hash) != KERNEL_REGION_ID ) { printf(" mem_map check hash - non c0 entry - " "address/value = %p %lx\n", mem_map+i,(mem_map+i)->next_hash); } if ((unsigned long)((mem_map+i)->next_hash) == KERNELBASE){ printf(" mem_map check hash - 0x%lx entry = %p \n", KERNELBASE, mem_map+i); } } } else { if (page_count(mem_map+i) < 0) { printf(" reserved page with negative count- entry = %lx \n", mem_map+i); } } } printf(" mem_map check hash completed \n");}void mem_check_dup_rpn (){ unsigned long htab_size_bytes; unsigned long htab_end; unsigned long last_rpn; HPTE *hpte1, *hpte2; int dup_count; struct task_struct *p; unsigned long kernel_vsid_c0,kernel_vsid_c1,kernel_vsid_c2,kernel_vsid_c3; unsigned long kernel_vsid_c4,kernel_vsid_c5,kernel_vsid_d,kernel_vsid_e; unsigned long kernel_vsid_f; unsigned long vsid0,vsid1,vsidB,vsid2; htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG htab_end = (unsigned long)htab_data.htab + htab_size_bytes; // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT; last_rpn = 0xfffff; printf("\nHardware Page Table Check\n-------------------\n"); printf("htab base : %.16lx\n", htab_data.htab); printf("htab size : %.16lx\n", htab_size_bytes); for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) { if ( hpte1->dw0.dw0.v != 0 ) { if ( hpte1->dw1.dw1.rpn <= last_rpn ) { dup_count = 0; for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) { if ( hpte2->dw0.dw0.v != 0 ) { if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) { dup_count++; } } } if(dup_count > 5) { printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn)); printf(" mem map array entry %p count = %d \n", (mem_map+(hpte1->dw1.dw1.rpn)), (mem_map+(hpte1->dw1.dw1.rpn))->count); for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) { if ( hpte2->dw0.dw0.v != 0 ) { if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) { printf(" hpte2: %16.16lx *hpte2: %16.16lx %16.16lx\n", hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1); } } } } } else { printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn)); printf(" hpte: %16.16lx *hpte: %16.16lx %16.16lx\n", hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1); } } if (xmon_interrupted()) return; } // print the kernel vsids kernel_vsid_c0 = get_kernel_vsid(0xC000000000000000); kernel_vsid_c1 = get_kernel_vsid(0xC000000010000000); kernel_vsid_c2 = get_kernel_vsid(0xC000000020000000); kernel_vsid_c3 = get_kernel_vsid(0xC000000030000000); kernel_vsid_c4 = get_kernel_vsid(0xC000000040000000); kernel_vsid_c5 = get_kernel_vsid(0xC000000050000000); kernel_vsid_d = get_kernel_vsid(0xD000000000000000); kernel_vsid_e = get_kernel_vsid(0xE000000000000000); kernel_vsid_f = get_kernel_vsid(0xF000000000000000); printf(" kernel vsid - seg c0 = %lx\n", kernel_vsid_c0 ); printf(" kernel vsid - seg c1 = %lx\n", kernel_vsid_c1 ); printf(" kernel vsid - seg c2 = %lx\n", kernel_vsid_c2 ); printf(" kernel vsid - seg c3 = %lx\n", kernel_vsid_c3 ); printf(" kernel vsid - seg c4 = %lx\n", kernel_vsid_c4 ); printf(" kernel vsid - seg c5 = %lx\n", kernel_vsid_c5 ); printf(" kernel vsid - seg d = %lx\n", kernel_vsid_d ); printf(" kernel vsid - seg e = %lx\n", kernel_vsid_e ); printf(" kernel vsid - seg f = %lx\n", kernel_vsid_f ); // print a list of valid vsids for the tasks read_lock(&tasklist_lock); for_each_task(p) if(p->mm) { struct mm_struct *mm = p->mm; printf(" task = %p mm = %lx pgd %lx\n", p, mm, mm->pgd); vsid0 = get_vsid( mm->context, 0 ); vsid1 = get_vsid( mm->context, 0x10000000 ); vsid2 = get_vsid( mm->context, 0x20000000 ); vsidB = get_vsid( mm->context, 0xB0000000 ); printf(" context = %lx vsid seg 0 = %lx\n", mm->context, vsid0 ); printf(" vsid seg 1 = %lx\n", vsid1 ); printf(" vsid seg 2 = %lx\n", vsid2 ); printf(" vsid seg 2 = %lx\n", vsidB ); printf("\n"); }; read_unlock(&tasklist_lock); printf("\nDone -------------------\n");}void mem_check_pagetable_vsids (){ unsigned long htab_size_bytes; unsigned long htab_end; unsigned long last_rpn; struct task_struct *p; unsigned long valid_table_count,invalid_table_count,bogus_rpn_count; int found; unsigned long user_address_table_count,kernel_page_table_count; unsigned long pt_vsid; HPTE *hpte1; htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG htab_end = (unsigned long)htab_data.htab + htab_size_bytes; // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT; last_rpn = 0xfffff; printf("\nHardware Page Table Check\n-------------------\n"); printf("htab base : %.16lx\n", htab_data.htab); printf("htab size : %.16lx\n", htab_size_bytes); valid_table_count = 0; invalid_table_count = 0; bogus_rpn_count = 0; user_address_table_count = 0; kernel_page_table_count = 0; for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) { if ( hpte1->dw0.dw0.v != 0 ) { valid_table_count++; if ( hpte1->dw1.dw1.rpn <= last_rpn ) { pt_vsid = (hpte1->dw0.dw0.avpn) >> 5; if ((pt_vsid == get_kernel_vsid(0xC000000000000000)) | (pt_vsid == get_kernel_vsid(0xC000000010000000)) | (pt_vsid == get_kernel_vsid(0xC000000020000000)) | (pt_vsid == get_kernel_vsid(0xC000000030000000)) | (pt_vsid == get_kernel_vsid(0xC000000040000000)) | (pt_vsid == get_kernel_vsid(0xC000000050000000)) | (pt_vsid == get_kernel_vsid(0xD000000000000000)) | (pt_vsid == get_kernel_vsid(0xE000000000000000)) | (pt_vsid == get_kernel_vsid(0xF000000000000000)) ) { kernel_page_table_count ++; } else { read_lock(&tasklist_lock); found = 0; for_each_task(p) { if(p->mm && (found == 0)) { struct mm_struct *mm = p->mm; if ((pt_vsid == get_vsid( mm->context, 0 )) | (pt_vsid == get_vsid( mm->context, 0x10000000 )) | (pt_vsid == get_vsid( mm->context, 0x20000000 )) | (pt_vsid == get_vsid( mm->context, 0x30000000 )) | (pt_vsid == get_vsid( mm->context, 0x40000000 )) | (pt_vsid == get_vsid( mm->context, 0x50000000 )) | (pt_vsid == get_vsid( mm->context, 0x60000000 )) | (pt_vsid == get_vsid( mm->context, 0x70000000 )) | (pt_vsid == get_vsid( mm->context, 0x80000000 )) | (pt_vsid == get_vsid( mm->context, 0x90000000 )) | (pt_vsid == get_vsid( mm->context, 0xA0000000 )) | (pt_vsid == get_vsid( mm->context, 0xB0000000 ))) { user_ad
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -