• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /////////////////////////////////////////////////////////////////////////
2 // $Id$
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  32 bit Bochs BIOS init code
6 //  Copyright (C) 2006 Fabrice Bellard
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 //  You should have received a copy of the GNU Lesser General Public
19 //  License along with this library; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
21 #include <stdarg.h>
22 #include <stddef.h>
23 
24 #include "rombios.h"
25 
26 typedef signed char  int8_t;
27 typedef short int16_t;
28 typedef int   int32_t;
29 typedef long long int64_t;
30 typedef unsigned char  uint8_t;
31 typedef unsigned short uint16_t;
32 typedef unsigned int   uint32_t;
33 typedef unsigned long long uint64_t;
34 
35 /* if true, put the MP float table and ACPI RSDT in EBDA and the MP
36    table in RAM. Unfortunately, Linux has bugs with that, so we prefer
37    to modify the BIOS in shadow RAM */
38 //#define BX_USE_EBDA_TABLES
39 
40 /* define it if the (emulated) hardware supports SMM mode */
41 #define BX_USE_SMM
42 
43 #define cpuid(index, eax, ebx, ecx, edx) \
44   asm volatile ("cpuid" \
45                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
46                 : "0" (index))
47 
48 #define wbinvd() asm volatile("wbinvd")
49 
50 #define CPUID_MSR (1 << 5)
51 #define CPUID_APIC (1 << 9)
52 #define CPUID_MTRR (1 << 12)
53 
54 #define APIC_BASE    ((uint8_t *)0xfee00000)
55 #define APIC_ICR_LOW 0x300
56 #define APIC_SVR     0x0F0
57 #define APIC_ID      0x020
58 #define APIC_LVT3    0x370
59 
60 #define APIC_ENABLED 0x0100
61 
62 #define AP_BOOT_ADDR 0x9f000
63 
64 #define MPTABLE_MAX_SIZE  0x00002000
65 #define SMI_CMD_IO_ADDR   0xb2
66 
67 #define BIOS_TMP_STORAGE  0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */
68 
69 #define MSR_MTRRcap                     0x000000fe
70 #define MSR_MTRRfix64K_00000            0x00000250
71 #define MSR_MTRRfix16K_80000            0x00000258
72 #define MSR_MTRRfix16K_A0000            0x00000259
73 #define MSR_MTRRfix4K_C0000             0x00000268
74 #define MSR_MTRRfix4K_C8000             0x00000269
75 #define MSR_MTRRfix4K_D0000             0x0000026a
76 #define MSR_MTRRfix4K_D8000             0x0000026b
77 #define MSR_MTRRfix4K_E0000             0x0000026c
78 #define MSR_MTRRfix4K_E8000             0x0000026d
79 #define MSR_MTRRfix4K_F0000             0x0000026e
80 #define MSR_MTRRfix4K_F8000             0x0000026f
81 #define MSR_MTRRdefType                 0x000002ff
82 
83 #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
84 #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
85 
outl(int addr,int val)86 static inline void outl(int addr, int val)
87 {
88     asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val));
89 }
90 
outw(int addr,int val)91 static inline void outw(int addr, int val)
92 {
93     asm volatile ("outw %w1, %w0" : : "d" (addr), "a" (val));
94 }
95 
outb(int addr,int val)96 static inline void outb(int addr, int val)
97 {
98     asm volatile ("outb %b1, %w0" : : "d" (addr), "a" (val));
99 }
100 
inl(int addr)101 static inline uint32_t inl(int addr)
102 {
103     uint32_t val;
104     asm volatile ("inl %w1, %0" : "=a" (val) : "d" (addr));
105     return val;
106 }
107 
inw(int addr)108 static inline uint16_t inw(int addr)
109 {
110     uint16_t val;
111     asm volatile ("inw %w1, %w0" : "=a" (val) : "d" (addr));
112     return val;
113 }
114 
inb(int addr)115 static inline uint8_t inb(int addr)
116 {
117     uint8_t val;
118     asm volatile ("inb %w1, %b0" : "=a" (val) : "d" (addr));
119     return val;
120 }
121 
writel(void * addr,uint32_t val)122 static inline void writel(void *addr, uint32_t val)
123 {
124     *(volatile uint32_t *)addr = val;
125 }
126 
writew(void * addr,uint16_t val)127 static inline void writew(void *addr, uint16_t val)
128 {
129     *(volatile uint16_t *)addr = val;
130 }
131 
writeb(void * addr,uint8_t val)132 static inline void writeb(void *addr, uint8_t val)
133 {
134     *(volatile uint8_t *)addr = val;
135 }
136 
readl(const void * addr)137 static inline uint32_t readl(const void *addr)
138 {
139     return *(volatile const uint32_t *)addr;
140 }
141 
readw(const void * addr)142 static inline uint16_t readw(const void *addr)
143 {
144     return *(volatile const uint16_t *)addr;
145 }
146 
readb(const void * addr)147 static inline uint8_t readb(const void *addr)
148 {
149     return *(volatile const uint8_t *)addr;
150 }
151 
putc(int c)152 static inline void putc(int c)
153 {
154     outb(INFO_PORT, c);
155 }
156 
rdmsr(unsigned index)157 static uint64_t rdmsr(unsigned index)
158 {
159     unsigned long long ret;
160 
161     asm ("rdmsr" : "=A"(ret) : "c"(index));
162     return ret;
163 }
164 
wrmsr(unsigned index,uint64_t val)165 static void wrmsr(unsigned index, uint64_t val)
166 {
167     asm volatile ("wrmsr" : : "c"(index), "A"(val));
168 }
169 
isdigit(int c)170 static inline int isdigit(int c)
171 {
172     return c >= '0' && c <= '9';
173 }
174 
memset(void * d1,int val,size_t len)175 void *memset(void *d1, int val, size_t len)
176 {
177     uint8_t *d = d1;
178 
179     while (len--) {
180         *d++ = val;
181     }
182     return d1;
183 }
184 
memcpy(void * d1,const void * s1,size_t len)185 void *memcpy(void *d1, const void *s1, size_t len)
186 {
187     uint8_t *d = d1;
188     const uint8_t *s = s1;
189 
190     while (len--) {
191         *d++ = *s++;
192     }
193     return d1;
194 }
195 
memmove(void * d1,const void * s1,size_t len)196 void *memmove(void *d1, const void *s1, size_t len)
197 {
198     uint8_t *d = d1;
199     const uint8_t *s = s1;
200 
201     if (d <= s) {
202         while (len--) {
203             *d++ = *s++;
204         }
205     } else {
206         d += len;
207         s += len;
208         while (len--) {
209             *--d = *--s;
210         }
211     }
212     return d1;
213 }
214 
memcmp(const void * s1,const void * s2,size_t len)215 int memcmp(const void *s1, const void *s2, size_t len)
216 {
217     const int8_t *p1 = s1;
218     const int8_t *p2 = s2;
219 
220     while (len--) {
221         int r = *p1++ - *p2++;
222         if(r)
223             return r;
224     }
225 
226     return 0;
227 }
228 
strlen(const char * s)229 size_t strlen(const char *s)
230 {
231     const char *s1;
232     for(s1 = s; *s1 != '\0'; s1++);
233     return s1 - s;
234 }
235 
236 /* from BSD ppp sources */
vsnprintf(char * buf,int buflen,const char * fmt,va_list args)237 int vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
238 {
239     int c, i, n;
240     int width, prec, fillch;
241     int base, len, neg;
242     unsigned long val = 0;
243     const char *f;
244     char *str, *buf0;
245     char num[32];
246     static const char hexchars[] = "0123456789abcdef";
247 
248     buf0 = buf;
249     --buflen;
250     while (buflen > 0) {
251 	for (f = fmt; *f != '%' && *f != 0; ++f)
252 	    ;
253 	if (f > fmt) {
254 	    len = f - fmt;
255 	    if (len > buflen)
256 		len = buflen;
257 	    memcpy(buf, fmt, len);
258 	    buf += len;
259 	    buflen -= len;
260 	    fmt = f;
261 	}
262 	if (*fmt == 0)
263 	    break;
264 	c = *++fmt;
265 	width = prec = 0;
266 	fillch = ' ';
267 	if (c == '0') {
268 	    fillch = '0';
269 	    c = *++fmt;
270 	}
271 	if (c == '*') {
272 	    width = va_arg(args, int);
273 	    c = *++fmt;
274 	} else {
275 	    while (isdigit(c)) {
276 		width = width * 10 + c - '0';
277 		c = *++fmt;
278 	    }
279 	}
280 	if (c == '.') {
281 	    c = *++fmt;
282 	    if (c == '*') {
283 		prec = va_arg(args, int);
284 		c = *++fmt;
285 	    } else {
286 		while (isdigit(c)) {
287 		    prec = prec * 10 + c - '0';
288 		    c = *++fmt;
289 		}
290 	    }
291 	}
292         /* modifiers */
293         switch(c) {
294         case 'l':
295             c = *++fmt;
296             break;
297         default:
298             break;
299         }
300         str = 0;
301 	base = 0;
302 	neg = 0;
303 	++fmt;
304 	switch (c) {
305 	case 'd':
306 	    i = va_arg(args, int);
307 	    if (i < 0) {
308 		neg = 1;
309 		val = -i;
310 	    } else
311 		val = i;
312 	    base = 10;
313 	    break;
314 	case 'o':
315 	    val = va_arg(args, unsigned int);
316 	    base = 8;
317 	    break;
318 	case 'x':
319 	case 'X':
320 	    val = va_arg(args, unsigned int);
321 	    base = 16;
322 	    break;
323 	case 'p':
324 	    val = (unsigned long) va_arg(args, void *);
325 	    base = 16;
326 	    neg = 2;
327 	    break;
328 	case 's':
329 	    str = va_arg(args, char *);
330 	    break;
331 	case 'c':
332 	    num[0] = va_arg(args, int);
333 	    num[1] = 0;
334 	    str = num;
335 	    break;
336 	default:
337 	    *buf++ = '%';
338 	    if (c != '%')
339 		--fmt;		/* so %z outputs %z etc. */
340 	    --buflen;
341 	    continue;
342 	}
343 	if (base != 0) {
344 	    str = num + sizeof(num);
345 	    *--str = 0;
346 	    while (str > num + neg) {
347 		*--str = hexchars[val % base];
348 		val = val / base;
349 		if (--prec <= 0 && val == 0)
350 		    break;
351 	    }
352 	    switch (neg) {
353 	    case 1:
354 		*--str = '-';
355 		break;
356 	    case 2:
357 		*--str = 'x';
358 		*--str = '0';
359 		break;
360 	    }
361 	    len = num + sizeof(num) - 1 - str;
362 	} else {
363 	    len = strlen(str);
364 	    if (prec > 0 && len > prec)
365 		len = prec;
366 	}
367 	if (width > 0) {
368 	    if (width > buflen)
369 		width = buflen;
370 	    if ((n = width - len) > 0) {
371 		buflen -= n;
372 		for (; n > 0; --n)
373 		    *buf++ = fillch;
374 	    }
375 	}
376 	if (len > buflen)
377 	    len = buflen;
378 	memcpy(buf, str, len);
379 	buf += len;
380 	buflen -= len;
381     }
382     *buf = 0;
383     return buf - buf0;
384 }
385 
snprintf(char * buf,size_t size,const char * fmt,...)386 int snprintf(char * buf, size_t size, const char *fmt, ...)
387 {
388 	va_list args;
389 	int i;
390 
391 	va_start(args, fmt);
392 	i=vsnprintf(buf,size,fmt,args);
393 	va_end(args);
394 	return i;
395 }
396 
bios_printf(int flags,const char * fmt,...)397 void bios_printf(int flags, const char *fmt, ...)
398 {
399     va_list ap;
400     char buf[1024];
401     const char *s;
402 
403     if ((flags & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT)
404         outb(PANIC_PORT2, 0x00);
405 
406     va_start(ap, fmt);
407     vsnprintf(buf, sizeof(buf), fmt, ap);
408     s = buf;
409     while (*s)
410         putc(*s++);
411     va_end(ap);
412 }
413 
delay_ms(int n)414 void delay_ms(int n)
415 {
416     int i, j;
417     for(i = 0; i < n; i++) {
418 #ifdef BX_QEMU
419         /* approximative ! */
420         for(j = 0; j < 1000000; j++);
421 #else
422         {
423           int r1, r2;
424           j = 66;
425           r1 = inb(0x61) & 0x10;
426           do {
427             r2 = inb(0x61) & 0x10;
428             if (r1 != r2) {
429               j--;
430               r1 = r2;
431             }
432           } while (j > 0);
433         }
434 #endif
435     }
436 }
437 
438 uint16_t smp_cpus;
439 uint32_t cpuid_signature;
440 uint32_t cpuid_features;
441 uint32_t cpuid_ext_features;
442 unsigned long ram_size;
443 uint64_t ram_end;
444 #ifdef BX_USE_EBDA_TABLES
445 unsigned long ebda_cur_addr;
446 #endif
447 int acpi_enabled;
448 uint32_t pm_io_base, smb_io_base;
449 int pm_sci_int;
450 unsigned long bios_table_cur_addr;
451 unsigned long bios_table_end_addr;
452 
le64_to_cpu(uint64_t x)453 static inline uint64_t le64_to_cpu(uint64_t x)
454 {
455     return x;
456 }
457 
wrmsr_smp(uint32_t index,uint64_t val)458 void wrmsr_smp(uint32_t index, uint64_t val)
459 {
460     static struct { uint32_t ecx, eax, edx; } *p = (void *)SMP_MSR_ADDR;
461 
462     wrmsr(index, val);
463     p->ecx = index;
464     p->eax = val;
465     p->edx = val >> 32;
466     ++p;
467     p->ecx = 0;
468 }
469 
470 #ifdef BX_QEMU
471 #define QEMU_CFG_CTL_PORT 0x510
472 #define QEMU_CFG_DATA_PORT 0x511
473 #define QEMU_CFG_SIGNATURE  0x00
474 #define QEMU_CFG_ID         0x01
475 #define QEMU_CFG_UUID       0x02
476 #define QEMU_CFG_NUMA       0x0D
477 #define QEMU_CFG_ARCH_LOCAL     0x8000
478 #define QEMU_CFG_ACPI_TABLES  (QEMU_CFG_ARCH_LOCAL + 0)
479 #define QEMU_CFG_SMBIOS_ENTRIES  (QEMU_CFG_ARCH_LOCAL + 1)
480 
481 int qemu_cfg_port;
482 
qemu_cfg_select(int f)483 void qemu_cfg_select(int f)
484 {
485     outw(QEMU_CFG_CTL_PORT, f);
486 }
487 
qemu_cfg_port_probe()488 int qemu_cfg_port_probe()
489 {
490     char *sig = "QEMU";
491     int i;
492 
493     qemu_cfg_select(QEMU_CFG_SIGNATURE);
494 
495     for (i = 0; i < 4; i++)
496         if (inb(QEMU_CFG_DATA_PORT) != sig[i])
497             return 0;
498 
499     return 1;
500 }
501 
qemu_cfg_read(uint8_t * buf,int len)502 void qemu_cfg_read(uint8_t *buf, int len)
503 {
504     while (len--)
505         *(buf++) = inb(QEMU_CFG_DATA_PORT);
506 }
507 
acpi_additional_tables(void)508 static uint16_t acpi_additional_tables(void)
509 {
510     uint16_t cnt;
511 
512     qemu_cfg_select(QEMU_CFG_ACPI_TABLES);
513     qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt));
514 
515     return cnt;
516 }
517 
acpi_load_table(int i,uint32_t addr,uint16_t * len)518 static int acpi_load_table(int i, uint32_t addr, uint16_t *len)
519 {
520     qemu_cfg_read((uint8_t*)len, sizeof(*len));
521 
522     if (!*len)
523         return -1;
524 
525     qemu_cfg_read((uint8_t*)addr, *len);
526     return 0;
527 }
528 
smbios_entries(void)529 static uint16_t smbios_entries(void)
530 {
531     uint16_t cnt;
532 
533     qemu_cfg_select(QEMU_CFG_SMBIOS_ENTRIES);
534     qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt));
535 
536     return cnt;
537 }
538 
qemu_cfg_get64(void)539 uint64_t qemu_cfg_get64 (void)
540 {
541     uint64_t ret;
542 
543     qemu_cfg_read((uint8_t*)&ret, 8);
544     return le64_to_cpu(ret);
545 }
546 #endif
547 
cpu_probe(void)548 void cpu_probe(void)
549 {
550     uint32_t eax, ebx, ecx, edx;
551     cpuid(1, eax, ebx, ecx, edx);
552     cpuid_signature = eax;
553     cpuid_features = edx;
554     cpuid_ext_features = ecx;
555 }
556 
cmos_readb(int addr)557 static int cmos_readb(int addr)
558 {
559     outb(0x70, addr);
560     return inb(0x71);
561 }
562 
setup_mtrr(void)563 void setup_mtrr(void)
564 {
565     int i, vcnt, fix, wc;
566     uint32_t mtrr_cap;
567     union {
568         uint8_t valb[8];
569         uint64_t val;
570     } u;
571 
572     *(uint32_t *)SMP_MSR_ADDR = 0;
573 
574     if (!(cpuid_features & CPUID_MTRR))
575         return;
576 
577     if (!(cpuid_features & CPUID_MSR))
578         return;
579 
580     mtrr_cap = rdmsr(MSR_MTRRcap);
581     vcnt = mtrr_cap & 0xff;
582     fix = mtrr_cap & 0x100;
583     wc = mtrr_cap & 0x400;
584     if (!vcnt || !fix)
585         return;
586 
587     u.val = 0;
588     for (i = 0; i < 8; ++i)
589         if (ram_size >= 65536 * (i + 1))
590             u.valb[i] = 6;
591     wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
592     u.val = 0;
593     for (i = 0; i < 8; ++i)
594         if (ram_size >= 65536 * 8 + 16384 * (i + 1))
595             u.valb[i] = 6;
596     wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
597     wrmsr_smp(MSR_MTRRfix16K_A0000, 0);
598     wrmsr_smp(MSR_MTRRfix4K_C0000, 0);
599     wrmsr_smp(MSR_MTRRfix4K_C8000, 0);
600     wrmsr_smp(MSR_MTRRfix4K_D0000, 0);
601     wrmsr_smp(MSR_MTRRfix4K_D8000, 0);
602     wrmsr_smp(MSR_MTRRfix4K_E0000, 0);
603     wrmsr_smp(MSR_MTRRfix4K_E8000, 0);
604     wrmsr_smp(MSR_MTRRfix4K_F0000, 0);
605     wrmsr_smp(MSR_MTRRfix4K_F8000, 0);
606     /* Mark 3.5-4GB as UC, anything not specified defaults to WB */
607     wrmsr_smp(MTRRphysBase_MSR(0), 0xe0000000ull | 0);
608     wrmsr_smp(MTRRphysMask_MSR(0), ~(0x20000000ull - 1) | 0x800);
609     wrmsr_smp(MSR_MTRRdefType, 0xc06);
610 }
611 
ram_probe(void)612 void ram_probe(void)
613 {
614   if (cmos_readb(0x34) | cmos_readb(0x35))
615     ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 +
616         16 * 1024 * 1024;
617   else
618     ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 +
619         1 * 1024 * 1024;
620   BX_INFO("ram_size=0x%08lx\n", ram_size);
621   if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d))
622     ram_end = (((uint64_t)cmos_readb(0x5b) << 16) |
623                ((uint64_t)cmos_readb(0x5c) << 24) |
624                ((uint64_t)cmos_readb(0x5d) << 32)) + (1ull << 32);
625   else
626     ram_end = ram_size;
627   BX_INFO("end of ram=%ldMB\n", ram_end >> 20);
628 #ifdef BX_USE_EBDA_TABLES
629   ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
630   BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
631 #endif
632 }
633 
634 /****************************************************/
635 /* SMP probe */
636 
637 extern uint8_t smp_ap_boot_code_start;
638 extern uint8_t smp_ap_boot_code_end;
639 
640 /* find the number of CPUs by launching a SIPI to them */
smp_probe(void)641 void smp_probe(void)
642 {
643     uint32_t val, sipi_vector;
644 
645     writew(&smp_cpus, 1);
646     if (cpuid_features & CPUID_APIC) {
647 
648         /* enable local APIC */
649         val = readl(APIC_BASE + APIC_SVR);
650         val |= APIC_ENABLED;
651         writel(APIC_BASE + APIC_SVR, val);
652 
653         /* copy AP boot code */
654         memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start,
655                &smp_ap_boot_code_end - &smp_ap_boot_code_start);
656 
657         /* broadcast SIPI */
658         writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500);
659         sipi_vector = AP_BOOT_ADDR >> 12;
660         writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector);
661 
662 #ifndef BX_QEMU
663         delay_ms(10);
664 #else
665         while (cmos_readb(0x5f) + 1 != readw(&smp_cpus))
666             ;
667 #endif
668     }
669     BX_INFO("Found %d cpu(s)\n", readw(&smp_cpus));
670 }
671 
672 /****************************************************/
673 /* PCI init */
674 
675 #define PCI_ADDRESS_SPACE_MEM		0x00
676 #define PCI_ADDRESS_SPACE_IO		0x01
677 #define PCI_ADDRESS_SPACE_MEM_PREFETCH	0x08
678 
679 #define PCI_ROM_SLOT 6
680 #define PCI_NUM_REGIONS 7
681 
682 #define PCI_DEVICES_MAX 64
683 
684 #define PCI_VENDOR_ID		0x00	/* 16 bits */
685 #define PCI_DEVICE_ID		0x02	/* 16 bits */
686 #define PCI_COMMAND		0x04	/* 16 bits */
687 #define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
688 #define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
689 #define PCI_CLASS_DEVICE        0x0a    /* Device class */
690 #define PCI_INTERRUPT_LINE	0x3c	/* 8 bits */
691 #define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */
692 #define PCI_MIN_GNT		0x3e	/* 8 bits */
693 #define PCI_MAX_LAT		0x3f	/* 8 bits */
694 
695 #define PCI_VENDOR_ID_INTEL             0x8086
696 #define PCI_DEVICE_ID_INTEL_82441       0x1237
697 #define PCI_DEVICE_ID_INTEL_82371SB_0   0x7000
698 #define PCI_DEVICE_ID_INTEL_82371SB_1   0x7010
699 #define PCI_DEVICE_ID_INTEL_82371AB_0   0x7110
700 #define PCI_DEVICE_ID_INTEL_82371AB     0x7111
701 #define PCI_DEVICE_ID_INTEL_82371AB_3   0x7113
702 
703 #define PCI_VENDOR_ID_IBM               0x1014
704 #define PCI_VENDOR_ID_APPLE             0x106b
705 
706 typedef struct PCIDevice {
707     int bus;
708     int devfn;
709 } PCIDevice;
710 
711 static uint32_t pci_bios_io_addr;
712 static uint32_t pci_bios_mem_addr;
713 static uint32_t pci_bios_bigmem_addr;
714 /* host irqs corresponding to PCI irqs A-D */
715 static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
716 static PCIDevice i440_pcidev;
717 
pci_config_writel(PCIDevice * d,uint32_t addr,uint32_t val)718 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
719 {
720     outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
721     outl(0xcfc, val);
722 }
723 
pci_config_writew(PCIDevice * d,uint32_t addr,uint32_t val)724 static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
725 {
726     outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
727     outw(0xcfc + (addr & 2), val);
728 }
729 
pci_config_writeb(PCIDevice * d,uint32_t addr,uint32_t val)730 static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
731 {
732     outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
733     outb(0xcfc + (addr & 3), val);
734 }
735 
pci_config_readl(PCIDevice * d,uint32_t addr)736 static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
737 {
738     outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
739     return inl(0xcfc);
740 }
741 
pci_config_readw(PCIDevice * d,uint32_t addr)742 static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
743 {
744     outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
745     return inw(0xcfc + (addr & 2));
746 }
747 
pci_config_readb(PCIDevice * d,uint32_t addr)748 static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
749 {
750     outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
751     return inb(0xcfc + (addr & 3));
752 }
753 
pci_set_io_region_addr(PCIDevice * d,int region_num,uint32_t addr)754 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
755 {
756     uint16_t cmd;
757     uint32_t ofs, old_addr;
758 
759     if ( region_num == PCI_ROM_SLOT ) {
760         ofs = 0x30;
761     }else{
762         ofs = 0x10 + region_num * 4;
763     }
764 
765     old_addr = pci_config_readl(d, ofs);
766 
767     pci_config_writel(d, ofs, addr);
768     BX_INFO("region %d: 0x%08x\n", region_num, addr);
769 
770     /* enable memory mappings */
771     cmd = pci_config_readw(d, PCI_COMMAND);
772     if ( region_num == PCI_ROM_SLOT )
773         cmd |= 2;
774     else if (old_addr & PCI_ADDRESS_SPACE_IO)
775         cmd |= 1;
776     else
777         cmd |= 2;
778     pci_config_writew(d, PCI_COMMAND, cmd);
779 }
780 
781 /* return the global irq number corresponding to a given device irq
782    pin. We could also use the bus number to have a more precise
783    mapping. */
pci_slot_get_pirq(PCIDevice * pci_dev,int irq_num)784 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
785 {
786     int slot_addend;
787     slot_addend = (pci_dev->devfn >> 3) - 1;
788     return (irq_num + slot_addend) & 3;
789 }
790 
find_bios_table_area(void)791 static void find_bios_table_area(void)
792 {
793     unsigned long addr;
794     for(addr = 0xf0000; addr < 0x100000; addr += 16) {
795         if (*(uint32_t *)addr == 0xaafb4442) {
796             bios_table_cur_addr = addr + 8;
797             bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
798             BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
799                     bios_table_cur_addr, bios_table_end_addr);
800             return;
801         }
802     }
803     return;
804 }
805 
bios_shadow_init(PCIDevice * d)806 static void bios_shadow_init(PCIDevice *d)
807 {
808     int v;
809 
810     if (bios_table_cur_addr == 0)
811         return;
812 
813     /* remap the BIOS to shadow RAM an keep it read/write while we
814        are writing tables */
815     v = pci_config_readb(d, 0x59);
816     v &= 0xcf;
817     pci_config_writeb(d, 0x59, v);
818     memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);
819     v |= 0x30;
820     pci_config_writeb(d, 0x59, v);
821     memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);
822 
823     i440_pcidev = *d;
824 }
825 
bios_lock_shadow_ram(void)826 static void bios_lock_shadow_ram(void)
827 {
828     PCIDevice *d = &i440_pcidev;
829     int v;
830 
831     wbinvd();
832     v = pci_config_readb(d, 0x59);
833     v = (v & 0x0f) | (0x10);
834     pci_config_writeb(d, 0x59, v);
835 }
836 
pci_bios_init_bridges(PCIDevice * d)837 static void pci_bios_init_bridges(PCIDevice *d)
838 {
839     uint16_t vendor_id, device_id;
840 
841     vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
842     device_id = pci_config_readw(d, PCI_DEVICE_ID);
843 
844     if (vendor_id == PCI_VENDOR_ID_INTEL &&
845        (device_id == PCI_DEVICE_ID_INTEL_82371SB_0 ||
846         device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) {
847         int i, irq;
848         uint8_t elcr[2];
849 
850         /* PIIX3/PIIX4 PCI to ISA bridge */
851 
852         elcr[0] = 0x00;
853         elcr[1] = 0x00;
854         for(i = 0; i < 4; i++) {
855             irq = pci_irqs[i];
856             /* set to trigger level */
857             elcr[irq >> 3] |= (1 << (irq & 7));
858             /* activate irq remapping in PIIX */
859             pci_config_writeb(d, 0x60 + i, irq);
860         }
861         outb(0x4d0, elcr[0]);
862         outb(0x4d1, elcr[1]);
863         BX_INFO("PIIX3/PIIX4 init: elcr=%02x %02x\n",
864                 elcr[0], elcr[1]);
865     } else if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441) {
866         /* i440 PCI bridge */
867         bios_shadow_init(d);
868     }
869 }
870 
871 extern uint8_t smm_relocation_start, smm_relocation_end;
872 extern uint8_t smm_code_start, smm_code_end;
873 
874 #ifdef BX_USE_SMM
smm_init(PCIDevice * d)875 static void smm_init(PCIDevice *d)
876 {
877     uint32_t value;
878 
879     /* check if SMM init is already done */
880     value = pci_config_readl(d, 0x58);
881     if ((value & (1 << 25)) == 0) {
882 
883         /* enable the SMM memory window */
884         pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x48);
885 
886         /* save original memory content */
887         memcpy((void *)0xa8000, (void *)0x38000, 0x8000);
888 
889         /* copy the SMM relocation code */
890         memcpy((void *)0x38000, &smm_relocation_start,
891                &smm_relocation_end - &smm_relocation_start);
892 
893         /* enable SMI generation when writing to the APMC register */
894         pci_config_writel(d, 0x58, value | (1 << 25));
895 
896         /* init APM status port */
897         outb(0xb3, 0x01);
898 
899         /* raise an SMI interrupt */
900         outb(0xb2, 0x00);
901 
902         /* wait until SMM code executed */
903         while (inb(0xb3) != 0x00);
904 
905         /* restore original memory content */
906         memcpy((void *)0x38000, (void *)0xa8000, 0x8000);
907 
908         /* copy the SMM code */
909         memcpy((void *)0xa8000, &smm_code_start,
910                &smm_code_end - &smm_code_start);
911         wbinvd();
912 
913         /* close the SMM memory window and enable normal SMM */
914         pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x08);
915     }
916 }
917 #endif
918 
piix4_pm_enable(PCIDevice * d)919 static void piix4_pm_enable(PCIDevice *d)
920 {
921         /* PIIX4 Power Management device (for ACPI) */
922         pci_config_writel(d, 0x40, PM_IO_BASE | 1);
923         pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
924         pci_config_writel(d, 0x90, SMB_IO_BASE | 1);
925         pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
926 #ifdef BX_USE_SMM
927         smm_init(d);
928 #endif
929 }
930 
pci_bios_init_device(PCIDevice * d)931 static void pci_bios_init_device(PCIDevice *d)
932 {
933     int class;
934     uint32_t *paddr;
935     int i, pin, pic_irq, vendor_id, device_id;
936 
937     class = pci_config_readw(d, PCI_CLASS_DEVICE);
938     vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
939     device_id = pci_config_readw(d, PCI_DEVICE_ID);
940     BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x class=0x%04x\n",
941             d->bus, d->devfn, vendor_id, device_id, class);
942     switch(class) {
943     case 0x0101: /* Mass storage controller - IDE interface */
944         if (vendor_id == PCI_VENDOR_ID_INTEL &&
945            (device_id == PCI_DEVICE_ID_INTEL_82371SB_1 ||
946             device_id == PCI_DEVICE_ID_INTEL_82371AB)) {
947             /* PIIX3/PIIX4 IDE */
948             pci_config_writew(d, 0x40, 0x8000); // enable IDE0
949             pci_config_writew(d, 0x42, 0x8000); // enable IDE1
950             goto default_map;
951         } else {
952             /* IDE: we map it as in ISA mode */
953             pci_set_io_region_addr(d, 0, 0x1f0);
954             pci_set_io_region_addr(d, 1, 0x3f4);
955             pci_set_io_region_addr(d, 2, 0x170);
956             pci_set_io_region_addr(d, 3, 0x374);
957         }
958         break;
959     case 0x0300: /* Display controller - VGA compatible controller */
960         if (vendor_id != 0x1234)
961             goto default_map;
962         /* VGA: map frame buffer to default Bochs VBE address */
963         pci_set_io_region_addr(d, 0, 0xE0000000);
964         break;
965     case 0x0800: /* Generic system peripheral - PIC */
966         if (vendor_id == PCI_VENDOR_ID_IBM) {
967             /* IBM */
968             if (device_id == 0x0046 || device_id == 0xFFFF) {
969                 /* MPIC & MPIC2 */
970                 pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
971             }
972         }
973         break;
974     case 0xff00:
975         if (vendor_id == PCI_VENDOR_ID_APPLE &&
976             (device_id == 0x0017 || device_id == 0x0022)) {
977             /* macio bridge */
978             pci_set_io_region_addr(d, 0, 0x80800000);
979         }
980         break;
981     default:
982     default_map:
983         /* default memory mappings */
984         for(i = 0; i < PCI_NUM_REGIONS; i++) {
985             int ofs;
986             uint32_t val, size ;
987 
988             if (i == PCI_ROM_SLOT) {
989                 ofs = 0x30;
990                 pci_config_writel(d, ofs, 0xfffffffe);
991             } else {
992                 ofs = 0x10 + i * 4;
993                 pci_config_writel(d, ofs, 0xffffffff);
994             }
995             val = pci_config_readl(d, ofs);
996             if (val != 0) {
997                 size = (~(val & ~0xf)) + 1;
998                 if (val & PCI_ADDRESS_SPACE_IO)
999                     paddr = &pci_bios_io_addr;
1000                 else if (size >= 0x04000000)
1001                     paddr = &pci_bios_bigmem_addr;
1002                 else
1003                     paddr = &pci_bios_mem_addr;
1004                 *paddr = (*paddr + size - 1) & ~(size - 1);
1005                 pci_set_io_region_addr(d, i, *paddr);
1006                 *paddr += size;
1007             }
1008         }
1009         break;
1010     }
1011 
1012     /* map the interrupt */
1013     pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
1014     if (pin != 0) {
1015         pin = pci_slot_get_pirq(d, pin - 1);
1016         pic_irq = pci_irqs[pin];
1017         pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
1018     }
1019 
1020     if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3) {
1021         /* PIIX4 Power Management device (for ACPI) */
1022         pm_io_base = PM_IO_BASE;
1023         smb_io_base = SMB_IO_BASE;
1024         // acpi sci is hardwired to 9
1025         pci_config_writeb(d, PCI_INTERRUPT_LINE, 9);
1026         pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
1027         piix4_pm_enable(d);
1028         acpi_enabled = 1;
1029     }
1030 }
1031 
pci_for_each_device(void (* init_func)(PCIDevice * d))1032 void pci_for_each_device(void (*init_func)(PCIDevice *d))
1033 {
1034     PCIDevice d1, *d = &d1;
1035     int bus, devfn;
1036     uint16_t vendor_id, device_id;
1037 
1038     for(bus = 0; bus < 1; bus++) {
1039         for(devfn = 0; devfn < 256; devfn++) {
1040             d->bus = bus;
1041             d->devfn = devfn;
1042             vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
1043             device_id = pci_config_readw(d, PCI_DEVICE_ID);
1044             if (vendor_id != 0xffff || device_id != 0xffff) {
1045                 init_func(d);
1046             }
1047         }
1048     }
1049 }
1050 
pci_bios_init(void)1051 void pci_bios_init(void)
1052 {
1053     pci_bios_io_addr = 0xc000;
1054     pci_bios_mem_addr = 0xf0000000;
1055     pci_bios_bigmem_addr = ram_size;
1056     if (pci_bios_bigmem_addr < 0x90000000)
1057         pci_bios_bigmem_addr = 0x90000000;
1058 
1059     pci_for_each_device(pci_bios_init_bridges);
1060 
1061     pci_for_each_device(pci_bios_init_device);
1062 }
1063 
1064 /****************************************************/
1065 /* Multi Processor table init */
1066 
putb(uint8_t ** pp,int val)1067 static void putb(uint8_t **pp, int val)
1068 {
1069     uint8_t *q;
1070     q = *pp;
1071     *q++ = val;
1072     *pp = q;
1073 }
1074 
putstr(uint8_t ** pp,const char * str)1075 static void putstr(uint8_t **pp, const char *str)
1076 {
1077     uint8_t *q;
1078     q = *pp;
1079     while (*str)
1080         *q++ = *str++;
1081     *pp = q;
1082 }
1083 
putle16(uint8_t ** pp,int val)1084 static void putle16(uint8_t **pp, int val)
1085 {
1086     uint8_t *q;
1087     q = *pp;
1088     *q++ = val;
1089     *q++ = val >> 8;
1090     *pp = q;
1091 }
1092 
putle32(uint8_t ** pp,int val)1093 static void putle32(uint8_t **pp, int val)
1094 {
1095     uint8_t *q;
1096     q = *pp;
1097     *q++ = val;
1098     *q++ = val >> 8;
1099     *q++ = val >> 16;
1100     *q++ = val >> 24;
1101     *pp = q;
1102 }
1103 
mpf_checksum(const uint8_t * data,int len)1104 static int mpf_checksum(const uint8_t *data, int len)
1105 {
1106     int sum, i;
1107     sum = 0;
1108     for(i = 0; i < len; i++)
1109         sum += data[i];
1110     return sum & 0xff;
1111 }
1112 
align(unsigned long addr,unsigned long v)1113 static unsigned long align(unsigned long addr, unsigned long v)
1114 {
1115     return (addr + v - 1) & ~(v - 1);
1116 }
1117 
mptable_init(void)1118 static void mptable_init(void)
1119 {
1120     uint8_t *mp_config_table, *q, *float_pointer_struct;
1121     int ioapic_id, i, len;
1122     int mp_config_table_size;
1123 
1124 #ifdef BX_USE_EBDA_TABLES
1125     mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
1126 #else
1127     bios_table_cur_addr = align(bios_table_cur_addr, 16);
1128     mp_config_table = (uint8_t *)bios_table_cur_addr;
1129 #endif
1130     q = mp_config_table;
1131     putstr(&q, "PCMP"); /* "PCMP signature */
1132     putle16(&q, 0); /* table length (patched later) */
1133     putb(&q, 4); /* spec rev */
1134     putb(&q, 0); /* checksum (patched later) */
1135 #ifdef BX_QEMU
1136     putstr(&q, "QEMUCPU "); /* OEM id */
1137 #else
1138     putstr(&q, "BOCHSCPU");
1139 #endif
1140     putstr(&q, "0.1         "); /* vendor id */
1141     putle32(&q, 0); /* OEM table ptr */
1142     putle16(&q, 0); /* OEM table size */
1143     putle16(&q, smp_cpus + 18); /* entry count */
1144     putle32(&q, 0xfee00000); /* local APIC addr */
1145     putle16(&q, 0); /* ext table length */
1146     putb(&q, 0); /* ext table checksum */
1147     putb(&q, 0); /* reserved */
1148 
1149     for(i = 0; i < smp_cpus; i++) {
1150         putb(&q, 0); /* entry type = processor */
1151         putb(&q, i); /* APIC id */
1152         putb(&q, 0x11); /* local APIC version number */
1153         if (i == 0)
1154             putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
1155         else
1156             putb(&q, 1); /* cpu flags: enabled */
1157         putb(&q, 0); /* cpu signature */
1158         putb(&q, 6);
1159         putb(&q, 0);
1160         putb(&q, 0);
1161         putle16(&q, 0x201); /* feature flags */
1162         putle16(&q, 0);
1163 
1164         putle16(&q, 0); /* reserved */
1165         putle16(&q, 0);
1166         putle16(&q, 0);
1167         putle16(&q, 0);
1168     }
1169 
1170     /* isa bus */
1171     putb(&q, 1); /* entry type = bus */
1172     putb(&q, 0); /* bus ID */
1173     putstr(&q, "ISA   ");
1174 
1175     /* ioapic */
1176     ioapic_id = smp_cpus;
1177     putb(&q, 2); /* entry type = I/O APIC */
1178     putb(&q, ioapic_id); /* apic ID */
1179     putb(&q, 0x11); /* I/O APIC version number */
1180     putb(&q, 1); /* enable */
1181     putle32(&q, 0xfec00000); /* I/O APIC addr */
1182 
1183     /* irqs */
1184     for(i = 0; i < 32; i++) {
1185 #ifdef BX_QEMU
1186         /* One entry per ioapic input. Input 2 is covered by
1187            irq0->inti2 override (i == 0). irq 2 is unused */
1188         if (i == 2)
1189             continue;
1190 #endif
1191         putb(&q, 3); /* entry type = I/O interrupt */
1192         putb(&q, 0); /* interrupt type = vectored interrupt */
1193         putb(&q, 0); /* flags: po=0, el=0 */
1194         putb(&q, 0);
1195         putb(&q, 0); /* source bus ID = ISA */
1196         putb(&q, i); /* source bus IRQ */
1197         putb(&q, ioapic_id); /* dest I/O APIC ID */
1198 #ifdef BX_QEMU
1199         putb(&q, i == 0 ? 2 : i); /* dest I/O APIC interrupt in */
1200 #else
1201         putb(&q, i); /* dest I/O APIC interrupt in */
1202 #endif
1203     }
1204     /* patch length */
1205     len = q - mp_config_table;
1206     mp_config_table[4] = len;
1207     mp_config_table[5] = len >> 8;
1208 
1209     mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
1210 
1211     mp_config_table_size = q - mp_config_table;
1212 
1213 #ifndef BX_USE_EBDA_TABLES
1214     bios_table_cur_addr += mp_config_table_size;
1215 #endif
1216 
1217     /* floating pointer structure */
1218 #ifdef BX_USE_EBDA_TABLES
1219     ebda_cur_addr = align(ebda_cur_addr, 16);
1220     float_pointer_struct = (uint8_t *)ebda_cur_addr;
1221 #else
1222     bios_table_cur_addr = align(bios_table_cur_addr, 16);
1223     float_pointer_struct = (uint8_t *)bios_table_cur_addr;
1224 #endif
1225     q = float_pointer_struct;
1226     putstr(&q, "_MP_");
1227     /* pointer to MP config table */
1228     putle32(&q, (unsigned long)mp_config_table);
1229 
1230     putb(&q, 1); /* length in 16 byte units */
1231     putb(&q, 4); /* MP spec revision */
1232     putb(&q, 0); /* checksum (patched later) */
1233     putb(&q, 0); /* MP feature byte 1 */
1234 
1235     putb(&q, 0);
1236     putb(&q, 0);
1237     putb(&q, 0);
1238     putb(&q, 0);
1239     float_pointer_struct[10] =
1240         -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
1241 #ifdef BX_USE_EBDA_TABLES
1242     ebda_cur_addr += (q - float_pointer_struct);
1243 #else
1244     bios_table_cur_addr += (q - float_pointer_struct);
1245 #endif
1246     BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
1247             (unsigned long)float_pointer_struct,
1248             (unsigned long)mp_config_table,
1249             mp_config_table_size);
1250 }
1251 
1252 /****************************************************/
1253 /* ACPI tables init */
1254 
1255 /* Table structure from Linux kernel (the ACPI tables are under the
1256    BSD license) */
1257 
1258 /*
1259  * All tables must be byte-packed to match the ACPI specification, since
1260  * the tables are provided by the system BIOS.
1261  */
1262 
1263 #define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
1264 	uint8_t                            signature [4];          /* ACPI signature (4 ASCII characters) */\
1265 	uint32_t                             length;                 /* Length of table, in bytes, including header */\
1266 	uint8_t                              revision;               /* ACPI Specification minor version # */\
1267 	uint8_t                              checksum;               /* To make sum of entire table == 0 */\
1268 	uint8_t                            oem_id [6];             /* OEM identification */\
1269 	uint8_t                            oem_table_id [8];       /* OEM table identification */\
1270 	uint32_t                             oem_revision;           /* OEM revision number */\
1271 	uint8_t                            asl_compiler_id [4];    /* ASL compiler vendor ID */\
1272 	uint32_t                             asl_compiler_revision;  /* ASL compiler revision number */
1273 
1274 
1275 struct acpi_table_header         /* ACPI common table header */
1276 {
1277 	ACPI_TABLE_HEADER_DEF
1278 } __attribute__((__packed__));
1279 
1280 struct rsdp_descriptor         /* Root System Descriptor Pointer */
1281 {
1282 	uint8_t                            signature [8];          /* ACPI signature, contains "RSD PTR " */
1283 	uint8_t                              checksum;               /* To make sum of struct == 0 */
1284 	uint8_t                            oem_id [6];             /* OEM identification */
1285 	uint8_t                              revision;               /* Must be 0 for 1.0, 2 for 2.0 */
1286 	uint32_t                             rsdt_physical_address;  /* 32-bit physical address of RSDT */
1287 	uint32_t                             length;                 /* XSDT Length in bytes including hdr */
1288 	uint64_t                             xsdt_physical_address;  /* 64-bit physical address of XSDT */
1289 	uint8_t                              extended_checksum;      /* Checksum of entire table */
1290 	uint8_t                            reserved [3];           /* Reserved field must be 0 */
1291 } __attribute__((__packed__));
1292 
1293 /*
1294  * ACPI 1.0 Root System Description Table (RSDT)
1295  */
1296 struct rsdt_descriptor_rev1
1297 {
1298 	ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
1299 #ifdef BX_QEMU
1300 	uint32_t                             table_offset_entry [5]; /* Array of pointers to other */
1301 #else
1302 	uint32_t                             table_offset_entry [3]; /* Array of pointers to other */
1303 #endif
1304 			 /* ACPI tables */
1305 } __attribute__((__packed__));
1306 
1307 /*
1308  * ACPI 1.0 Firmware ACPI Control Structure (FACS)
1309  */
1310 struct facs_descriptor_rev1
1311 {
1312 	uint8_t                            signature[4];           /* ACPI Signature */
1313 	uint32_t                             length;                 /* Length of structure, in bytes */
1314 	uint32_t                             hardware_signature;     /* Hardware configuration signature */
1315 	uint32_t                             firmware_waking_vector; /* ACPI OS waking vector */
1316 	uint32_t                             global_lock;            /* Global Lock */
1317 	uint32_t                             S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
1318 	uint32_t                             reserved1       : 31;   /* Must be 0 */
1319 	uint8_t                              resverved3 [40];        /* Reserved - must be zero */
1320 } __attribute__((__packed__));
1321 
1322 
1323 /*
1324  * ACPI 1.0 Fixed ACPI Description Table (FADT)
1325  */
1326 struct fadt_descriptor_rev1
1327 {
1328 	ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
1329 	uint32_t                             firmware_ctrl;          /* Physical address of FACS */
1330 	uint32_t                             dsdt;                   /* Physical address of DSDT */
1331 	uint8_t                              model;                  /* System Interrupt Model */
1332 	uint8_t                              reserved1;              /* Reserved */
1333 	uint16_t                             sci_int;                /* System vector of SCI interrupt */
1334 	uint32_t                             smi_cmd;                /* Port address of SMI command port */
1335 	uint8_t                              acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
1336 	uint8_t                              acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
1337 	uint8_t                              S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
1338 	uint8_t                              reserved2;              /* Reserved - must be zero */
1339 	uint32_t                             pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
1340 	uint32_t                             pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
1341 	uint32_t                             pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
1342 	uint32_t                             pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
1343 	uint32_t                             pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
1344 	uint32_t                             pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
1345 	uint32_t                             gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
1346 	uint32_t                             gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
1347 	uint8_t                              pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
1348 	uint8_t                              pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
1349 	uint8_t                              pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
1350 	uint8_t                              pm_tmr_len;              /* Byte Length of ports at pm_tm_blk */
1351 	uint8_t                              gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
1352 	uint8_t                              gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
1353 	uint8_t                              gpe1_base;              /* Offset in gpe model where gpe1 events start */
1354 	uint8_t                              reserved3;              /* Reserved */
1355 	uint16_t                             plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
1356 	uint16_t                             plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
1357 	uint16_t                             flush_size;             /* Size of area read to flush caches */
1358 	uint16_t                             flush_stride;           /* Stride used in flushing caches */
1359 	uint8_t                              duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
1360 	uint8_t                              duty_width;             /* Bit width of duty cycle field in p_cnt reg */
1361 	uint8_t                              day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
1362 	uint8_t                              mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
1363 	uint8_t                              century;                /* Index to century in RTC CMOS RAM */
1364 	uint8_t                              reserved4;              /* Reserved */
1365 	uint8_t                              reserved4a;             /* Reserved */
1366 	uint8_t                              reserved4b;             /* Reserved */
1367 #if 0
1368 	uint32_t                             wb_invd         : 1;    /* The wbinvd instruction works properly */
1369 	uint32_t                             wb_invd_flush   : 1;    /* The wbinvd flushes but does not invalidate */
1370 	uint32_t                             proc_c1         : 1;    /* All processors support C1 state */
1371 	uint32_t                             plvl2_up        : 1;    /* C2 state works on MP system */
1372 	uint32_t                             pwr_button      : 1;    /* Power button is handled as a generic feature */
1373 	uint32_t                             sleep_button    : 1;    /* Sleep button is handled as a generic feature, or not present */
1374 	uint32_t                             fixed_rTC       : 1;    /* RTC wakeup stat not in fixed register space */
1375 	uint32_t                             rtcs4           : 1;    /* RTC wakeup stat not possible from S4 */
1376 	uint32_t                             tmr_val_ext     : 1;    /* The tmr_val width is 32 bits (0 = 24 bits) */
1377 	uint32_t                             reserved5       : 23;   /* Reserved - must be zero */
1378 #else
1379         uint32_t flags;
1380 #endif
1381 } __attribute__((__packed__));
1382 
1383 /*
1384  * MADT values and structures
1385  */
1386 
1387 /* Values for MADT PCATCompat */
1388 
1389 #define DUAL_PIC                0
1390 #define MULTIPLE_APIC           1
1391 
1392 
1393 /* Master MADT */
1394 
1395 struct multiple_apic_table
1396 {
1397 	ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
1398 	uint32_t                             local_apic_address;     /* Physical address of local APIC */
1399 #if 0
1400 	uint32_t                             PCATcompat      : 1;    /* A one indicates system also has dual 8259s */
1401 	uint32_t                             reserved1       : 31;
1402 #else
1403         uint32_t                             flags;
1404 #endif
1405 } __attribute__((__packed__));
1406 
1407 
1408 /* Values for Type in APIC sub-headers */
1409 
1410 #define APIC_PROCESSOR          0
1411 #define APIC_IO                 1
1412 #define APIC_XRUPT_OVERRIDE     2
1413 #define APIC_NMI                3
1414 #define APIC_LOCAL_NMI          4
1415 #define APIC_ADDRESS_OVERRIDE   5
1416 #define APIC_IO_SAPIC           6
1417 #define APIC_LOCAL_SAPIC        7
1418 #define APIC_XRUPT_SOURCE       8
1419 #define APIC_RESERVED           9           /* 9 and greater are reserved */
1420 
1421 #define ACPI_SUB_HEADER_DEF                 /* Common ACPI sub-structure header */\
1422 	uint8_t                              type; \
1423 	uint8_t                              length;
1424 
1425 /*
1426  * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
1427  */
1428 /* Sub-structures for MADT */
1429 
1430 struct madt_processor_apic
1431 {
1432 	ACPI_SUB_HEADER_DEF
1433 	uint8_t                              processor_id;           /* ACPI processor id */
1434 	uint8_t                              local_apic_id;          /* Processor's local APIC id */
1435 #if 0
1436 	uint32_t                             processor_enabled: 1;   /* Processor is usable if set */
1437 	uint32_t                             reserved2       : 31;   /* Reserved, must be zero */
1438 #else
1439         uint32_t flags;
1440 #endif
1441 } __attribute__((__packed__));
1442 
1443 /*
1444  * SRAT (NUMA topology description) table
1445  */
1446 
1447 #define SRAT_PROCESSOR          0
1448 #define SRAT_MEMORY             1
1449 
1450 struct system_resource_affinity_table
1451 {
1452     ACPI_TABLE_HEADER_DEF
1453     uint32_t    reserved1;
1454     uint32_t    reserved2[2];
1455 };
1456 
1457 struct srat_processor_affinity
1458 {
1459     ACPI_SUB_HEADER_DEF
1460     uint8_t     proximity_lo;
1461     uint8_t     local_apic_id;
1462     uint32_t    flags;
1463     uint8_t     local_sapic_eid;
1464     uint8_t     proximity_hi[3];
1465     uint32_t    reserved;
1466 };
1467 
1468 struct srat_memory_affinity
1469 {
1470     ACPI_SUB_HEADER_DEF
1471     uint8_t     proximity[4];
1472     uint16_t    reserved1;
1473     uint32_t    base_addr_low,base_addr_high;
1474     uint32_t    length_low,length_high;
1475     uint32_t    reserved2;
1476     uint32_t    flags;
1477     uint32_t    reserved3[2];
1478 };
1479 
1480 #ifdef BX_QEMU
1481 /*
1482  *  * ACPI 2.0 Generic Address Space definition.
1483  *   */
1484 struct acpi_20_generic_address {
1485     uint8_t  address_space_id;
1486     uint8_t  register_bit_width;
1487     uint8_t  register_bit_offset;
1488     uint8_t  reserved;
1489     uint64_t address;
1490 } __attribute__((__packed__));
1491 
1492 /*
1493  *  * HPET Description Table
1494  *   */
1495 struct acpi_20_hpet {
1496     ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
1497     uint32_t           timer_block_id;
1498     struct acpi_20_generic_address addr;
1499     uint8_t            hpet_number;
1500     uint16_t           min_tick;
1501     uint8_t            page_protect;
1502 } __attribute__((__packed__));
1503 #define ACPI_HPET_ADDRESS 0xFED00000UL
1504 #endif
1505 
1506 struct madt_io_apic
1507 {
1508 	ACPI_SUB_HEADER_DEF
1509 	uint8_t                              io_apic_id;             /* I/O APIC ID */
1510 	uint8_t                              reserved;               /* Reserved - must be zero */
1511 	uint32_t                             address;                /* APIC physical address */
1512 	uint32_t                             interrupt;              /* Global system interrupt where INTI
1513 			  * lines start */
1514 } __attribute__((__packed__));
1515 
1516 #ifdef BX_QEMU
1517 struct madt_int_override
1518 {
1519 	ACPI_SUB_HEADER_DEF
1520 	uint8_t                bus;     /* Identifies ISA Bus */
1521 	uint8_t                source;  /* Bus-relative interrupt source */
1522 	uint32_t               gsi;     /* GSI that source will signal */
1523 	uint16_t               flags;   /* MPS INTI flags */
1524 } __attribute__((__packed__));
1525 #endif
1526 
1527 #include "acpi-dsdt.hex"
1528 
cpu_to_le16(uint16_t x)1529 static inline uint16_t cpu_to_le16(uint16_t x)
1530 {
1531     return x;
1532 }
1533 
cpu_to_le32(uint32_t x)1534 static inline uint32_t cpu_to_le32(uint32_t x)
1535 {
1536     return x;
1537 }
1538 
acpi_checksum(const uint8_t * data,int len)1539 static int acpi_checksum(const uint8_t *data, int len)
1540 {
1541     int sum, i;
1542     sum = 0;
1543     for(i = 0; i < len; i++)
1544         sum += data[i];
1545     return (-sum) & 0xff;
1546 }
1547 
acpi_build_table_header(struct acpi_table_header * h,char * sig,int len,uint8_t rev)1548 static void acpi_build_table_header(struct acpi_table_header *h,
1549                                     char *sig, int len, uint8_t rev)
1550 {
1551     memcpy(h->signature, sig, 4);
1552     h->length = cpu_to_le32(len);
1553     h->revision = rev;
1554 #ifdef BX_QEMU
1555     memcpy(h->oem_id, "QEMU  ", 6);
1556     memcpy(h->oem_table_id, "QEMU", 4);
1557 #else
1558     memcpy(h->oem_id, "BOCHS ", 6);
1559     memcpy(h->oem_table_id, "BXPC", 4);
1560 #endif
1561     memcpy(h->oem_table_id + 4, sig, 4);
1562     h->oem_revision = cpu_to_le32(1);
1563 #ifdef BX_QEMU
1564     memcpy(h->asl_compiler_id, "QEMU", 4);
1565 #else
1566     memcpy(h->asl_compiler_id, "BXPC", 4);
1567 #endif
1568     h->asl_compiler_revision = cpu_to_le32(1);
1569     h->checksum = acpi_checksum((void *)h, len);
1570 }
1571 
acpi_build_processor_ssdt(uint8_t * ssdt)1572 int acpi_build_processor_ssdt(uint8_t *ssdt)
1573 {
1574     uint8_t *ssdt_ptr = ssdt;
1575     int i, length;
1576     int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
1577 
1578     ssdt_ptr[9] = 0; // checksum;
1579     ssdt_ptr += sizeof(struct acpi_table_header);
1580 
1581     // caluculate the length of processor block and scope block excluding PkgLength
1582     length = 0x0d * acpi_cpus + 4;
1583 
1584     // build processor scope header
1585     *(ssdt_ptr++) = 0x10; // ScopeOp
1586     if (length <= 0x3e) {
1587         *(ssdt_ptr++) = length + 1;
1588     } else {
1589         *(ssdt_ptr++) = 0x7F;
1590         *(ssdt_ptr++) = (length + 2) >> 6;
1591     }
1592     *(ssdt_ptr++) = '_'; // Name
1593     *(ssdt_ptr++) = 'P';
1594     *(ssdt_ptr++) = 'R';
1595     *(ssdt_ptr++) = '_';
1596 
1597     // build object for each processor
1598     for(i=0;i<acpi_cpus;i++) {
1599         *(ssdt_ptr++) = 0x5B; // ProcessorOp
1600         *(ssdt_ptr++) = 0x83;
1601         *(ssdt_ptr++) = 0x0B; // Length
1602         *(ssdt_ptr++) = 'C';  // Name (CPUxx)
1603         *(ssdt_ptr++) = 'P';
1604         if ((i & 0xf0) != 0)
1605             *(ssdt_ptr++) = (i >> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa;
1606         else
1607             *(ssdt_ptr++) = 'U';
1608         *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa;
1609         *(ssdt_ptr++) = i;
1610         *(ssdt_ptr++) = 0x10; // Processor block address
1611         *(ssdt_ptr++) = 0xb0;
1612         *(ssdt_ptr++) = 0;
1613         *(ssdt_ptr++) = 0;
1614         *(ssdt_ptr++) = 6;    // Processor block length
1615     }
1616 
1617     acpi_build_table_header((struct acpi_table_header *)ssdt,
1618                             "SSDT", ssdt_ptr - ssdt, 1);
1619 
1620     return ssdt_ptr - ssdt;
1621 }
1622 
acpi_build_srat_memory(struct srat_memory_affinity * numamem,uint64_t base,uint64_t len,int node,int enabled)1623 static void acpi_build_srat_memory(struct srat_memory_affinity *numamem,
1624     uint64_t base, uint64_t len, int node, int enabled)
1625 {
1626      numamem->type = SRAT_MEMORY;
1627      numamem->length = sizeof(*numamem);
1628      memset (numamem->proximity, 0 ,4);
1629      numamem->proximity[0] = node;
1630      numamem->flags = cpu_to_le32(!!enabled);
1631      numamem->base_addr_low = base & 0xFFFFFFFF;
1632      numamem->base_addr_high = base >> 32;
1633      numamem->length_low = len & 0xFFFFFFFF;
1634      numamem->length_high = len >> 32;
1635      return;
1636 }
1637 
1638 /* base_addr must be a multiple of 4KB */
acpi_bios_init(void)1639 void acpi_bios_init(void)
1640 {
1641     struct rsdp_descriptor *rsdp;
1642     struct rsdt_descriptor_rev1 *rsdt;
1643     struct fadt_descriptor_rev1 *fadt;
1644     struct facs_descriptor_rev1 *facs;
1645     struct multiple_apic_table *madt;
1646     uint8_t *dsdt, *ssdt;
1647 #ifdef BX_QEMU
1648     struct system_resource_affinity_table *srat;
1649     struct acpi_20_hpet *hpet;
1650     uint32_t hpet_addr;
1651 #endif
1652     uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
1653     uint32_t acpi_tables_size, madt_addr, madt_size, rsdt_size;
1654     uint32_t srat_addr,srat_size;
1655     uint16_t i, external_tables;
1656     int nb_numa_nodes;
1657 
1658     /* reserve memory space for tables */
1659 #ifdef BX_USE_EBDA_TABLES
1660     ebda_cur_addr = align(ebda_cur_addr, 16);
1661     rsdp = (void *)(ebda_cur_addr);
1662     ebda_cur_addr += sizeof(*rsdp);
1663 #else
1664     bios_table_cur_addr = align(bios_table_cur_addr, 16);
1665     rsdp = (void *)(bios_table_cur_addr);
1666     bios_table_cur_addr += sizeof(*rsdp);
1667 #endif
1668 
1669 #ifdef BX_QEMU
1670     external_tables = acpi_additional_tables();
1671 #else
1672     external_tables = 0;
1673 #endif
1674 
1675     addr = base_addr = ram_size - ACPI_DATA_SIZE;
1676     rsdt_addr = addr;
1677     rsdt = (void *)(addr);
1678     rsdt_size = sizeof(*rsdt) + external_tables * 4;
1679     addr += rsdt_size;
1680 
1681     fadt_addr = addr;
1682     fadt = (void *)(addr);
1683     addr += sizeof(*fadt);
1684 
1685     /* XXX: FACS should be in RAM */
1686     addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
1687     facs_addr = addr;
1688     facs = (void *)(addr);
1689     addr += sizeof(*facs);
1690 
1691     dsdt_addr = addr;
1692     dsdt = (void *)(addr);
1693     addr += sizeof(AmlCode);
1694 
1695     ssdt_addr = addr;
1696     ssdt = (void *)(addr);
1697     addr += acpi_build_processor_ssdt(ssdt);
1698 #ifdef BX_QEMU
1699     qemu_cfg_select(QEMU_CFG_NUMA);
1700     nb_numa_nodes = qemu_cfg_get64();
1701 #else
1702     nb_numa_nodes = 0;
1703 #endif
1704     if (nb_numa_nodes > 0) {
1705         addr = (addr + 7) & ~7;
1706         srat_addr = addr;
1707         srat_size = sizeof(*srat) +
1708             sizeof(struct srat_processor_affinity) * smp_cpus +
1709             sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
1710         srat = (void *)(addr);
1711         addr += srat_size;
1712     } else {
1713         srat_addr = addr;
1714         srat = (void*)(addr);
1715         srat_size = 0;
1716     }
1717 
1718     addr = (addr + 7) & ~7;
1719     madt_addr = addr;
1720     madt_size = sizeof(*madt) +
1721         sizeof(struct madt_processor_apic) * smp_cpus +
1722 #ifdef BX_QEMU
1723         sizeof(struct madt_io_apic) + sizeof(struct madt_int_override);
1724 #else
1725         sizeof(struct madt_io_apic);
1726 #endif
1727     madt = (void *)(addr);
1728     addr += madt_size;
1729 
1730 #ifdef BX_QEMU
1731     addr = (addr + 7) & ~7;
1732     hpet_addr = addr;
1733     hpet = (void *)(addr);
1734     addr += sizeof(*hpet);
1735 #endif
1736 
1737     /* RSDP */
1738     memset(rsdp, 0, sizeof(*rsdp));
1739     memcpy(rsdp->signature, "RSD PTR ", 8);
1740 #ifdef BX_QEMU
1741     memcpy(rsdp->oem_id, "QEMU  ", 6);
1742 #else
1743     memcpy(rsdp->oem_id, "BOCHS ", 6);
1744 #endif
1745     rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
1746     rsdp->checksum = acpi_checksum((void *)rsdp, 20);
1747 
1748     /* FADT */
1749     memset(fadt, 0, sizeof(*fadt));
1750     fadt->firmware_ctrl = cpu_to_le32(facs_addr);
1751     fadt->dsdt = cpu_to_le32(dsdt_addr);
1752     fadt->model = 1;
1753     fadt->reserved1 = 0;
1754     fadt->sci_int = cpu_to_le16(pm_sci_int);
1755     fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
1756     fadt->acpi_enable = 0xf1;
1757     fadt->acpi_disable = 0xf0;
1758     fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
1759     fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
1760     fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
1761     fadt->pm1_evt_len = 4;
1762     fadt->pm1_cnt_len = 2;
1763     fadt->pm_tmr_len = 4;
1764     fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
1765     fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
1766     fadt->gpe0_blk = cpu_to_le32(0xafe0);
1767     fadt->gpe0_blk_len = 4;
1768     /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */
1769     fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6));
1770     acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
1771                             sizeof(*fadt), 1);
1772 
1773     /* FACS */
1774     memset(facs, 0, sizeof(*facs));
1775     memcpy(facs->signature, "FACS", 4);
1776     facs->length = cpu_to_le32(sizeof(*facs));
1777     BX_INFO("Firmware waking vector %p\n", &facs->firmware_waking_vector);
1778 
1779     /* DSDT */
1780     memcpy(dsdt, AmlCode, sizeof(AmlCode));
1781 
1782     /* MADT */
1783     {
1784         struct madt_processor_apic *apic;
1785         struct madt_io_apic *io_apic;
1786 #ifdef BX_QEMU
1787         struct madt_int_override *int_override;
1788 #endif
1789 
1790         memset(madt, 0, madt_size);
1791         madt->local_apic_address = cpu_to_le32(0xfee00000);
1792         madt->flags = cpu_to_le32(1);
1793         apic = (void *)(madt + 1);
1794         for(i=0;i<smp_cpus;i++) {
1795             apic->type = APIC_PROCESSOR;
1796             apic->length = sizeof(*apic);
1797             apic->processor_id = i;
1798             apic->local_apic_id = i;
1799             apic->flags = cpu_to_le32(1);
1800             apic++;
1801         }
1802         io_apic = (void *)apic;
1803         io_apic->type = APIC_IO;
1804         io_apic->length = sizeof(*io_apic);
1805         io_apic->io_apic_id = smp_cpus;
1806         io_apic->address = cpu_to_le32(0xfec00000);
1807         io_apic->interrupt = cpu_to_le32(0);
1808 #ifdef BX_QEMU
1809         io_apic++;
1810 
1811         int_override = (void *)io_apic;
1812         int_override->type = APIC_XRUPT_OVERRIDE;
1813         int_override->length = sizeof(*int_override);
1814         int_override->bus = cpu_to_le32(0);
1815         int_override->source = cpu_to_le32(0);
1816         int_override->gsi = cpu_to_le32(2);
1817         int_override->flags = cpu_to_le32(0);
1818 #endif
1819 
1820         acpi_build_table_header((struct acpi_table_header *)madt,
1821                                 "APIC", madt_size, 1);
1822     }
1823 
1824     memset(rsdt, 0, rsdt_size);
1825 #ifdef BX_QEMU
1826     /* SRAT */
1827     if (nb_numa_nodes > 0) {
1828         struct srat_processor_affinity *core;
1829         struct srat_memory_affinity *numamem;
1830         int slots;
1831         uint64_t mem_len, mem_base, next_base = 0, curnode;
1832 
1833         qemu_cfg_select(QEMU_CFG_NUMA);
1834         qemu_cfg_get64();
1835         memset (srat, 0 , srat_size);
1836         srat->reserved1=1;
1837 
1838         core = (void*)(srat + 1);
1839         for (i = 0; i < smp_cpus; ++i) {
1840              core->type = SRAT_PROCESSOR;
1841              core->length = sizeof(*core);
1842              core->local_apic_id = i;
1843              curnode = qemu_cfg_get64();
1844              core->proximity_lo = curnode;
1845              memset (core->proximity_hi, 0, 3);
1846              core->local_sapic_eid = 0;
1847              if (i < smp_cpus)
1848                  core->flags = cpu_to_le32(1);
1849              else
1850                  core->flags = 0;
1851              core++;
1852         }
1853 
1854         /* the memory map is a bit tricky, it contains at least one hole
1855          * from 640k-1M and possibly another one from 3.5G-4G.
1856          */
1857         numamem = (void*)core; slots = 0;
1858         acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
1859         next_base = 1024 * 1024; numamem++;slots++;
1860         for (i = 1; i < nb_numa_nodes + 1; ++i) {
1861             mem_base = next_base;
1862             mem_len = qemu_cfg_get64();
1863             if (i == 1) mem_len -= 1024 * 1024;
1864             next_base = mem_base + mem_len;
1865 
1866             /* Cut out the PCI hole */
1867             if (mem_base <= ram_size && next_base > ram_size) {
1868                 mem_len -= next_base - ram_size;
1869                 if (mem_len > 0) {
1870                     acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
1871                     numamem++; slots++;
1872                 }
1873                 mem_base = 1ULL << 32;
1874                 mem_len = next_base - ram_size;
1875                 next_base += (1ULL << 32) - ram_size;
1876             }
1877             acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
1878             numamem++; slots++;
1879         }
1880         for (; slots < nb_numa_nodes + 2; slots++) {
1881             acpi_build_srat_memory(numamem, 0, 0, 0, 0);
1882             numamem++;
1883         }
1884 
1885          acpi_build_table_header((struct acpi_table_header *)srat,
1886                                 "SRAT", srat_size, 1);
1887     }
1888 
1889     /* HPET */
1890     memset(hpet, 0, sizeof(*hpet));
1891     /* Note timer_block_id value must be kept in sync with value advertised by
1892      * emulated hpet
1893      */
1894     hpet->timer_block_id = cpu_to_le32(0x8086a201);
1895     hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS);
1896     acpi_build_table_header((struct  acpi_table_header *)hpet,
1897                              "HPET", sizeof(*hpet), 1);
1898 
1899     acpi_additional_tables(); /* resets cfg to required entry */
1900     for(i = 0; i < external_tables; i++) {
1901         uint16_t len;
1902         if(acpi_load_table(i, addr, &len) < 0)
1903             BX_PANIC("Failed to load ACPI table from QEMU\n");
1904         rsdt->table_offset_entry[i+4] = cpu_to_le32(addr);
1905         addr += len;
1906         if(addr >= ram_size)
1907             BX_PANIC("ACPI table overflow\n");
1908     }
1909 #endif
1910 
1911     /* RSDT */
1912     rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
1913     rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
1914     rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
1915 #ifdef BX_QEMU
1916     rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr);
1917     if (nb_numa_nodes > 0)
1918         rsdt->table_offset_entry[4] = cpu_to_le32(srat_addr);
1919 #endif
1920     acpi_build_table_header((struct acpi_table_header *)rsdt, "RSDT",
1921         rsdt_size - (nb_numa_nodes > 0? 0: sizeof(uint32_t)), 1);
1922 
1923     acpi_tables_size = addr - base_addr;
1924 
1925     BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
1926             (unsigned long)rsdp,
1927             (unsigned long)rsdt, acpi_tables_size);
1928 
1929 }
1930 
1931 /* SMBIOS entry point -- must be written to a 16-bit aligned address
1932    between 0xf0000 and 0xfffff.
1933  */
1934 struct smbios_entry_point {
1935 	char anchor_string[4];
1936 	uint8_t checksum;
1937 	uint8_t length;
1938 	uint8_t smbios_major_version;
1939 	uint8_t smbios_minor_version;
1940 	uint16_t max_structure_size;
1941 	uint8_t entry_point_revision;
1942 	uint8_t formatted_area[5];
1943 	char intermediate_anchor_string[5];
1944 	uint8_t intermediate_checksum;
1945 	uint16_t structure_table_length;
1946 	uint32_t structure_table_address;
1947 	uint16_t number_of_structures;
1948 	uint8_t smbios_bcd_revision;
1949 } __attribute__((__packed__));
1950 
1951 /* This goes at the beginning of every SMBIOS structure. */
1952 struct smbios_structure_header {
1953 	uint8_t type;
1954 	uint8_t length;
1955 	uint16_t handle;
1956 } __attribute__((__packed__));
1957 
1958 /* SMBIOS type 0 - BIOS Information */
1959 struct smbios_type_0 {
1960 	struct smbios_structure_header header;
1961 	uint8_t vendor_str;
1962 	uint8_t bios_version_str;
1963 	uint16_t bios_starting_address_segment;
1964 	uint8_t bios_release_date_str;
1965 	uint8_t bios_rom_size;
1966 	uint8_t bios_characteristics[8];
1967 	uint8_t bios_characteristics_extension_bytes[2];
1968 	uint8_t system_bios_major_release;
1969 	uint8_t system_bios_minor_release;
1970 	uint8_t embedded_controller_major_release;
1971 	uint8_t embedded_controller_minor_release;
1972 } __attribute__((__packed__));
1973 
1974 /* SMBIOS type 1 - System Information */
1975 struct smbios_type_1 {
1976 	struct smbios_structure_header header;
1977 	uint8_t manufacturer_str;
1978 	uint8_t product_name_str;
1979 	uint8_t version_str;
1980 	uint8_t serial_number_str;
1981 	uint8_t uuid[16];
1982 	uint8_t wake_up_type;
1983 	uint8_t sku_number_str;
1984 	uint8_t family_str;
1985 } __attribute__((__packed__));
1986 
1987 /* SMBIOS type 3 - System Enclosure (v2.3) */
1988 struct smbios_type_3 {
1989 	struct smbios_structure_header header;
1990 	uint8_t manufacturer_str;
1991 	uint8_t type;
1992 	uint8_t version_str;
1993 	uint8_t serial_number_str;
1994 	uint8_t asset_tag_number_str;
1995 	uint8_t boot_up_state;
1996 	uint8_t power_supply_state;
1997 	uint8_t thermal_state;
1998 	uint8_t security_status;
1999     uint32_t oem_defined;
2000     uint8_t height;
2001     uint8_t number_of_power_cords;
2002     uint8_t contained_element_count;
2003     // contained elements follow
2004 } __attribute__((__packed__));
2005 
2006 /* SMBIOS type 4 - Processor Information (v2.0) */
2007 struct smbios_type_4 {
2008 	struct smbios_structure_header header;
2009 	uint8_t socket_designation_str;
2010 	uint8_t processor_type;
2011 	uint8_t processor_family;
2012 	uint8_t processor_manufacturer_str;
2013 	uint32_t processor_id[2];
2014 	uint8_t processor_version_str;
2015 	uint8_t voltage;
2016 	uint16_t external_clock;
2017 	uint16_t max_speed;
2018 	uint16_t current_speed;
2019 	uint8_t status;
2020 	uint8_t processor_upgrade;
2021         uint16_t l1_cache_handle;
2022         uint16_t l2_cache_handle;
2023         uint16_t l3_cache_handle;
2024 } __attribute__((__packed__));
2025 
2026 /* SMBIOS type 16 - Physical Memory Array
2027  *   Associated with one type 17 (Memory Device).
2028  */
2029 struct smbios_type_16 {
2030 	struct smbios_structure_header header;
2031 	uint8_t location;
2032 	uint8_t use;
2033 	uint8_t error_correction;
2034 	uint32_t maximum_capacity;
2035 	uint16_t memory_error_information_handle;
2036 	uint16_t number_of_memory_devices;
2037 } __attribute__((__packed__));
2038 
2039 /* SMBIOS type 17 - Memory Device
2040  *   Associated with one type 19
2041  */
2042 struct smbios_type_17 {
2043 	struct smbios_structure_header header;
2044 	uint16_t physical_memory_array_handle;
2045 	uint16_t memory_error_information_handle;
2046 	uint16_t total_width;
2047 	uint16_t data_width;
2048 	uint16_t size;
2049 	uint8_t form_factor;
2050 	uint8_t device_set;
2051 	uint8_t device_locator_str;
2052 	uint8_t bank_locator_str;
2053 	uint8_t memory_type;
2054 	uint16_t type_detail;
2055 } __attribute__((__packed__));
2056 
2057 /* SMBIOS type 19 - Memory Array Mapped Address */
2058 struct smbios_type_19 {
2059 	struct smbios_structure_header header;
2060 	uint32_t starting_address;
2061 	uint32_t ending_address;
2062 	uint16_t memory_array_handle;
2063 	uint8_t partition_width;
2064 } __attribute__((__packed__));
2065 
2066 /* SMBIOS type 20 - Memory Device Mapped Address */
2067 struct smbios_type_20 {
2068 	struct smbios_structure_header header;
2069 	uint32_t starting_address;
2070 	uint32_t ending_address;
2071 	uint16_t memory_device_handle;
2072 	uint16_t memory_array_mapped_address_handle;
2073 	uint8_t partition_row_position;
2074 	uint8_t interleave_position;
2075 	uint8_t interleaved_data_depth;
2076 } __attribute__((__packed__));
2077 
2078 /* SMBIOS type 32 - System Boot Information */
2079 struct smbios_type_32 {
2080 	struct smbios_structure_header header;
2081 	uint8_t reserved[6];
2082 	uint8_t boot_status;
2083 } __attribute__((__packed__));
2084 
2085 /* SMBIOS type 127 -- End-of-table */
2086 struct smbios_type_127 {
2087 	struct smbios_structure_header header;
2088 } __attribute__((__packed__));
2089 
2090 static void
smbios_entry_point_init(void * start,uint16_t max_structure_size,uint16_t structure_table_length,uint32_t structure_table_address,uint16_t number_of_structures)2091 smbios_entry_point_init(void *start,
2092                         uint16_t max_structure_size,
2093                         uint16_t structure_table_length,
2094                         uint32_t structure_table_address,
2095                         uint16_t number_of_structures)
2096 {
2097     uint8_t sum;
2098     int i;
2099     struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
2100 
2101     memcpy(ep->anchor_string, "_SM_", 4);
2102     ep->length = 0x1f;
2103     ep->smbios_major_version = 2;
2104     ep->smbios_minor_version = 4;
2105     ep->max_structure_size = max_structure_size;
2106     ep->entry_point_revision = 0;
2107     memset(ep->formatted_area, 0, 5);
2108     memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
2109 
2110     ep->structure_table_length = structure_table_length;
2111     ep->structure_table_address = structure_table_address;
2112     ep->number_of_structures = number_of_structures;
2113     ep->smbios_bcd_revision = 0x24;
2114 
2115     ep->checksum = 0;
2116     ep->intermediate_checksum = 0;
2117 
2118     sum = 0;
2119     for (i = 0; i < 0x10; i++)
2120         sum += ((int8_t *)start)[i];
2121     ep->checksum = -sum;
2122 
2123     sum = 0;
2124     for (i = 0x10; i < ep->length; i++)
2125         sum += ((int8_t *)start)[i];
2126     ep->intermediate_checksum = -sum;
2127     }
2128 
2129 struct smbios_header {
2130     uint16_t length;
2131     uint8_t type;
2132 } __attribute__((__packed__));
2133 
2134 struct smbios_field {
2135     struct smbios_header header;
2136     uint8_t type;
2137     uint16_t offset;
2138     uint8_t data[];
2139 } __attribute__((__packed__));
2140 
2141 struct smbios_table {
2142     struct smbios_header header;
2143     uint8_t data[];
2144 } __attribute__((__packed__));
2145 
2146 #define SMBIOS_FIELD_ENTRY 0
2147 #define SMBIOS_TABLE_ENTRY 1
2148 
2149 static size_t
smbios_load_field(int type,size_t offset,void * addr)2150 smbios_load_field(int type, size_t offset, void *addr)
2151 {
2152 #ifdef BX_QEMU
2153     int i;
2154 
2155     for (i = smbios_entries(); i > 0; i--) {
2156         struct smbios_field field;
2157 
2158         qemu_cfg_read((uint8_t *)&field, sizeof(struct smbios_header));
2159         field.header.length -= sizeof(struct smbios_header);
2160 
2161         if (field.header.type != SMBIOS_FIELD_ENTRY) {
2162             while (field.header.length--)
2163                 inb(QEMU_CFG_DATA_PORT);
2164             continue;
2165         }
2166 
2167         qemu_cfg_read((uint8_t *)&field.type,
2168                       sizeof(field) - sizeof(struct smbios_header));
2169         field.header.length -= sizeof(field) - sizeof(struct smbios_header);
2170 
2171         if (field.type != type || field.offset != offset) {
2172             while (field.header.length--)
2173                 inb(QEMU_CFG_DATA_PORT);
2174             continue;
2175         }
2176 
2177         qemu_cfg_read(addr, field.header.length);
2178         return (size_t)field.header.length;
2179     }
2180 #endif
2181     return 0;
2182 }
2183 
2184 #define load_str_field_with_default(type, field, def) do {             \
2185     size = smbios_load_field(type, offsetof(struct smbios_type_##type, \
2186                                             field), end);              \
2187     if (size > 0) {                                                    \
2188         end += size;                                                   \
2189     } else {                                                           \
2190         memcpy(end, def, sizeof(def));                                 \
2191         end += sizeof(def);                                            \
2192     }                                                                  \
2193     p->field = ++str_index;                                            \
2194 } while (0)
2195 
2196 #define load_str_field_or_skip(type, field) do {                       \
2197     size = smbios_load_field(type, offsetof(struct smbios_type_##type, \
2198                                             field), end);              \
2199     if (size > 0) {                                                    \
2200         end += size;                                                   \
2201         p->field = ++str_index;                                        \
2202     } else {                                                           \
2203         p->field = 0;                                                  \
2204     }                                                                  \
2205 } while (0)
2206 
2207 /* Type 0 -- BIOS Information */
2208 #define RELEASE_DATE_STR "01/01/2007"
2209 static void *
smbios_init_type_0(void * start)2210 smbios_init_type_0(void *start)
2211 {
2212     struct smbios_type_0 *p = (struct smbios_type_0 *)start;
2213     char *end = (char *)start + sizeof(struct smbios_type_0);
2214     size_t size;
2215     int str_index = 0;
2216 
2217     p->header.type = 0;
2218     p->header.length = sizeof(struct smbios_type_0);
2219     p->header.handle = 0;
2220 
2221     load_str_field_with_default(0, vendor_str, BX_APPNAME);
2222     load_str_field_with_default(0, bios_version_str, BX_APPNAME);
2223 
2224     p->bios_starting_address_segment = 0xe800;
2225 
2226     load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR);
2227 
2228     p->bios_rom_size = 0; /* FIXME */
2229 
2230     memset(p->bios_characteristics, 0, 8);
2231     p->bios_characteristics[0] = 0x08; /* BIOS characteristics not supported */
2232     p->bios_characteristics_extension_bytes[0] = 0;
2233     p->bios_characteristics_extension_bytes[1] = 0;
2234 
2235     if (!smbios_load_field(0, offsetof(struct smbios_type_0,
2236                                        system_bios_major_release),
2237                            &p->system_bios_major_release))
2238         p->system_bios_major_release = 1;
2239 
2240     if (!smbios_load_field(0, offsetof(struct smbios_type_0,
2241                                        system_bios_minor_release),
2242                            &p->system_bios_minor_release))
2243         p->system_bios_minor_release = 0;
2244 
2245     p->embedded_controller_major_release = 0xff;
2246     p->embedded_controller_minor_release = 0xff;
2247 
2248     *end = 0;
2249     end++;
2250 
2251     return end;
2252 }
2253 
2254 /* Type 1 -- System Information */
2255 static void *
smbios_init_type_1(void * start)2256 smbios_init_type_1(void *start)
2257 {
2258     struct smbios_type_1 *p = (struct smbios_type_1 *)start;
2259     char *end = (char *)start + sizeof(struct smbios_type_1);
2260     size_t size;
2261     int str_index = 0;
2262 
2263     p->header.type = 1;
2264     p->header.length = sizeof(struct smbios_type_1);
2265     p->header.handle = 0x100;
2266 
2267     load_str_field_or_skip(1, manufacturer_str);
2268     load_str_field_or_skip(1, product_name_str);
2269     load_str_field_or_skip(1, version_str);
2270     load_str_field_or_skip(1, serial_number_str);
2271 
2272     size = smbios_load_field(1, offsetof(struct smbios_type_1,
2273                                          uuid), &p->uuid);
2274     if (size == 0)
2275         memset(p->uuid, 0, 16);
2276 
2277     p->wake_up_type = 0x06; /* power switch */
2278 
2279     load_str_field_or_skip(1, sku_number_str);
2280     load_str_field_or_skip(1, family_str);
2281 
2282     *end = 0;
2283     end++;
2284     if (!str_index) {
2285         *end = 0;
2286         end++;
2287     }
2288 
2289     return end;
2290 }
2291 
2292 /* Type 3 -- System Enclosure */
2293 static void *
smbios_init_type_3(void * start)2294 smbios_init_type_3(void *start)
2295 {
2296     struct smbios_type_3 *p = (struct smbios_type_3 *)start;
2297 
2298     p->header.type = 3;
2299     p->header.length = sizeof(struct smbios_type_3);
2300     p->header.handle = 0x300;
2301 
2302     p->manufacturer_str = 0;
2303     p->type = 0x01; /* other */
2304     p->version_str = 0;
2305     p->serial_number_str = 0;
2306     p->asset_tag_number_str = 0;
2307     p->boot_up_state = 0x03; /* safe */
2308     p->power_supply_state = 0x03; /* safe */
2309     p->thermal_state = 0x03; /* safe */
2310     p->security_status = 0x02; /* unknown */
2311     p->oem_defined = 0;
2312     p->height = 0;
2313     p->number_of_power_cords = 0;
2314     p->contained_element_count = 0;
2315 
2316     start += sizeof(struct smbios_type_3);
2317     *((uint16_t *)start) = 0;
2318 
2319     return start+2;
2320 }
2321 
2322 /* Type 4 -- Processor Information */
2323 static void *
smbios_init_type_4(void * start,unsigned int cpu_number)2324 smbios_init_type_4(void *start, unsigned int cpu_number)
2325 {
2326     struct smbios_type_4 *p = (struct smbios_type_4 *)start;
2327 
2328     p->header.type = 4;
2329     p->header.length = sizeof(struct smbios_type_4);
2330     p->header.handle = 0x400 + cpu_number;
2331 
2332     p->socket_designation_str = 1;
2333     p->processor_type = 0x03; /* CPU */
2334     p->processor_family = 0x01; /* other */
2335     p->processor_manufacturer_str = 0;
2336 
2337     p->processor_id[0] = cpuid_signature;
2338     p->processor_id[1] = cpuid_features;
2339 
2340     p->processor_version_str = 0;
2341     p->voltage = 0;
2342     p->external_clock = 0;
2343 
2344     p->max_speed = 0; /* unknown */
2345     p->current_speed = 0; /* unknown */
2346 
2347     p->status = 0x41; /* socket populated, CPU enabled */
2348     p->processor_upgrade = 0x01; /* other */
2349 
2350     p->l1_cache_handle = 0xffff; /* cache information structure not provided */
2351     p->l2_cache_handle = 0xffff;
2352     p->l3_cache_handle = 0xffff;
2353 
2354     start += sizeof(struct smbios_type_4);
2355 
2356     memcpy((char *)start, "CPU  " "\0" "" "\0" "", 7);
2357 	((char *)start)[4] = cpu_number + '0';
2358 
2359     return start+7;
2360 }
2361 
2362 /* Type 16 -- Physical Memory Array */
2363 static void *
smbios_init_type_16(void * start,uint32_t memsize,int nr_mem_devs)2364 smbios_init_type_16(void *start, uint32_t memsize, int nr_mem_devs)
2365 {
2366     struct smbios_type_16 *p = (struct smbios_type_16*)start;
2367 
2368     p->header.type = 16;
2369     p->header.length = sizeof(struct smbios_type_16);
2370     p->header.handle = 0x1000;
2371 
2372     p->location = 0x01; /* other */
2373     p->use = 0x03; /* system memory */
2374     p->error_correction = 0x01; /* other */
2375     p->maximum_capacity = memsize * 1024;
2376     p->memory_error_information_handle = 0xfffe; /* none provided */
2377     p->number_of_memory_devices = nr_mem_devs;
2378 
2379     start += sizeof(struct smbios_type_16);
2380     *((uint16_t *)start) = 0;
2381 
2382     return start + 2;
2383 }
2384 
2385 /* Type 17 -- Memory Device */
2386 static void *
smbios_init_type_17(void * start,uint32_t memory_size_mb,int instance)2387 smbios_init_type_17(void *start, uint32_t memory_size_mb, int instance)
2388 {
2389     struct smbios_type_17 *p = (struct smbios_type_17 *)start;
2390 
2391     p->header.type = 17;
2392     p->header.length = sizeof(struct smbios_type_17);
2393     p->header.handle = 0x1100 + instance;
2394 
2395     p->physical_memory_array_handle = 0x1000;
2396     p->total_width = 64;
2397     p->data_width = 64;
2398 /* TODO: should assert in case something is wrong   ASSERT((memory_size_mb & ~0x7fff) == 0); */
2399     p->size = memory_size_mb;
2400     p->form_factor = 0x09; /* DIMM */
2401     p->device_set = 0;
2402     p->device_locator_str = 1;
2403     p->bank_locator_str = 0;
2404     p->memory_type = 0x07; /* RAM */
2405     p->type_detail = 0;
2406 
2407     start += sizeof(struct smbios_type_17);
2408     snprintf(start, 8, "DIMM %d", instance);
2409     start += strlen(start) + 1;
2410     *((uint8_t *)start) = 0;
2411 
2412     return start+1;
2413 }
2414 
2415 /* Type 19 -- Memory Array Mapped Address */
2416 static void *
smbios_init_type_19(void * start,uint32_t memory_size_mb,int instance)2417 smbios_init_type_19(void *start, uint32_t memory_size_mb, int instance)
2418 {
2419     struct smbios_type_19 *p = (struct smbios_type_19 *)start;
2420 
2421     p->header.type = 19;
2422     p->header.length = sizeof(struct smbios_type_19);
2423     p->header.handle = 0x1300 + instance;
2424 
2425     p->starting_address = instance << 24;
2426     p->ending_address = p->starting_address + (memory_size_mb << 10) - 1;
2427     p->memory_array_handle = 0x1000;
2428     p->partition_width = 1;
2429 
2430     start += sizeof(struct smbios_type_19);
2431     *((uint16_t *)start) = 0;
2432 
2433     return start + 2;
2434 }
2435 
2436 /* Type 20 -- Memory Device Mapped Address */
2437 static void *
smbios_init_type_20(void * start,uint32_t memory_size_mb,int instance)2438 smbios_init_type_20(void *start, uint32_t memory_size_mb, int instance)
2439 {
2440     struct smbios_type_20 *p = (struct smbios_type_20 *)start;
2441 
2442     p->header.type = 20;
2443     p->header.length = sizeof(struct smbios_type_20);
2444     p->header.handle = 0x1400 + instance;
2445 
2446     p->starting_address = instance << 24;
2447     p->ending_address = p->starting_address + (memory_size_mb << 10) - 1;
2448     p->memory_device_handle = 0x1100 + instance;
2449     p->memory_array_mapped_address_handle = 0x1300 + instance;
2450     p->partition_row_position = 1;
2451     p->interleave_position = 0;
2452     p->interleaved_data_depth = 0;
2453 
2454     start += sizeof(struct smbios_type_20);
2455 
2456     *((uint16_t *)start) = 0;
2457     return start+2;
2458 }
2459 
2460 /* Type 32 -- System Boot Information */
2461 static void *
smbios_init_type_32(void * start)2462 smbios_init_type_32(void *start)
2463 {
2464     struct smbios_type_32 *p = (struct smbios_type_32 *)start;
2465 
2466     p->header.type = 32;
2467     p->header.length = sizeof(struct smbios_type_32);
2468     p->header.handle = 0x2000;
2469     memset(p->reserved, 0, 6);
2470     p->boot_status = 0; /* no errors detected */
2471 
2472     start += sizeof(struct smbios_type_32);
2473     *((uint16_t *)start) = 0;
2474 
2475     return start+2;
2476 }
2477 
2478 /* Type 127 -- End of Table */
2479 static void *
smbios_init_type_127(void * start)2480 smbios_init_type_127(void *start)
2481 {
2482     struct smbios_type_127 *p = (struct smbios_type_127 *)start;
2483 
2484     p->header.type = 127;
2485     p->header.length = sizeof(struct smbios_type_127);
2486     p->header.handle = 0x7f00;
2487 
2488     start += sizeof(struct smbios_type_127);
2489     *((uint16_t *)start) = 0;
2490 
2491     return start + 2;
2492 }
2493 
2494 static int
smbios_load_external(int type,char ** p,unsigned * nr_structs,unsigned * max_struct_size)2495 smbios_load_external(int type, char **p, unsigned *nr_structs,
2496                      unsigned *max_struct_size)
2497 {
2498 #ifdef BX_QEMU
2499     static uint64_t used_bitmap[4] = { 0 };
2500     char *start = *p;
2501     int i;
2502 
2503     /* Check if we've already reported these tables */
2504     if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
2505         return 1;
2506 
2507     /* Don't introduce spurious end markers */
2508     if (type == 127)
2509         return 0;
2510 
2511     for (i = smbios_entries(); i > 0; i--) {
2512         struct smbios_table table;
2513         struct smbios_structure_header *header = (void *)*p;
2514         int string;
2515 
2516         qemu_cfg_read((uint8_t *)&table, sizeof(struct smbios_header));
2517         table.header.length -= sizeof(struct smbios_header);
2518 
2519         if (table.header.type != SMBIOS_TABLE_ENTRY) {
2520             while (table.header.length--)
2521                 inb(QEMU_CFG_DATA_PORT);
2522             continue;
2523         }
2524 
2525         qemu_cfg_read((uint8_t *)*p, sizeof(struct smbios_structure_header));
2526         table.header.length -= sizeof(struct smbios_structure_header);
2527 
2528         if (header->type != type) {
2529             while (table.header.length--)
2530                 inb(QEMU_CFG_DATA_PORT);
2531             continue;
2532         }
2533 
2534         *p += sizeof(struct smbios_structure_header);
2535 
2536         /* Entries end with a double NULL char, if there's a string at
2537          * the end (length is greater than formatted length), the string
2538          * terminator provides the first NULL. */
2539         string = header->length < table.header.length +
2540                  sizeof(struct smbios_structure_header);
2541 
2542         /* Read the rest and terminate the entry */
2543         qemu_cfg_read((uint8_t *)*p, table.header.length);
2544         *p += table.header.length;
2545         *((uint8_t*)*p) = 0;
2546         (*p)++;
2547         if (!string) {
2548             *((uint8_t*)*p) = 0;
2549             (*p)++;
2550         }
2551 
2552         (*nr_structs)++;
2553         if (*p - (char *)header > *max_struct_size)
2554             *max_struct_size = *p - (char *)header;
2555     }
2556 
2557     /* Mark that we've reported on this type */
2558     used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
2559 
2560     return (start != *p);
2561 #else /* !BX_QEMU */
2562     return 0;
2563 #endif
2564 }
2565 
smbios_init(void)2566 void smbios_init(void)
2567 {
2568     unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
2569     char *start, *p, *q;
2570     int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) :
2571                   (ram_end - (1ull << 32) + ram_size) / (1024 * 1024);
2572     int i, nr_mem_devs;
2573 
2574 #ifdef BX_USE_EBDA_TABLES
2575     ebda_cur_addr = align(ebda_cur_addr, 16);
2576     start = (void *)(ebda_cur_addr);
2577 #else
2578     bios_table_cur_addr = align(bios_table_cur_addr, 16);
2579     start = (void *)(bios_table_cur_addr);
2580 #endif
2581 
2582 	p = (char *)start + sizeof(struct smbios_entry_point);
2583 
2584 #define add_struct(type, args...) do {                                    \
2585     if (!smbios_load_external(type, &p, &nr_structs, &max_struct_size)) { \
2586         q = smbios_init_type_##type(args);                                \
2587         nr_structs++;                                                     \
2588         if ((q - p) > max_struct_size)                                    \
2589             max_struct_size = q - p;                                      \
2590         p = q;                                                            \
2591     }                                                                     \
2592 } while (0)
2593 
2594     add_struct(0, p);
2595     add_struct(1, p);
2596     add_struct(3, p);
2597     for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
2598         add_struct(4, p, cpu_num);
2599 
2600     /* Each 'memory device' covers up to 16GB of address space. */
2601     nr_mem_devs = (memsize + 0x3fff) >> 14;
2602     add_struct(16, p, memsize, nr_mem_devs);
2603     for ( i = 0; i < nr_mem_devs; i++ )
2604     {
2605         uint32_t dev_memsize = ((i == (nr_mem_devs - 1))
2606                                 ? (((memsize-1) & 0x3fff)+1) : 0x4000);
2607         add_struct(17, p, dev_memsize, i);
2608         add_struct(19, p, dev_memsize, i);
2609         add_struct(20, p, dev_memsize, i);
2610     }
2611 
2612     add_struct(32, p);
2613     /* Add any remaining provided entries before the end marker */
2614     for (i = 0; i < 256; i++)
2615         smbios_load_external(i, &p, &nr_structs, &max_struct_size);
2616     add_struct(127, p);
2617 
2618 #undef add_struct
2619 
2620     smbios_entry_point_init(
2621         start, max_struct_size,
2622         (p - (char *)start) - sizeof(struct smbios_entry_point),
2623         (uint32_t)(start + sizeof(struct smbios_entry_point)),
2624         nr_structs);
2625 
2626 #ifdef BX_USE_EBDA_TABLES
2627     ebda_cur_addr += (p - (char *)start);
2628 #else
2629     bios_table_cur_addr += (p - (char *)start);
2630 #endif
2631 
2632     BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
2633 }
2634 
find_resume_vector(void)2635 static uint32_t find_resume_vector(void)
2636 {
2637     unsigned long addr, start, end;
2638 
2639 #ifdef BX_USE_EBDA_TABLES
2640     start = align(ebda_cur_addr, 16);
2641     end = 0xa000 << 4;
2642 #else
2643     if (bios_table_cur_addr == 0)
2644         return 0;
2645     start = align(bios_table_cur_addr, 16);
2646     end = bios_table_end_addr;
2647 #endif
2648 
2649     for (addr = start; addr < end; addr += 16) {
2650         if (!memcmp((void*)addr, "RSD PTR ", 8)) {
2651             struct rsdp_descriptor *rsdp = (void*)addr;
2652             struct rsdt_descriptor_rev1 *rsdt = (void*)rsdp->rsdt_physical_address;
2653             struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[0];
2654             struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
2655             return facs->firmware_waking_vector;
2656         }
2657     }
2658 
2659     return 0;
2660 }
2661 
find_440fx(PCIDevice * d)2662 static void find_440fx(PCIDevice *d)
2663 {
2664     uint16_t vendor_id, device_id;
2665 
2666     vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
2667     device_id = pci_config_readw(d, PCI_DEVICE_ID);
2668 
2669     if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441)
2670         i440_pcidev = *d;
2671 }
2672 
reinit_piix4_pm(PCIDevice * d)2673 static void reinit_piix4_pm(PCIDevice *d)
2674 {
2675     uint16_t vendor_id, device_id;
2676 
2677     vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
2678     device_id = pci_config_readw(d, PCI_DEVICE_ID);
2679 
2680     if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3)
2681         piix4_pm_enable(d);
2682 }
2683 
rombios32_init(uint32_t * s3_resume_vector,uint8_t * shutdown_flag)2684 void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
2685 {
2686     BX_INFO("Starting rombios32\n");
2687     BX_INFO("Shutdown flag %x\n", *shutdown_flag);
2688 
2689 #ifdef BX_QEMU
2690     qemu_cfg_port = qemu_cfg_port_probe();
2691 #endif
2692 
2693     ram_probe();
2694 
2695     cpu_probe();
2696 
2697     setup_mtrr();
2698 
2699     smp_probe();
2700 
2701     find_bios_table_area();
2702 
2703     if (*shutdown_flag == 0xfe) {
2704         /* redirect bios read access to RAM */
2705         pci_for_each_device(find_440fx);
2706         bios_lock_shadow_ram(); /* bios is already copied */
2707         *s3_resume_vector = find_resume_vector();
2708         if (!*s3_resume_vector) {
2709             BX_INFO("This is S3 resume but wakeup vector is NULL\n");
2710         } else {
2711             BX_INFO("S3 resume vector %p\n", *s3_resume_vector);
2712             pci_for_each_device(reinit_piix4_pm);
2713         }
2714         return;
2715     }
2716 
2717     pci_bios_init();
2718 
2719     if (bios_table_cur_addr != 0) {
2720 
2721         mptable_init();
2722 
2723         smbios_init();
2724 
2725         if (acpi_enabled)
2726             acpi_bios_init();
2727 
2728         bios_lock_shadow_ram();
2729 
2730         BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
2731         if (bios_table_cur_addr > bios_table_end_addr)
2732             BX_PANIC("bios_table_end_addr overflow!\n");
2733 #ifdef BX_USE_EBDA_TABLES
2734         BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
2735         if (ebda_cur_addr > 0xA0000)
2736             BX_PANIC("ebda_cur_addr overflow!\n");
2737 #endif
2738     }
2739 }
2740