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 "printer.h" 14 15#ifdef CONFIG_LIB_SEL4_ACPI_DEBUG 16 17/************************ 18 **** Debug features **** 19 ************************/ 20#include <acpi/acpi.h> 21#include "acpi.h" 22 23#include <stdio.h> 24#include <string.h> 25 26static char 27pprint(char c) 28{ 29 if (c < 0x32) { 30 return '.'; 31 } 32 if (c < 0x7F) { 33 return c; 34 } 35 return '.'; 36} 37 38void 39colour_bf(int i, const char* ptr) 40{ 41 if (i == 3 && ((*ptr) & 0xff) == 0xbf) { 42 printf("\033[01;31m"); 43 } 44} 45 46void 47colour_1a(int i, const char* ptr) 48{ 49 (void)i; 50 if (((*ptr) & 0xff) == 0x1a) { 51 printf("\033[01;29m"); 52 } 53} 54 55void 56colour_1d(int i, const char* ptr) 57{ 58 (void)i; 59 if (((*ptr) & 0xff) == 0x1d) { 60 printf("\033[01;28m"); 61 } 62} 63 64static void 65colour(int i, const char* ptr) 66{ 67 colour_bf(i, ptr); 68 colour_1a(i, ptr); 69 colour_1d(i, ptr); 70} 71 72// print the raw table with "indent" printed before each column 73void 74acpi_print_table_raw(const void* start, int length) 75{ 76 int i, j; 77 const char *ptr = start; 78 const char *end = start + length; 79 80 while (1) { 81 // store pointer to start of row for txt printing later 82 const char* row_start = ptr; 83 84 // Col1 : position 85 printf("0x%p: ", row_start); 86 // print hex values 87 for (i = 0; i < 4; i++) { 88 for (j = 0; j < 4; j++) { 89 if (ptr == end) { 90 printf(" "); 91 } else { 92 colour(j, ptr); 93 printf("%02x ", (*ptr++) & 0xff); 94 printf("\033[00m"); 95 } 96 } 97 printf(" "); 98 } 99 // print txt 100 ptr = row_start; 101 for (i = 0; i < 4; i++) { 102 for (j = 0; j < 4; j++) { 103 printf("%c", pprint(*ptr++)); 104 if (ptr == end) { 105 printf("\n"); 106 return; 107 } 108 } 109 printf(" "); 110 } 111 printf("\n"); 112 } 113} 114 115static void 116print_path(acpi_dmar_dscope_t* dscope) 117{ 118 int entries = acpi_dmar_dscope_path_length(dscope); 119 acpi_device_path_t* path = acpi_dmar_path_first(dscope); 120 printf("\t\t<<<Path>>>\n"); 121 while (entries-- > 0) { 122 printf("\t\tPCI device number = 0x%02x, ", path->device & 0xff); 123 printf("PCI function number = 0x%02x\n", path->function & 0xff); 124 path++; 125 } 126} 127 128static void 129print_dscope(acpi_dmar_remap_hdr_t* head, acpi_dmar_dscope_t* dscope) 130{ 131 while (dscope != NULL) { 132 printf("\t<<Device Scope>>\n\t"); 133 switch (dscope->type) { 134 case ACPI_DSCOPE_PCI_ENDPOINT: 135 printf("PCI Endpoint Device\n"); 136 break; 137 case ACPI_DSCOPE_PCI_BRIDGE: 138 printf("PCI Sub-heirarchy\n"); 139 break; 140 case ACPI_DSCOPE_IOAPIC: 141 printf("IOAPIC 0x%02x\n", dscope->enum_id & 0xff); 142 break; 143 case ACPI_DSCOPE_HPET: 144 printf("HPET timer 0x%02d\n", dscope->enum_id & 0xff); 145 break; 146 default: 147 printf("Unknown device scope\n"); 148 acpi_print_table_raw(dscope, dscope->length); 149 } 150 151 if (ACPI_DSCOPE_VALID(dscope->type)) { 152 printf("\tStart bus number 0x%02x\n", 153 dscope->start_bus_number & 0xff); 154 } 155 156 print_path(dscope); 157 158 dscope = acpi_dmar_next_dscope(head, dscope); 159 } 160} 161 162static void 163print_dmar(acpi_dmar_hdr_t* dmar) 164{ 165 acpi_print_table_raw(dmar, dmar->header.length); 166 167 acpi_dmar_remap_hdr_t* sub = acpi_dmar_first_remap(dmar); 168 while (sub != NULL) { 169 switch (sub->type) { 170 case ACPI_DMAR_DRHD_TYPE: 171 printf("\n<DMA Remapping Hardware Unit Definition>\n"); 172 acpi_dmar_drhd_t* drhd = (acpi_dmar_drhd_t*)sub; 173 printf("Flags 0x%02x\n", drhd->flags & 0xff); 174 printf("Segment number 0x%04x\n", 175 drhd->segment_number & 0xffff); 176 printf("Base address 0x%016lx\n", 177 (unsigned long)drhd->register_address); 178// acpi_print_table_raw(drhd, drhd->header.length, ""); 179 print_dscope(sub, acpi_dmar_drhd_first_dscope(drhd)); 180 break; 181 case ACPI_DMAR_RMRR_TYPE: 182 printf("\n<Reserved Memory Region Reporting>\n"); 183 acpi_dmar_rmrr_t* rmrr = (acpi_dmar_rmrr_t*)sub; 184 printf("Segment number 0x%04x\n", 185 rmrr->segment_number & 0xffff); 186 printf("Memory range 0x%016lx -> 0x%016lx\n", 187 (unsigned long)rmrr->base_address, 188 (unsigned long)rmrr->limit_address); 189// acpi_print_table_raw(rmrr, rmrr->header.length, ""); 190 print_dscope(sub, acpi_dmar_rmrr_first_dscope(rmrr)); 191 break; 192 case ACPI_DMAR_ATSR_TYPE: 193 printf("\n<root port ATS capbility Reporting>\n"); 194 acpi_dmar_atsr_t* atsr = (acpi_dmar_atsr_t*)sub; 195 printf("Flags 0x%02x\n", atsr->flags & 0xff); 196 printf("Segment number 0x%04x\n", 197 atsr->segment_number & 0xffff); 198// acpi_print_table_raw(atsr, atsr->header.length, ""); 199 print_dscope(sub, acpi_dmar_atsr_first_dscope(atsr)); 200 break; 201 case ACPI_DMAR_RHSA_TYPE: 202 printf("\n<Remapping Hardware Affinity>\n"); 203 acpi_dmar_rhsa_t* rhsa = (acpi_dmar_rhsa_t*)sub; 204 printf("Base address 0x%016lx\n", 205 (unsigned long)rhsa->base_address); 206 printf("Proximity domain 0x%08x\n", 207 rhsa->proximity_domain); 208// acpi_print_table_raw(rhsa, sizeof(*rhsa), ""); 209 break; 210 default: 211 printf("\n<Unknown remapping structure>\n"); 212 acpi_print_table_raw(sub, sizeof(*sub)); 213 break; 214 } 215 sub = acpi_dmar_next_remap(dmar, sub); 216 } 217} 218 219static void 220print_mcfg_desc(acpi_mcfg_desc_t* mcfg_desc) 221{ 222 printf("<PCI Device Description %p>\n", mcfg_desc); 223 printf("Address: 0x%016lx\n", (unsigned long)mcfg_desc->address); 224 printf("Segment 0x%04x\n", mcfg_desc->segment); 225 printf("Bus 0x%02x - 0x%02x\n", mcfg_desc->bus_end, 226 mcfg_desc->bus_start); 227} 228 229static void 230print_mcfg(acpi_mcfg_t* mcfg) 231{ 232 acpi_print_table_raw(mcfg, mcfg->header.length); 233 acpi_mcfg_desc_t* cur = acpi_mcfg_desc_first(mcfg); 234 while (cur != NULL) { 235 print_mcfg_desc(cur); 236 cur = acpi_mcfg_desc_next(mcfg, cur); 237 } 238} 239 240static void 241print_rsdt(acpi_rsdt_t* rsdt) 242{ 243 acpi_print_table_raw(rsdt, rsdt->header.length); 244 printf("Child tables:\n"); 245 uint32_t* next = acpi_rsdt_first(rsdt); 246 int entries = acpi_rsdt_entry_count(rsdt); 247 int i = 0; 248 while (next != NULL) { 249 printf("%d/%d -> %p\n", i++, entries, (void*)*next); 250 next = acpi_rsdt_next(rsdt, next); 251 } 252 printf("\n"); 253} 254 255static void 256print_xsdt(acpi_xsdt_t* xsdt) 257{ 258 acpi_print_table_raw(xsdt, xsdt->header.length); 259 printf("Child tables:\n"); 260 uint64_t* next = acpi_xsdt_first(xsdt); 261 int entries = acpi_xsdt_entry_count(xsdt); 262 int i = 0; 263 while (next != NULL) { 264 printf("%d/%d -> %p\n", i++, entries, 265 (void*)(uintptr_t)*next); 266 next = acpi_xsdt_next(xsdt, next); 267 } 268 printf("\n"); 269} 270 271static void 272print_rsdp(acpi_rsdp_t* rsdp) 273{ 274 acpi_print_table_raw(rsdp, rsdp->length); 275 printf("RSDT->%p\n", (void*)rsdp->rsdt_address); 276 printf("XSDT->%p\n", (void*)(uintptr_t)rsdp->xsdt_address); 277 printf("\n"); 278} 279 280static void 281print_madt(acpi_madt_t* madt) 282{ 283 acpi_print_table_raw(madt, madt->header.length); 284 acpi_madt_ics_hdr_t* entry = acpi_madt_first_ics(madt); 285 while (entry != NULL) { 286 char* txt; 287 switch (entry->type) { 288 case ACPI_APIC_LOCAL: 289 txt = "LOCAL"; 290 break; 291 case ACPI_APIC_ISO: 292 txt = "ISO"; 293 break; 294 case ACPI_APIC_NMI: 295 txt = "NMI"; 296 break; 297 case ACPI_APIC_LOCAL_NMI: 298 txt = "LOCAL NMI"; 299 break; 300 case ACPI_APIC_LOCAL_AO: 301 txt = "LOCAL AO"; 302 break; 303 case ACPI_APIC_SAPIC: 304 txt = "SAPIC"; 305 break; 306 case ACPI_APIC_PINT_SRC: 307 txt = "PINT SRC"; 308 break; 309 case ACPI_APIC_LOCAL_X2APIC: 310 txt = "LOCAL X2APIC"; 311 break; 312 case ACPI_APIC_LOCAL_X2APIC_NMI: 313 txt = "LOCAL X2APIC_NMI"; 314 break; 315 case ACPI_APIC_GIC: 316 txt = "GIC"; 317 break; 318 case ACPI_APIC_GICD: 319 txt = "GICD"; 320 break; 321 case ACPI_APIC_IOSAPIC: 322 txt = "IOSAPIC"; 323 break; 324 case ACPI_APIC_IOAPIC: 325 txt = "IOAPIC"; 326 break; 327 default: 328 txt = "Unknown"; 329 break; 330 } 331 printf("<<%s>>\n", txt); 332 acpi_print_table_raw(entry, entry->length); 333 entry = acpi_madt_next_ics(madt, entry); 334 } 335} 336 337void 338acpi_print_table(const void* start) 339{ 340 // for now, just find the length of the table and print 341 // in raw format 342 int len = acpi_table_length(start); 343 if (len > 0) { 344 if (ACPI_TABLE_TEST(start, DMAR)) { 345 print_dmar((acpi_dmar_hdr_t*)start); 346 } else if (ACPI_TABLE_TEST(start, MCFG)) { 347 print_mcfg((acpi_mcfg_t*)start); 348 } else if (ACPI_TABLE_TEST(start, RSDT)) { 349 print_rsdt((acpi_rsdt_t*)start); 350 } else if (ACPI_TABLE_TEST(start, XSDT)) { 351 print_xsdt((acpi_xsdt_t*)start); 352 } else if (ACPI_TABLE_TEST(start, RSDP)) { 353 print_rsdp((acpi_rsdp_t*)start); 354 } else if (ACPI_TABLE_TEST(start, MADT)) { 355 print_madt((acpi_madt_t*)start); 356 } else { 357 acpi_print_table_raw(start, len); 358 } 359 } 360} 361 362void 363acpi_print_regions(const RegionList_t* rl) 364{ 365 printf("\n"); 366 printf("index | Signiture | Address | " 367 "Adjusted address | parent index\n"); 368 int i; 369 for (i = 0; i < 83; i++) { 370 printf("-"); 371 } 372 printf("\n"); 373 374 for (i = 0; i < rl->region_count; i++) { 375 const Region_t* r = rl->regions + i; 376 const char* sig = acpi_sig_str(r->type); 377 int sig_len = strlen(sig); 378 printf(" %2d | ", i); 379 printf("\"%s\"", acpi_sig_str(r->type)); 380 while (sig_len++ < 9) { 381 printf(" "); 382 } 383 printf("| "); 384 385 printf("%p->%p | ", r->start, r->start + r->size); 386 printf("%p->", r->start - rl->offset); 387 printf("%p | ", r->start + r->size - rl->offset); 388 printf("%3d\n", r->parent); 389 } 390} 391 392#endif 393