3 * ACPI BIOS interface test program.
4 * (C) 2011-2012 Jonathan Campbell.
5 * Hackipedia DOS library.
7 * This code is licensed under the LGPL.
8 * <insert LGPL legal text here>
10 * Compiles for intended target environments:
11 * - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
15 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
26 #include <hw/dos/dos.h>
27 #include <hw/cpu/cpu.h>
28 #include <hw/acpi/acpi.h>
29 #include <hw/8254/8254.h> /* 8254 timer */
30 #include <hw/8259/8259.h> /* 8259 PIC */
31 #include <hw/flatreal/flatreal.h>
32 #include <hw/dos/doswin.h>
35 fprintf(stderr,"Test [options]\n");
36 fprintf(stderr," /32 Use 32-bit RSDT\n");
39 int main(int argc,char **argv) {
40 struct acpi_rsdt_header sdth;
43 uint32_t tmp32,tmplen;
46 for (i=1;i < (unsigned long)argc;) {
47 const char *a = argv[(unsigned int)(i++)];
49 if (*a == '-' || *a == '/') {
50 do { a++; } while (*a == '-' || *a == '/');
52 if (!strcmp(a,"?") || !strcmp(a,"h") || !strcmp(a,"help")) {
56 else if (!strcmp(a,"32")) {
60 fprintf(stderr,"Unknown switch '%s'\n",a);
66 fprintf(stderr,"Unknown arg '%s'\n",a);
73 printf("Cannot init 8254 timer\n");
77 printf("Cannot init 8259 PIC\n");
83 #if TARGET_MSDOS == 32
88 #if TARGET_MSDOS == 16
89 if (!flatrealmode_setup(FLATREALMODE_4GB)) {
90 printf("Unable to set up flat real mode (needed for 16-bit builds)\n");
91 printf("Most ACPI functions require access to the full 4GB range.\n");
97 printf("ACPI BIOS not found\n");
100 assert(acpi_rsdp != NULL);
101 printf("ACPI %u.0 structure at 0x%05lX\n",acpi_rsdp->revision+1,(unsigned long)acpi_rsdp_location);
103 memcpy(tmp,(char*)(&(acpi_rsdp->OEM_id)),6); tmp[6]=0;
104 printf("ACPI OEM ID '%s', RSDT address (32-bit) 0x%08lX Length %lu\n",tmp,
105 (unsigned long)(acpi_rsdp->rsdt_address),
106 (unsigned long)(acpi_rsdp->length));
107 if (acpi_rsdp->revision != 0)
108 printf(" XSDT address (64-bit) 0x%016llX\n",
109 (unsigned long long)(acpi_rsdp->xsdt_address));
111 printf("Chosen RSDT/XSDT at 0x%08llX\n",(unsigned long long)acpi_rsdt_location);
113 if (acpi_rsdt != NULL) {
114 memcpy(tmp,(void*)(acpi_rsdt->signature),4); tmp[4] = 0;
115 printf(" '%s': len=%lu rev=%u\n",tmp,(unsigned long)acpi_rsdt->length,
116 acpi_rsdt->revision);
118 memcpy(tmp,(void*)(acpi_rsdt->OEM_id),6); tmp[6] = 0;
119 printf(" OEM id: '%s'\n",tmp);
121 memcpy(tmp,(void*)(acpi_rsdt->OEM_table_id),8); tmp[8] = 0;
122 printf(" OEM table id: '%s' rev %lu\n",tmp,
123 (unsigned long)acpi_rsdt->OEM_revision);
125 memcpy(tmp,(void*)(&(acpi_rsdt->creator_id)),4); tmp[4] = 0;
126 printf(" Creator: '%s' rev %lu\n",tmp,
127 (unsigned long)acpi_rsdt->creator_revision);
130 max = acpi_rsdt_entries();
131 if (acpi_rsdt_is_xsdt()) {
132 printf("Showing XSDT, %lu entries\n",max);
135 printf("Showing RSDT, %lu entries\n",max);
138 for (i=0;i < max;i++) {
139 addr = acpi_rsdt_entry(i);
140 printf(" [%lu] 0x%08llX ",i,(unsigned long long)addr);
142 tmp32 = acpi_mem_readd(addr);
145 memcpy(tmp,&tmp32,4); tmp[4] = 0;
146 if (acpi_probe_rsdt_check(addr,tmp32,&tmplen)) {
147 acpi_memcpy_from_phys(&sdth,addr,sizeof(struct acpi_rsdt_header));
149 printf("'%s' len=0x%lX rev=%u ",tmp,(unsigned long)tmplen,sdth.revision);
151 memcpy(tmp,&sdth.OEM_id,6); tmp[6] = 0;
152 printf("OEM id: '%s'\n",tmp);
154 memcpy(tmp,&sdth.OEM_table_id,8); tmp[8] = 0;
155 printf("OEM table id: '%s' rev %u ",tmp,sdth.OEM_revision);
157 memcpy(tmp,&sdth.creator_id,4); tmp[4] = 0;
158 printf("Creator id: '%s' rev %u",tmp,sdth.creator_revision);
160 if (!memcmp(sdth.signature,"MCFG",4)) {
161 struct acpi_mcfg_entry entry;
162 uint64_t o = addr + 44;
165 printf("\nPCI Express map:");
166 assert(sizeof(struct acpi_mcfg_entry) == 16);
167 count = (unsigned int)(tmplen / sizeof(struct acpi_mcfg_entry));
169 acpi_memcpy_from_phys(&entry,o,sizeof(struct acpi_mcfg_entry));
170 o += sizeof(struct acpi_mcfg_entry);
172 /* Some bioses I test against seem to return enough for 3 but fill in only 1? */
173 if (entry.base_address != 0ULL || entry.start_pci_bus_number != 0 || entry.end_pci_bus_number != 0) {
176 if (entry.start_pci_bus_number > entry.end_pci_bus_number)
177 entry.start_pci_bus_number = entry.end_pci_bus_number;
179 sz = (((unsigned long long)(entry.end_pci_bus_number - entry.start_pci_bus_number)) + 1ULL) << 20ULL;
180 printf("\n @0x%08llX-0x%08llX seg=%u bus=%u-%u",
181 (unsigned long long)entry.base_address,
182 (unsigned long long)(entry.base_address + sz - 1ULL),
183 (unsigned int)entry.pci_segment_group_number,
184 (unsigned int)entry.start_pci_bus_number,
185 (unsigned int)entry.end_pci_bus_number);
193 printf("'%s' check failed",tmp);