Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/aarch64 - add ddb command "machine ttbr" to dump MM...



details:   https://anonhg.NetBSD.org/src/rev/53ba1d73b0e4
branches:  trunk
changeset: 449750:53ba1d73b0e4
user:      ryo <ryo%NetBSD.org@localhost>
date:      Tue Mar 19 16:45:28 2019 +0000

description:
- add ddb command "machine ttbr" to dump MMU tables.
- tidy up descriptions, usages and messages.

diffstat:

 sys/arch/aarch64/aarch64/db_machdep.c |   80 ++++++++++++++++---
 sys/arch/aarch64/aarch64/pmap.c       |  137 +++++++++++++++++++++++++++++++--
 sys/arch/aarch64/include/pmap.h       |    4 +-
 3 files changed, 197 insertions(+), 24 deletions(-)

diffs (truncated from 385 to 300 lines):

diff -r d823d5a387d3 -r 53ba1d73b0e4 sys/arch/aarch64/aarch64/db_machdep.c
--- a/sys/arch/aarch64/aarch64/db_machdep.c     Tue Mar 19 16:05:49 2019 +0000
+++ b/sys/arch/aarch64/aarch64/db_machdep.c     Tue Mar 19 16:45:28 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.c,v 1.14 2019/01/27 02:08:36 pgoyette Exp $ */
+/* $NetBSD: db_machdep.c,v 1.15 2019/03/19 16:45:28 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.14 2019/01/27 02:08:36 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.15 2019/03/19 16:45:28 ryo Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd32.h"
@@ -54,6 +54,7 @@
 #include <ddb/db_access.h>
 #include <ddb/db_command.h>
 #include <ddb/db_output.h>
+#include <ddb/db_proc.h>
 #include <ddb/db_variables.h>
 #include <ddb/db_run.h>
 #include <ddb/db_sym.h>
@@ -68,6 +69,7 @@
 void db_md_lwp_cmd(db_expr_t, bool, db_expr_t, const char *);
 void db_md_pte_cmd(db_expr_t, bool, db_expr_t, const char *);
 void db_md_tlbi_cmd(db_expr_t, bool, db_expr_t, const char *);
+void db_md_ttbr_cmd(db_expr_t, bool, db_expr_t, const char *);
 void db_md_sysreg_cmd(db_expr_t, bool, db_expr_t, const char *);
 void db_md_watch_cmd(db_expr_t, bool, db_expr_t, const char *);
 #if defined(_KERNEL) && defined(MULTIPROCESSOR)
@@ -87,28 +89,28 @@
        {
                DDB_ADD_CMD(
                    "cpuinfo", db_md_cpuinfo_cmd, 0,
-                   "Displays the cpuinfo",
+                   "Displays the current cpuinfo",
                    NULL, NULL)
        },
        {
                DDB_ADD_CMD(
                    "frame", db_md_frame_cmd, 0,
                    "Displays the contents of a trapframe",
-                   "<address>",
-                   "\taddress:\taddress of trapfame to display")
+                   "address",
+                   "\taddress:\taddress of trapframe to display")
        },
        {
                DDB_ADD_CMD(
                    "lwp", db_md_lwp_cmd, 0,
                    "Displays the lwp",
-                   "<address>",
+                   "address",
                    "\taddress:\taddress of lwp to display")
        },
        {
                DDB_ADD_CMD(
                    "pte", db_md_pte_cmd, 0,
                    "Display information of pte",
-                   "<address>",
+                   "address",
                    "\taddress:\tvirtual address of page")
        },
        {
@@ -125,16 +127,26 @@
        },
        {
                DDB_ADD_CMD(
+                   "ttbr", db_md_ttbr_cmd, 0,
+                   "Dump or count TTBR table",
+                   "[/apc] address | pid",
+                   "\taddress:\taddress of pmap to display\n"
+                   "\tpid:\t\tpid of pmap to display")
+       },
+       {
+               DDB_ADD_CMD(
                    "watch", db_md_watch_cmd, 0,
                    "set or clear watchpoint",
-                   "<param>",
-                   "\tparam: <address> | <#>")
+                   "[/12345678] [address|#]",
+                   "\taddress: watchpoint address to set\n"
+                   "\t#: watchpoint number to remove"
+                   "\t/1..8: size of data\n")
        },
 #endif
        {
                DDB_ADD_CMD(NULL, NULL, 0,
                    NULL,
-                   NULL,NULL)
+                   NULL, NULL)
        }
 };
 
@@ -290,7 +302,7 @@
        struct trapframe *tf;
 
        if (!have_addr) {
-               db_printf("frame: <address>\n");
+               db_printf("frame address must be specified\n");
                return;
        }
 
@@ -306,7 +318,7 @@
        struct pcb *pcb;
 
        if (!have_addr) {
-               db_printf("lwp: <address>\n");
+               db_printf("lwp address must be specified\n");
                return;
        }
        l = (lwp_t *)addr;
@@ -339,7 +351,7 @@
     const char *modif)
 {
        if (!have_addr) {
-               db_printf("pte: <address>\n");
+               db_printf("pte address must be specified\n");
                return;
        }
        pmap_db_pteinfo(addr, db_printf);
@@ -353,6 +365,48 @@
 }
 
 void
+db_md_ttbr_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
+    const char *modif)
+{
+       bool countmode = false, by_pid = true;
+
+       if (!have_addr) {
+               db_printf("usage: machine ttbr [/a] [/p] [/c] address|pid\n");
+               db_printf("\t/a == argument is an address of any pmap_t\n");
+               db_printf("\t/p == argument is a pid [default]\n");
+               db_printf("\t/c == count TLB entries\n");
+               return;
+       }
+
+       if (modif != NULL) {
+               for (; *modif != '\0'; modif++) {
+                       switch (*modif) {
+                       case 'c':
+                               countmode = true;
+                               break;
+                       case 'a':
+                               by_pid = false;
+                               break;
+                       case 'p':
+                               by_pid = true;
+                               break;
+                       }
+               }
+       }
+
+       if (by_pid) {
+               proc_t *p = db_proc_find((pid_t)addr);
+               if (p == NULL) {
+                       db_printf("bad address\n");
+                       return;
+               }
+               addr = (db_addr_t)p->p_vmspace->vm_map.pmap;
+       }
+
+       pmap_db_ttbrdump(countmode, addr, db_printf);
+}
+
+void
 db_md_sysreg_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
     const char *modif)
 {
diff -r d823d5a387d3 -r 53ba1d73b0e4 sys/arch/aarch64/aarch64/pmap.c
--- a/sys/arch/aarch64/aarch64/pmap.c   Tue Mar 19 16:05:49 2019 +0000
+++ b/sys/arch/aarch64/aarch64/pmap.c   Tue Mar 19 16:45:28 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.36 2019/03/19 16:05:49 ryo Exp $    */
+/*     $NetBSD: pmap.c,v 1.37 2019/03/19 16:45:28 ryo Exp $    */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.36 2019/03/19 16:05:49 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.37 2019/03/19 16:45:28 ryo Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_ddb.h"
@@ -50,6 +50,10 @@
 #include <aarch64/armreg.h>
 #include <aarch64/cpufunc.h>
 #include <aarch64/machdep.h>
