1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <config.h> 8 9#ifdef CONFIG_DEBUG_BUILD 10 11#include <machine/capdl.h> 12#include <arch/machine/capdl.h> 13 14static void obj_asidpool_print_attrs(cap_t asid_cap); 15static void obj_frame_print_attrs(paddr_t paddr); 16static void riscv_obj_pt_print_slots(pte_t *lvl1pt, pte_t *pt, int level); 17static void cap_frame_print_attrs_vptr(word_t vptr, pte_t *lvl1pt); 18static void cap_frame_print_attrs_pt(pte_t *ptSlot); 19 20static void obj_asidpool_print_attrs(cap_t asid_cap) 21{ 22 asid_t asid = cap_asid_pool_cap_get_capASIDBase(asid_cap); 23 printf("(asid_high: 0x%lx)\n", ASID_HIGH(asid)); 24} 25 26void print_ipc_buffer_slot(tcb_t *tcb) 27{ 28 word_t vptr = tcb->tcbIPCBuffer; 29 asid_t asid = cap_page_table_cap_get_capPTMappedASID(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap); 30 findVSpaceForASID_ret_t find_ret = findVSpaceForASID(asid); 31 32 printf("ipc_buffer_slot: "); 33 cap_frame_print_attrs_vptr(vptr, find_ret.vspace_root); 34} 35 36static void riscv_cap_pt_print_slots(pte_t *upperPtSlot, word_t ptIndex, int level) 37{ 38 pte_t *pt; 39 if (level == CONFIG_PT_LEVELS) { 40 printf("%p_pd {\n", upperPtSlot); 41 pt = upperPtSlot; 42 } else { 43 printf("pt_%p_%04lu {\n", upperPtSlot, ptIndex); 44 pt = getPPtrFromHWPTE(upperPtSlot); 45 } 46 level -= 1; 47 48 word_t ptBitsLeft = PT_INDEX_BITS * level + seL4_PageBits; 49 50 /* - 1 to avoid overflowing */ 51 for (word_t i = 0; i < BIT(ptBitsLeft + PT_INDEX_BITS) - 1; i += (1 << (ptBitsLeft))) { 52 word_t ptSlotIndex = ((i >> ptBitsLeft) & MASK(PT_INDEX_BITS)); 53 pte_t *ptSlot = pt + ptSlotIndex; 54 if (pte_ptr_get_valid(ptSlot)) { 55 if (level) { /* pt */ 56 printf("0x%lx: pt_%p_%04lu\n", ptSlotIndex, ptSlot, ptSlotIndex); 57 } else { /* frame */ 58 printf("0x%lx: frame_%p_%04lu", ptSlotIndex, ptSlot, ptSlotIndex); 59 cap_frame_print_attrs_pt(ptSlot); 60 } 61 } 62 } 63 printf("}\n"); /* lvl1pt/pt */ 64 65 for (word_t i = 0; i < BIT(ptBitsLeft + PT_INDEX_BITS) - 1; i += (1 << (ptBitsLeft))) { 66 word_t ptSlotIndex = ((i >> ptBitsLeft) & MASK(PT_INDEX_BITS)); 67 pte_t *ptSlot = pt + ptSlotIndex; 68 if (pte_ptr_get_valid(ptSlot)) { 69 if (level) { /* pt */ 70 riscv_cap_pt_print_slots(ptSlot, ptSlotIndex, level); 71 } 72 } 73 } 74} 75 76void obj_vtable_print_slots(tcb_t *tcb) 77{ 78 if (isValidVTableRoot(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap) && !seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)) { 79 pte_t *lvl1pt = PTE_PTR(pptr_of_cap(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)); 80 add_to_seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap); 81 riscv_cap_pt_print_slots(lvl1pt, 0, CONFIG_PT_LEVELS); 82 } 83} 84 85word_t get_tcb_sp(tcb_t *tcb) 86{ 87 return tcb->tcbArch.tcbContext.registers[SP]; 88} 89 90static void cap_frame_print_attrs_pt(pte_t *ptSlot) 91{ 92 printf("("); 93 94 /* rights */ 95 if (pte_ptr_get_read(ptSlot)) { 96 printf("R"); 97 } 98 99 if (pte_ptr_get_write(ptSlot)) { 100 printf("W"); 101 } 102 103 if (pte_ptr_get_execute(ptSlot)) { 104 printf("X"); 105 } 106 107 /* cacheable not supported yet */ 108 109 printf(")\n"); 110} 111 112static void cap_frame_print_attrs_vptr(word_t vptr, pte_t *lvl1pt) 113{ 114 lookupPTSlot_ret_t lu_ret = lookupPTSlot(lvl1pt, vptr); 115 assert(lu_ret.ptBitsLeft == seL4_PageBits); 116 word_t slot = ((vptr >> lu_ret.ptBitsLeft) & MASK(PT_INDEX_BITS)); 117 118 printf("frame_%p_%04lu ", lu_ret.ptSlot, slot); 119 cap_frame_print_attrs_pt(lu_ret.ptSlot); 120} 121 122void print_cap_arch(cap_t cap) 123{ 124 switch (cap_get_capType(cap)) { 125 case cap_page_table_cap: { 126 asid_t asid = cap_page_table_cap_get_capPTMappedASID(cap); 127 findVSpaceForASID_ret_t find_ret = findVSpaceForASID(asid); 128 vptr_t vptr = cap_page_table_cap_get_capPTMappedAddress(cap); 129 130 word_t ptBitsLeft = PT_INDEX_BITS * CONFIG_PT_LEVELS + seL4_PageBits; 131 word_t slot = ((vptr >> ptBitsLeft) & MASK(PT_INDEX_BITS)); 132 if (asid) { 133 printf("pt_%p_%04lu (asid: %lu)\n", 134 lookupPTSlot(find_ret.vspace_root, vptr).ptSlot, slot, (long unsigned int)asid); 135 } else { 136 printf("pt_%p_%04lu\n", lookupPTSlot(find_ret.vspace_root, vptr).ptSlot, slot); 137 } 138 break; 139 } 140 case cap_asid_control_cap: { 141 /* only one in the system */ 142 printf("asid_control\n"); 143 break; 144 } 145 case cap_frame_cap: { 146 vptr_t vptr = cap_frame_cap_get_capFMappedAddress(cap); 147 findVSpaceForASID_ret_t find_ret = findVSpaceForASID(cap_frame_cap_get_capFMappedASID(cap)); 148 149 assert(find_ret.status == EXCEPTION_NONE); 150 cap_frame_print_attrs_vptr(vptr, find_ret.vspace_root); 151 break; 152 } 153 case cap_asid_pool_cap: { 154 printf("%p_asid_pool\n", (void *)cap_asid_pool_cap_get_capASIDPool(cap)); 155 break; 156 } 157 /* riscv specific caps */ 158 /* nothing */ 159 default: { 160 printf("[unknown cap %lu]\n", (long unsigned int)cap_get_capType(cap)); 161 break; 162 } 163 } 164} 165 166static void obj_frame_print_attrs(paddr_t paddr) 167{ 168 printf("(4k, paddr: 0x%p)\n", (void *)paddr); 169} 170 171void print_object_arch(cap_t cap) 172{ 173 switch (cap_get_capType(cap)) { 174 case cap_frame_cap: 175 case cap_page_table_cap: 176 /* don't need to deal with these objects since they get handled from vtable */ 177 break; 178 179 case cap_asid_pool_cap: { 180 printf("%p_asid_pool = asid_pool ", 181 (void *)cap_asid_pool_cap_get_capASIDPool(cap)); 182 obj_asidpool_print_attrs(cap); 183 break; 184 } 185 /* riscv specific caps */ 186 /* nothing */ 187 default: { 188 printf("[unknown object %lu]\n", (long unsigned int)cap_get_capType(cap)); 189 break; 190 } 191 } 192} 193 194static void riscv_obj_pt_print_slots(pte_t *lvl1pt, pte_t *pt, int level) 195{ 196 word_t ptBitsLeft = PT_INDEX_BITS * level + seL4_PageBits; 197 198 for (word_t i = 0; i < BIT(ptBitsLeft + PT_INDEX_BITS); i += (1 << (ptBitsLeft))) { 199 word_t ptIndex = ((i >> ptBitsLeft) & MASK(PT_INDEX_BITS)); 200 pte_t *ptSlot = pt + ptIndex; 201 if (pte_ptr_get_valid(ptSlot)) { 202 if (level) { /* pt */ 203 printf("pt_%p_%04lu = pt\n", ptSlot, ptIndex); 204 riscv_obj_pt_print_slots(lvl1pt, getPPtrFromHWPTE(ptSlot), level - 1); 205 } else { /* frame */ 206 paddr_t paddr = pte_ptr_get_ppn(ptSlot); 207 printf("frame_%p_%04lu = frame ", ptSlot, ptIndex); 208 obj_frame_print_attrs(paddr); 209 } 210 } 211 } 212} 213 214void obj_tcb_print_vtable(tcb_t *tcb) 215{ 216 if (isValidVTableRoot(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap) && !seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)) { 217 add_to_seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap); 218 pte_t *lvl1pt = PTE_PTR(pptr_of_cap(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)); 219 printf("%p_pd = pt\n", lvl1pt); 220 riscv_obj_pt_print_slots(lvl1pt, lvl1pt, CONFIG_PT_LEVELS - 1); 221 } 222} 223 224void capDL(void) 225{ 226 printf("arch riscv32\n"); 227 printf("objects {\n"); 228 print_objects(); 229 printf("}\n"); 230 231 printf("caps {\n"); 232 233 /* reset the seen list */ 234 reset_seen_list(); 235 236 print_caps(); 237 printf("}\n"); 238 239 obj_irq_print_maps(); 240} 241 242#endif /* CONFIG_DEBUG_BUILD */ 243