1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#include "browser.h" 14 15#ifdef CONFIG_LIB_SEL4_ACPI_DEBUG 16 17#include "acpi.h" 18#include "regions.h" 19#include "printer.h" 20 21#include <stdio.h> 22#include <string.h> 23 24static int 25_browse_tables(void* table, size_t offset) 26{ 27 /* 28 * NOTE: offset added to address JUST BEFORE moving 29 * to the next table 30 */ 31 void* vector[26] = {NULL}; 32 33 printf("reading table at %p\n", table); 34 35 do { 36 37 // print table and set links 38 printf("\n"); 39 region_type_t table_type = acpi_sig_id(table); 40 char input; 41 42 switch (table_type) { 43 case ACPI_RSDP: { 44 printf("Root System Descriptor table Pointer\n"); 45 acpi_print_table(table); 46 acpi_rsdp_t* rsdp = (acpi_rsdp_t*)table; 47 vector[0] = (void*)rsdp->rsdt_address; 48 vector[1] = (void*)(uintptr_t)rsdp->xsdt_address; 49 printf("\n"); 50 printf("a - RSDT at %p\n", vector[0]); 51 printf("b - XSDT at %p\n", vector[1]); 52 break; 53 } 54 case ACPI_RSDT: { 55 printf("Root System Descriptor Table\n"); 56 acpi_print_table(table); 57 acpi_rsdt_t* rsdt = (acpi_rsdt_t*)table; 58 printf("\n"); 59 int i = 0; 60 uint32_t* entry = acpi_rsdt_first(rsdt); 61 while (entry != NULL) { 62 char sig[5]; 63 sig[4] = '\0'; 64 memcpy(sig, (char*)(*entry) + offset, 4); 65 vector[i] = (void*)(*entry); 66 printf("%c - %s table at %p\n", i + 'a', sig, vector[i]); 67 i++; 68 entry = acpi_rsdt_next(rsdt, entry); 69 } 70 break; 71 } 72 case ACPI_XSDT: { 73 printf("eXtended root System Descriptor Table\n"); 74 acpi_print_table(table); 75 acpi_xsdt_t* xsdt = (acpi_xsdt_t*)table; 76 printf("\n"); 77 int i = 0; 78 uint64_t* entry = acpi_xsdt_first(xsdt); 79 while (entry != NULL) { 80 char sig[5]; 81 sig[4] = '\0'; 82 char* _e = (char*)(uintptr_t)(*entry); 83 memcpy(sig, _e, 4); 84 vector[i] = _e; 85 printf("%c - %s table at %p\n", i + 'a', sig, vector[i]); 86 i++; 87 entry = acpi_xsdt_next(xsdt, entry); 88 } 89 break; 90 } 91 case ACPI_FADT: { 92 printf("Fixed ACPI Description Table\n"); 93 acpi_print_table(table); 94 acpi_fadt_t* fadt = (acpi_fadt_t*)table; 95 vector[0] = (void*)fadt->facs_address; 96 vector[1] = (void*)fadt->dsdt_address; 97 vector[2] = (void*)(uintptr_t)fadt->x_facs_address; 98 vector[3] = (void*)(uintptr_t)fadt->x_dsdt_address; 99 printf("\n"); 100 printf("a - FACS at %p\n", vector[0]); 101 printf("b - DSDT at %p\n", vector[1]); 102 printf("c - XFACS at %p\n", vector[2]); 103 printf("d - XDSDT at %p\n", vector[3]); 104 break; 105 } 106 case ACPI_FACS: { 107 printf("Firmware ACPI Constrol Structure\n"); 108 acpi_print_table(table); 109 acpi_facs_t* facs = (acpi_facs_t*)table; 110 vector[0] = (void*)facs->firmware_walking_vector; 111 vector[3] = (void*)(uintptr_t)facs->x_firmware_walking_vector; 112 printf("\n"); 113 printf("a - Firware Walking vector at %p\n", vector[0]); 114 printf("b - X Firware walking vector at %p\n", vector[1]); 115 break; 116 } 117 case ACPI_MCFG: 118 printf("PCI Memory mapped ConFiGuration\n"); 119 acpi_print_table(table); 120 break; 121 case ACPI_DSDT: 122 printf("Differentiated System Description Table\n"); 123 acpi_print_table(table); 124 break; 125 case ACPI_SSDT: 126 printf("Secondary System Description Table\n"); 127 acpi_print_table(table); 128 break; 129 case ACPI_SPMI: 130 printf("Server Platform Management Interface table\n"); 131 acpi_print_table(table); 132 break; 133 case ACPI_HPET: 134 printf("High Precision Event Timer table\n"); 135 acpi_print_table(table); 136 break; 137 case ACPI_SPCR: 138 printf("Serial Port Console Redirection table\n"); 139 acpi_print_table(table); 140 break; 141 case ACPI_BOOT: 142 printf("Boot flags table\n"); 143 acpi_print_table(table); 144 break; 145 case ACPI_DMAR: 146 printf("DMA Remapping table\n"); 147 acpi_print_table(table); 148 break; 149 case ACPI_ASF : 150 printf("Alert Standard Format table\n"); 151 acpi_print_table(table); 152 break; 153 case ACPI_HEST: 154 printf("Hardware Error Source Table\n"); 155 acpi_print_table(table); 156 break; 157 case ACPI_ERST: 158 printf("Error Record Serialisation Table\n"); 159 acpi_print_table(table); 160 break; 161 case ACPI_BERT: 162 printf("Boot Error Record Table\n"); 163 acpi_print_table(table); 164 break; 165 case ACPI_EINJ: 166 printf("Error INjection Table\n"); 167 acpi_print_table(table); 168 break; 169 case ACPI_MADT: 170 printf("Multiple Apic Descriptor table\n"); 171 acpi_print_table(table); 172 break; 173 case ACPI_ASPT: 174 printf("ASPT -- Unknown table\n"); 175 acpi_print_table(table); 176 break; 177 178 default: 179 printf("Unknown Table\n"); 180 acpi_print_table(table); 181 } 182 183 // collect input and act 184 do { 185 printf(">>"); 186 input = getchar(); 187 188 if (input >= 'a' && input <= 'z') { 189 // input steps into another table 190 if (vector[input - 'a'] != NULL) { 191 void* next_tbl; 192 next_tbl = vector[input - 'a'] + offset; 193 if (_browse_tables(next_tbl, offset)) { 194 return 1 /* quit */; 195 } else { 196 input = 'p'; 197 } 198 } 199 } 200 // other options 201 switch (input) { 202 case 'p': 203 break; 204 case 'q': 205 return 1; 206 case '\\': 207 return 0; 208 case '?': 209 default: 210 printf("\n" 211 "p - print table\n" 212 "q - quit\n" 213 "\\ - go up 1 table level\n" 214 "[a-z] Traverse tables\n"); 215 break; 216 } 217 } while (input != 'p'); 218 } while (1); 219} 220 221void 222acpi_browse_tables(const acpi_rsdp_t* rsdp, size_t offset) 223{ 224 _browse_tables((void*)rsdp, offset); 225} 226 227static int 228_browse_regions(const RegionList_t* rlist, int parent) 229{ 230 /* 231 * NOTE: We don't use offsets here because we are following 232 * the absolute address listed in the region list instead of 233 * the link addresses contained within the tables. 234 */ 235 236 while (1) { 237 /* print table at region "parent" */ 238 if (parent != NOPARENT) { 239 acpi_print_table(rlist->regions[parent].start); 240 } else { 241 printf("Root tables\n"); 242 } 243 244 /* print children */ 245 int children[MAX_REGIONS]; 246 int child_count = 0; 247 int i; 248 for (i = 0; i < rlist->region_count; i++) { 249 const Region_t* r = rlist->regions + i; 250 if (r->parent == parent) { 251 const char* sig = acpi_sig_str(r->type); 252 char key = child_count + 'a'; 253 printf("%c - %s at %p\n", key, sig, r->start); 254 children[child_count++] = i; 255 } 256 } 257 258 do { 259 printf(">>"); 260 char input = getchar(); 261 printf("%c\n\n", input); 262 263 unsigned char key = input - 'a'; 264 if (key < child_count) { 265 // input steps into another table 266 if (_browse_regions(rlist, children[key])) { 267 return 1 /* quit */; 268 } else { 269 break; /* restart loop, print tables */ 270 } 271 } 272 273 // other options 274 switch (input) { 275 case 'p': 276 break; /* restart loop, print tables */ 277 case 'q': 278 return 1; /* exit */ 279 case '\\': 280 return 0; /* up one level */ 281 case '?': 282 default: 283 printf("\n" 284 "p - print table\n" 285 "q - quit\n" 286 "\\ - go up 1 table level\n" 287 "[a-%c] Traverse tables\n", 288 'a' + child_count); 289 break; 290 } 291 } while (1); 292 } 293 while (1); 294} 295 296void 297acpi_browse_regions(const RegionList_t* rlist) 298{ 299 _browse_regions(rlist, NOPARENT); 300} 301 302#endif 303