1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2014 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 
8 #include <err.h>
9 #include <inttypes.h>
10 #include <lib/console.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <trace.h>
14 #include <vm/page.h>
15 #include <vm/physmap.h>
16 #include <vm/pmm.h>
17 #include <vm/vm.h>
18 
19 #define LOCAL_TRACE 0
20 
page_state_to_string(unsigned int state)21 const char* page_state_to_string(unsigned int state) {
22     switch (state) {
23     case VM_PAGE_STATE_FREE:
24         return "free";
25     case VM_PAGE_STATE_ALLOC:
26         return "alloc";
27     case VM_PAGE_STATE_WIRED:
28         return "wired";
29     case VM_PAGE_STATE_HEAP:
30         return "heap";
31     case VM_PAGE_STATE_OBJECT:
32         return "object";
33     case VM_PAGE_STATE_MMU:
34         return "mmu";
35     case VM_PAGE_STATE_IPC:
36         return "ipc";
37     default:
38         return "unknown";
39     }
40 }
41 
dump() const42 void vm_page::dump() const {
43     printf("page %p: address %#" PRIxPTR " state %s flags %#x\n", this, paddr(),
44            page_state_to_string(state), flags);
45 }
46 
cmd_vm_page(int argc,const cmd_args * argv,uint32_t flags)47 static int cmd_vm_page(int argc, const cmd_args* argv, uint32_t flags) {
48     if (argc < 2) {
49     notenoughargs:
50         printf("not enough arguments\n");
51     usage:
52         printf("usage:\n");
53         printf("%s dump <address>\n", argv[0].str);
54         printf("%s hexdump <address>\n", argv[0].str);
55         return ZX_ERR_INTERNAL;
56     }
57 
58     if (!strcmp(argv[1].str, "dump")) {
59         if (argc < 2) {
60             goto notenoughargs;
61         }
62 
63         vm_page* page = reinterpret_cast<vm_page*>(argv[2].u);
64 
65         page->dump();
66     } else if (!strcmp(argv[1].str, "hexdump")) {
67         if (argc < 2) {
68             goto notenoughargs;
69         }
70 
71         vm_page* page = reinterpret_cast<vm_page*>(argv[2].u);
72 
73         paddr_t pa = page->paddr();
74         void* ptr = paddr_to_physmap(pa);
75         if (!ptr) {
76             printf("bad page or page not mapped in kernel space\n");
77             return -1;
78         }
79         hexdump(ptr, PAGE_SIZE);
80     } else {
81         printf("unknown command\n");
82         goto usage;
83     }
84 
85     return ZX_OK;
86 }
87 
88 STATIC_COMMAND_START
89 #if LK_DEBUGLEVEL > 0
90 STATIC_COMMAND("vm_page", "vm_page debug commands", &cmd_vm_page)
91 #endif
92 STATIC_COMMAND_END(vm_page);
93