+#ifdef DDB
+#include <aarch64/db_machdep.h>
+#include <ddb/db_access.h>
+#endif
 
 //#define PMAP_DEBUG
 //#define PMAP_PV_DEBUG
@@ -2165,6 +2169,7 @@
 }
 
 #ifdef DDB
+
 /* get pointer to kernel segment L2 or L3 table entry */
 pt_entry_t *
 kvtopte(vaddr_t va)
@@ -2232,7 +2237,7 @@
                if ((level == 0) && ((pte & LX_TYPE) != LX_TYPE_TBL))
                        pr(" **ILLEGAL TYPE**"); /* L0 doesn't support block */
                else
-                       pr(" TABLE");
+                       pr(" L%d-TABLE", level);
 
                pr(", PA=%lx", l0pde_pa(pte));
 
@@ -2250,22 +2255,35 @@
            (level == 3)) {
 
                /* L1/L2 BLOCK or L3 PAGE */
-               if (level == 3) {
+               switch (level) {
+               case 1:
+                       pr(" L1(1G)-BLOCK");
+                       break;
+               case 2:
+                       pr(" L2(2M)-BLOCK");
+                       break;
+               case 3:
                        pr(" %s", l3pte_is_page(pte) ?
-                           "PAGE" : "**ILLEGAL TYPE**");
-               } else
-                       pr(" BLOCK");
+                           "L3(4K)-PAGE" : "**ILLEGAL TYPE**");
+                       break;
+               }
 
                pr(", PA=%lx", l3pte_pa(pte));
 
-               pr(", %s", (pte & LX_BLKPAG_UXN) ? "UXN" : "user-exec");
-               pr(", %s", (pte & LX_BLKPAG_PXN) ? "PXN" : "kernel-exec");
+               pr(", %s", (pte & LX_BLKPAG_UXN) ?
+                   "UXN      " :
+                   "user-exec");
+               pr(", %s", (pte & LX_BLKPAG_PXN) ?
+                  "PXN        " :
+                  "kernel-exec");
 
                if (pte & LX_BLKPAG_CONTIG)
                        pr(", CONTIG");
 
                pr(", %s", (pte & LX_BLKPAG_NG) ? "NG" : "global");
-               pr(", %s", (pte & LX_BLKPAG_AF) ? "AF" : "*cannot-access*");
+               pr(", %s", (pte & LX_BLKPAG_AF) ?
+                   "accessible" :
+                   "**fault** ");
 
                switch (pte & LX_BLKPAG_SH) {
                case LX_BLKPAG_SH_NS:
@@ -2396,4 +2414,103 @@
                pv_dump(md, pr);
        }
 }
+
+static void
+dump_ln_table(bool countmode, pd_entry_t *pdp, int level, int lnindex,
+    vaddr_t va, void (*pr)(const char *, ...))
+{
+       struct vm_page *pg;
+       struct vm_page_md *md;
+       pd_entry_t pde;
+       paddr_t pa;
+       int i, n;
+       const char *spaces[4] = { " ", "  ", "   ", "    " };
+       const char *spc = spaces[level];
+
+       pa = AARCH64_KVA_TO_PA((vaddr_t)pdp);
+       pg = PHYS_TO_VM_PAGE(pa);
+       md = VM_PAGE_TO_MD(pg);
+
+       if (pg == NULL) {
+               pr("%sL%d: pa=%lx pg=NULL\n", spc, level, pa);
+       } else {
+               pr("%sL%d: pa=%lx pg=%p, wire_count=%d, mdpg_ptep_parent=%p\n",
+                   spc, level, pa, pg, pg->wire_count, md->mdpg_ptep_parent);
+       }
+
+       for (i = n = 0; i < Ln_ENTRIES; i++) {
+               db_read_bytes((db_addr_t)&pdp[i], sizeof(pdp[i]), (char *)&pde);
+               if (lxpde_valid(pde)) {
+                       if (!countmode)
+                               pr("%sL%d[%3d] %3dth, va=%016lx, pte=%016lx:",
+                                   spc, level, i, n, va, pde);
+                       n++;
+
+                       if (((level != 0) && (level != 3) &&



Home | Main Index | Thread Index | Old Index