- removed special case for the Bochs VBE LFB base address (it can be treated
[gplbios.git] / rombios32.c
blob596695ae5f2628b1fbacc5de690a16a9e6bcdf8f
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.
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.
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>
24 #include "rombios.h"
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;
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
40 /* define it if the (emulated) hardware supports SMM mode */
41 #define BX_USE_SMM
43 #define cpuid(index, eax, ebx, ecx, edx) \
44 asm volatile ("cpuid" \
45 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
46 : "0" (index))
48 #define wbinvd() asm volatile("wbinvd")
50 #define CPUID_MSR (1 << 5)
51 #define CPUID_APIC (1 << 9)
52 #define CPUID_MTRR (1 << 12)
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
60 #define APIC_ENABLED 0x0100
62 #define AP_BOOT_ADDR 0x9f000
64 #define MPTABLE_MAX_SIZE 0x00002000
65 #define SMI_CMD_IO_ADDR 0xb2
67 #define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */
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
83 #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
84 #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
86 static inline void outl(int addr, int val)
88 asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val));
91 static inline void outw(int addr, int val)
93 asm volatile ("outw %w1, %w0" : : "d" (addr), "a" (val));
96 static inline void outb(int addr, int val)
98 asm volatile ("outb %b1, %w0" : : "d" (addr), "a" (val));
101 static inline uint32_t inl(int addr)
103 uint32_t val;
104 asm volatile ("inl %w1, %0" : "=a" (val) : "d" (addr));
105 return val;
108 static inline uint16_t inw(int addr)
110 uint16_t val;
111 asm volatile ("inw %w1, %w0" : "=a" (val) : "d" (addr));
112 return val;
115 static inline uint8_t inb(int addr)
117 uint8_t val;
118 asm volatile ("inb %w1, %b0" : "=a" (val) : "d" (addr));
119 return val;
122 static inline void writel(void *addr, uint32_t val)
124 *(volatile uint32_t *)addr = val;
127 static inline void writew(void *addr, uint16_t val)
129 *(volatile uint16_t *)addr = val;
132 static inline void writeb(void *addr, uint8_t val)
134 *(volatile uint8_t *)addr = val;
137 static inline uint32_t readl(const void *addr)
139 return *(volatile const uint32_t *)addr;
142 static inline uint16_t readw(const void *addr)
144 return *(volatile const uint16_t *)addr;
147 static inline uint8_t readb(const void *addr)
149 return *(volatile const uint8_t *)addr;
152 static inline void putch(int c)
154 outb(INFO_PORT, c);
157 static uint64_t rdmsr(unsigned index)
159 unsigned long long ret;
161 asm ("rdmsr" : "=A"(ret) : "c"(index));
162 return ret;
165 static void wrmsr(unsigned index, uint64_t val)
167 asm volatile ("wrmsr" : : "c"(index), "A"(val));
170 static inline int isdigit(int c)
172 return c >= '0' && c <= '9';
175 void *memset(void *d1, int val, size_t len)
177 uint8_t *d = d1;
179 while (len--) {
180 *d++ = val;
182 return d1;
185 void *memcpy(void *d1, const void *s1, size_t len)
187 uint8_t *d = d1;
188 const uint8_t *s = s1;
190 while (len--) {
191 *d++ = *s++;
193 return d1;
196 void *memmove(void *d1, const void *s1, size_t len)
198 uint8_t *d = d1;
199 const uint8_t *s = s1;
201 if (d <= s) {
202 while (len--) {
203 *d++ = *s++;
205 } else {
206 d += len;
207 s += len;
208 while (len--) {
209 *--d = *--s;
212 return d1;
215 int memcmp(const void *s1, const void *s2, size_t len)
217 const int8_t *p1 = s1;
218 const int8_t *p2 = s2;
220 while (len--) {
221 int r = *p1++ - *p2++;
222 if(r)
223 return r;
226 return 0;
229 size_t strlen(const char *s)
231 const char *s1;
232 for(s1 = s; *s1 != '\0'; s1++);
233 return s1 - s;
236 /* from BSD ppp sources */
237 int vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
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";
248 buf0 = buf;
249 --buflen;
250 while (buflen > 0) {
251 for (f = fmt; *f != '%' && *f != 0; ++f)
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;
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;
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;
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;
292 /* modifiers */
293 switch(c) {
294 case 'l':
295 c = *++fmt;
296 break;
297 default:
298 break;
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;
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;
352 switch (neg) {
353 case 1:
354 *--str = '-';
355 break;
356 case 2:
357 *--str = 'x';
358 *--str = '0';
359 break;
361 len = num + sizeof(num) - 1 - str;
362 } else {
363 len = strlen(str);
364 if (prec > 0 && len > prec)
365 len = prec;
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;
376 if (len > buflen)
377 len = buflen;
378 memcpy(buf, str, len);
379 buf += len;
380 buflen -= len;
382 *buf = 0;
383 return buf - buf0;
386 void bios_printf(int flags, const char *fmt, ...)
388 va_list ap;
389 char buf[1024];
390 const char *s;
392 if ((flags & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT)
393 outb(PANIC_PORT2, 0x00);
395 va_start(ap, fmt);
396 vsnprintf(buf, sizeof(buf), fmt, ap);
397 s = buf;
398 while (*s)
399 putch(*s++);
400 va_end(ap);
403 void delay_ms(int n)
405 int i, j;
406 for(i = 0; i < n; i++) {
407 #ifdef BX_QEMU
408 /* approximative ! */
409 for(j = 0; j < 1000000; j++);
410 #else
412 int r1, r2;
413 j = 66;
414 r1 = inb(0x61) & 0x10;
415 do {
416 r2 = inb(0x61) & 0x10;
417 if (r1 != r2) {
418 j--;
419 r1 = r2;
421 } while (j > 0);
423 #endif
427 uint16_t smp_cpus;
428 uint32_t cpuid_signature;
429 uint32_t cpuid_features;
430 uint32_t cpuid_ext_features;
431 unsigned long ram_size;
432 uint8_t bios_uuid[16];
433 #ifdef BX_USE_EBDA_TABLES
434 unsigned long ebda_cur_addr;
435 #endif
436 int acpi_enabled;
437 uint32_t pm_io_base, smb_io_base;
438 int pm_sci_int;
439 unsigned long bios_table_cur_addr;
440 unsigned long bios_table_end_addr;
442 void wrmsr_smp(uint32_t index, uint64_t val)
444 static struct { uint32_t ecx, eax, edx; } *p = (void *)SMP_MSR_ADDR;
446 wrmsr(index, val);
447 p->ecx = index;
448 p->eax = val;
449 p->edx = val >> 32;
450 ++p;
451 p->ecx = 0;
454 #ifdef BX_QEMU
455 #define QEMU_CFG_CTL_PORT 0x510
456 #define QEMU_CFG_DATA_PORT 0x511
457 #define QEMU_CFG_SIGNATURE 0x00
458 #define QEMU_CFG_ID 0x01
459 #define QEMU_CFG_UUID 0x02
461 int qemu_cfg_port;
463 void qemu_cfg_select(int f)
465 outw(QEMU_CFG_CTL_PORT, f);
468 int qemu_cfg_port_probe()
470 char *sig = "QEMU";
471 int i;
473 qemu_cfg_select(QEMU_CFG_SIGNATURE);
475 for (i = 0; i < 4; i++)
476 if (inb(QEMU_CFG_DATA_PORT) != sig[i])
477 return 0;
479 return 1;
482 void qemu_cfg_read(uint8_t *buf, int len)
484 while (len--)
485 *(buf++) = inb(QEMU_CFG_DATA_PORT);
487 #endif
489 void uuid_probe(void)
491 #ifdef BX_QEMU
492 if(qemu_cfg_port) {
493 qemu_cfg_select(QEMU_CFG_UUID);
494 qemu_cfg_read(bios_uuid, 16);
495 return;
497 #endif
498 memset(bios_uuid, 0, 16);
501 void cpu_probe(void)
503 uint32_t eax, ebx, ecx, edx;
504 cpuid(1, eax, ebx, ecx, edx);
505 cpuid_signature = eax;
506 cpuid_features = edx;
507 cpuid_ext_features = ecx;
510 static int cmos_readb(int addr)
512 outb(0x70, addr);
513 return inb(0x71);
516 void setup_mtrr(void)
518 int i, vcnt, fix, wc;
519 uint32_t mtrr_cap;
520 union {
521 uint8_t valb[8];
522 uint64_t val;
523 } u;
525 *(uint32_t *)SMP_MSR_ADDR = 0;
527 if (!(cpuid_features & CPUID_MTRR))
528 return;
530 if (!(cpuid_features & CPUID_MSR))
531 return;
533 mtrr_cap = rdmsr(MSR_MTRRcap);
534 vcnt = mtrr_cap & 0xff;
535 fix = mtrr_cap & 0x100;
536 wc = mtrr_cap & 0x400;
537 if (!vcnt || !fix)
538 return;
540 u.val = 0;
541 for (i = 0; i < 8; ++i)
542 if (ram_size >= 65536 * (i + 1))
543 u.valb[i] = 6;
544 wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
545 u.val = 0;
546 for (i = 0; i < 8; ++i)
547 if (ram_size >= 65536 * 8 + 16384 * (i + 1))
548 u.valb[i] = 6;
549 wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
550 wrmsr_smp(MSR_MTRRfix16K_A0000, 0);
551 wrmsr_smp(MSR_MTRRfix4K_C0000, 0);
552 wrmsr_smp(MSR_MTRRfix4K_C8000, 0);
553 wrmsr_smp(MSR_MTRRfix4K_D0000, 0);
554 wrmsr_smp(MSR_MTRRfix4K_D8000, 0);
555 wrmsr_smp(MSR_MTRRfix4K_E0000, 0);
556 wrmsr_smp(MSR_MTRRfix4K_E8000, 0);
557 wrmsr_smp(MSR_MTRRfix4K_F0000, 0);
558 wrmsr_smp(MSR_MTRRfix4K_F8000, 0);
559 /* Mark 3.5-4GB as UC, anything not specified defaults to WB */
560 wrmsr_smp(MTRRphysBase_MSR(0), 0xe0000000ull | 0);
561 wrmsr_smp(MTRRphysMask_MSR(0), ~(0x20000000ull - 1) | 0x800);
562 wrmsr_smp(MSR_MTRRdefType, 0xc06);
565 void ram_probe(void)
567 if (cmos_readb(0x34) | cmos_readb(0x35))
568 ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 +
569 16 * 1024 * 1024;
570 else
571 ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 +
572 1 * 1024 * 1024;
573 BX_INFO("ram_size=0x%08lx\n", ram_size);
574 #ifdef BX_USE_EBDA_TABLES
575 ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
576 BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
577 #endif
580 /****************************************************/
581 /* SMP probe */
583 extern uint8_t smp_ap_boot_code_start;
584 extern uint8_t smp_ap_boot_code_end;
586 /* find the number of CPUs by launching a SIPI to them */
587 void smp_probe(void)
589 uint32_t val, sipi_vector;
591 writew(&smp_cpus, 1);
592 if (cpuid_features & CPUID_APIC) {
594 /* enable local APIC */
595 val = readl(APIC_BASE + APIC_SVR);
596 val |= APIC_ENABLED;
597 writel(APIC_BASE + APIC_SVR, val);
599 /* copy AP boot code */
600 memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start,
601 &smp_ap_boot_code_end - &smp_ap_boot_code_start);
603 /* broadcast SIPI */
604 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500);
605 sipi_vector = AP_BOOT_ADDR >> 12;
606 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector);
608 #ifndef BX_QEMU
609 delay_ms(10);
610 #else
611 while (cmos_readb(0x5f) + 1 != readw(&smp_cpus))
613 #endif
615 BX_INFO("Found %d cpu(s)\n", readw(&smp_cpus));
618 /****************************************************/
619 /* PCI init */
621 #define PCI_ADDRESS_SPACE_MEM 0x00
622 #define PCI_ADDRESS_SPACE_IO 0x01
623 #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
625 #define PCI_ROM_SLOT 6
626 #define PCI_NUM_REGIONS 7
628 #define PCI_DEVICES_MAX 64
630 #define PCI_VENDOR_ID 0x00 /* 16 bits */
631 #define PCI_DEVICE_ID 0x02 /* 16 bits */
632 #define PCI_COMMAND 0x04 /* 16 bits */
633 #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
634 #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
635 #define PCI_CLASS_DEVICE 0x0a /* Device class */
636 #define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
637 #define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
638 #define PCI_MIN_GNT 0x3e /* 8 bits */
639 #define PCI_MAX_LAT 0x3f /* 8 bits */
641 #define PCI_VENDOR_ID_INTEL 0x8086
642 #define PCI_DEVICE_ID_INTEL_82441 0x1237
643 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
644 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
645 #define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
646 #define PCI_DEVICE_ID_INTEL_82371AB 0x7111
647 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
649 #define PCI_VENDOR_ID_IBM 0x1014
650 #define PCI_VENDOR_ID_APPLE 0x106b
652 typedef struct PCIDevice {
653 int bus;
654 int devfn;
655 } PCIDevice;
657 static uint32_t pci_bios_io_addr;
658 static uint32_t pci_bios_mem_addr;
659 static uint32_t pci_bios_bigmem_addr;
660 /* host irqs corresponding to PCI irqs A-D */
661 static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
662 static PCIDevice i440_pcidev;
664 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
666 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
667 outl(0xcfc, val);
670 static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
672 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
673 outw(0xcfc + (addr & 2), val);
676 static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
678 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
679 outb(0xcfc + (addr & 3), val);
682 static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
684 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
685 return inl(0xcfc);
688 static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
690 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
691 return inw(0xcfc + (addr & 2));
694 static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
696 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
697 return inb(0xcfc + (addr & 3));
700 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
702 uint16_t cmd;
703 uint32_t ofs, old_addr;
705 if ( region_num == PCI_ROM_SLOT ) {
706 ofs = 0x30;
707 }else{
708 ofs = 0x10 + region_num * 4;
711 old_addr = pci_config_readl(d, ofs);
713 pci_config_writel(d, ofs, addr);
714 BX_INFO("region %d: 0x%08x\n", region_num, addr);
716 /* enable memory mappings */
717 cmd = pci_config_readw(d, PCI_COMMAND);
718 if ( region_num == PCI_ROM_SLOT )
719 cmd |= 2;
720 else if (old_addr & PCI_ADDRESS_SPACE_IO)
721 cmd |= 1;
722 else
723 cmd |= 2;
724 pci_config_writew(d, PCI_COMMAND, cmd);
727 /* return the global irq number corresponding to a given device irq
728 pin. We could also use the bus number to have a more precise
729 mapping. */
730 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
732 int slot_addend;
733 slot_addend = (pci_dev->devfn >> 3) - 1;
734 return (irq_num + slot_addend) & 3;
737 static void find_bios_table_area(void)
739 unsigned long addr;
740 for(addr = 0xf0000; addr < 0x100000; addr += 16) {
741 if (*(uint32_t *)addr == 0xaafb4442) {
742 bios_table_cur_addr = addr + 8;
743 bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
744 BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
745 bios_table_cur_addr, bios_table_end_addr);
746 return;
749 return;
752 static void bios_shadow_init(PCIDevice *d)
754 int v;
756 if (bios_table_cur_addr == 0)
757 return;
759 /* remap the BIOS to shadow RAM an keep it read/write while we
760 are writing tables */
761 v = pci_config_readb(d, 0x59);
762 v &= 0xcf;
763 pci_config_writeb(d, 0x59, v);
764 memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);
765 v |= 0x30;
766 pci_config_writeb(d, 0x59, v);
767 memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);
769 i440_pcidev = *d;
772 static void bios_lock_shadow_ram(void)
774 PCIDevice *d = &i440_pcidev;
775 int v;
777 wbinvd();
778 v = pci_config_readb(d, 0x59);
779 v = (v & 0x0f) | (0x10);
780 pci_config_writeb(d, 0x59, v);
783 static void pci_bios_init_bridges(PCIDevice *d)
785 uint16_t vendor_id, device_id;
787 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
788 device_id = pci_config_readw(d, PCI_DEVICE_ID);
790 if (vendor_id == PCI_VENDOR_ID_INTEL &&
791 (device_id == PCI_DEVICE_ID_INTEL_82371SB_0 ||
792 device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) {
793 int i, irq;
794 uint8_t elcr[2];
796 /* PIIX3/PIIX4 PCI to ISA bridge */
798 elcr[0] = 0x00;
799 elcr[1] = 0x00;
800 for(i = 0; i < 4; i++) {
801 irq = pci_irqs[i];
802 /* set to trigger level */
803 elcr[irq >> 3] |= (1 << (irq & 7));
804 /* activate irq remapping in PIIX */
805 pci_config_writeb(d, 0x60 + i, irq);
807 outb(0x4d0, elcr[0]);
808 outb(0x4d1, elcr[1]);
809 BX_INFO("PIIX3/PIIX4 init: elcr=%02x %02x\n",
810 elcr[0], elcr[1]);
811 } else if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441) {
812 /* i440 PCI bridge */
813 bios_shadow_init(d);
817 extern uint8_t smm_relocation_start, smm_relocation_end;
818 extern uint8_t smm_code_start, smm_code_end;
820 #ifdef BX_USE_SMM
821 static void smm_init(PCIDevice *d)
823 uint32_t value;
825 /* check if SMM init is already done */
826 value = pci_config_readl(d, 0x58);
827 if ((value & (1 << 25)) == 0) {
829 /* enable the SMM memory window */
830 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x48);
832 /* save original memory content */
833 memcpy((void *)0xa8000, (void *)0x38000, 0x8000);
835 /* copy the SMM relocation code */
836 memcpy((void *)0x38000, &smm_relocation_start,
837 &smm_relocation_end - &smm_relocation_start);
839 /* enable SMI generation when writing to the APMC register */
840 pci_config_writel(d, 0x58, value | (1 << 25));
842 /* init APM status port */
843 outb(0xb3, 0x01);
845 /* raise an SMI interrupt */
846 outb(0xb2, 0x00);
848 /* wait until SMM code executed */
849 while (inb(0xb3) != 0x00);
851 /* restore original memory content */
852 memcpy((void *)0x38000, (void *)0xa8000, 0x8000);
854 /* copy the SMM code */
855 memcpy((void *)0xa8000, &smm_code_start,
856 &smm_code_end - &smm_code_start);
857 wbinvd();
859 /* close the SMM memory window and enable normal SMM */
860 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x08);
863 #endif
865 static void piix4_pm_enable(PCIDevice *d)
867 /* PIIX4 Power Management device (for ACPI) */
868 pci_config_writel(d, 0x40, PM_IO_BASE | 1);
869 pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
870 pci_config_writel(d, 0x90, SMB_IO_BASE | 1);
871 pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
872 #ifdef BX_USE_SMM
873 smm_init(d);
874 #endif
877 static void pci_bios_init_device(PCIDevice *d)
879 int class;
880 uint32_t *paddr;
881 int i, pin, pic_irq, vendor_id, device_id;
883 class = pci_config_readw(d, PCI_CLASS_DEVICE);
884 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
885 device_id = pci_config_readw(d, PCI_DEVICE_ID);
886 BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x class=0x%04x\n",
887 d->bus, d->devfn, vendor_id, device_id, class);
888 switch(class) {
889 case 0x0101: /* Mass storage controller - IDE interface */
890 if (vendor_id == PCI_VENDOR_ID_INTEL &&
891 (device_id == PCI_DEVICE_ID_INTEL_82371SB_1 ||
892 device_id == PCI_DEVICE_ID_INTEL_82371AB)) {
893 /* PIIX3/PIIX4 IDE */
894 pci_config_writew(d, 0x40, 0x8000); // enable IDE0
895 pci_config_writew(d, 0x42, 0x8000); // enable IDE1
896 goto default_map;
897 } else {
898 /* IDE: we map it as in ISA mode */
899 pci_set_io_region_addr(d, 0, 0x1f0);
900 pci_set_io_region_addr(d, 1, 0x3f4);
901 pci_set_io_region_addr(d, 2, 0x170);
902 pci_set_io_region_addr(d, 3, 0x374);
904 break;
905 case 0x0800: /* Generic system peripheral - PIC */
906 if (vendor_id == PCI_VENDOR_ID_IBM) {
907 /* IBM */
908 if (device_id == 0x0046 || device_id == 0xFFFF) {
909 /* MPIC & MPIC2 */
910 pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
913 break;
914 case 0xff00:
915 if (vendor_id == PCI_VENDOR_ID_APPLE &&
916 (device_id == 0x0017 || device_id == 0x0022)) {
917 /* macio bridge */
918 pci_set_io_region_addr(d, 0, 0x80800000);
920 break;
921 default:
922 default_map:
923 /* default memory mappings */
924 for(i = 0; i < PCI_NUM_REGIONS; i++) {
925 int ofs;
926 uint32_t val, size ;
928 if (i == PCI_ROM_SLOT)
929 ofs = 0x30;
930 else
931 ofs = 0x10 + i * 4;
932 pci_config_writel(d, ofs, 0xffffffff);
933 val = pci_config_readl(d, ofs);
934 if (val != 0) {
935 size = (~(val & ~0xf)) + 1;
936 if (val & PCI_ADDRESS_SPACE_IO)
937 paddr = &pci_bios_io_addr;
938 else if (size >= 0x04000000)
939 paddr = &pci_bios_bigmem_addr;
940 else
941 paddr = &pci_bios_mem_addr;
942 *paddr = (*paddr + size - 1) & ~(size - 1);
943 pci_set_io_region_addr(d, i, *paddr);
944 *paddr += size;
947 break;
950 /* map the interrupt */
951 pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
952 if (pin != 0) {
953 pin = pci_slot_get_pirq(d, pin - 1);
954 pic_irq = pci_irqs[pin];
955 pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
958 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3) {
959 /* PIIX4 Power Management device (for ACPI) */
960 pm_io_base = PM_IO_BASE;
961 smb_io_base = SMB_IO_BASE;
962 pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
963 piix4_pm_enable(d);
964 acpi_enabled = 1;
968 void pci_for_each_device(void (*init_func)(PCIDevice *d))
970 PCIDevice d1, *d = &d1;
971 int bus, devfn;
972 uint16_t vendor_id, device_id;
974 for(bus = 0; bus < 1; bus++) {
975 for(devfn = 0; devfn < 256; devfn++) {
976 d->bus = bus;
977 d->devfn = devfn;
978 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
979 device_id = pci_config_readw(d, PCI_DEVICE_ID);
980 if (vendor_id != 0xffff || device_id != 0xffff) {
981 init_func(d);
987 void pci_bios_init(void)
989 pci_bios_io_addr = 0xc000;
990 pci_bios_mem_addr = 0xc0000000;
991 pci_bios_bigmem_addr = ram_size;
992 if (pci_bios_bigmem_addr < 0x90000000)
993 pci_bios_bigmem_addr = 0x90000000;
995 pci_for_each_device(pci_bios_init_bridges);
997 pci_for_each_device(pci_bios_init_device);
1000 /****************************************************/
1001 /* Multi Processor table init */
1003 static void putb(uint8_t **pp, int val)
1005 uint8_t *q;
1006 q = *pp;
1007 *q++ = val;
1008 *pp = q;
1011 static void putstr(uint8_t **pp, const char *str)
1013 uint8_t *q;
1014 q = *pp;
1015 while (*str)
1016 *q++ = *str++;
1017 *pp = q;
1020 static void putle16(uint8_t **pp, int val)
1022 uint8_t *q;
1023 q = *pp;
1024 *q++ = val;
1025 *q++ = val >> 8;
1026 *pp = q;
1029 static void putle32(uint8_t **pp, int val)
1031 uint8_t *q;
1032 q = *pp;
1033 *q++ = val;
1034 *q++ = val >> 8;
1035 *q++ = val >> 16;
1036 *q++ = val >> 24;
1037 *pp = q;
1040 static int mpf_checksum(const uint8_t *data, int len)
1042 int sum, i;
1043 sum = 0;
1044 for(i = 0; i < len; i++)
1045 sum += data[i];
1046 return sum & 0xff;
1049 static unsigned long align(unsigned long addr, unsigned long v)
1051 return (addr + v - 1) & ~(v - 1);
1054 static void mptable_init(void)
1056 uint8_t *mp_config_table, *q, *float_pointer_struct;
1057 int ioapic_id, i, len;
1058 int mp_config_table_size;
1060 #ifdef BX_QEMU
1061 if (smp_cpus <= 1)
1062 return;
1063 #endif
1065 #ifdef BX_USE_EBDA_TABLES
1066 mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
1067 #else
1068 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1069 mp_config_table = (uint8_t *)bios_table_cur_addr;
1070 #endif
1071 q = mp_config_table;
1072 putstr(&q, "PCMP"); /* "PCMP signature */
1073 putle16(&q, 0); /* table length (patched later) */
1074 putb(&q, 4); /* spec rev */
1075 putb(&q, 0); /* checksum (patched later) */
1076 #ifdef BX_QEMU
1077 putstr(&q, "QEMUCPU "); /* OEM id */
1078 #else
1079 putstr(&q, "BOCHSCPU");
1080 #endif
1081 putstr(&q, "0.1 "); /* vendor id */
1082 putle32(&q, 0); /* OEM table ptr */
1083 putle16(&q, 0); /* OEM table size */
1084 putle16(&q, smp_cpus + 18); /* entry count */
1085 putle32(&q, 0xfee00000); /* local APIC addr */
1086 putle16(&q, 0); /* ext table length */
1087 putb(&q, 0); /* ext table checksum */
1088 putb(&q, 0); /* reserved */
1090 for(i = 0; i < smp_cpus; i++) {
1091 putb(&q, 0); /* entry type = processor */
1092 putb(&q, i); /* APIC id */
1093 putb(&q, 0x11); /* local APIC version number */
1094 if (i == 0)
1095 putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
1096 else
1097 putb(&q, 1); /* cpu flags: enabled */
1098 if (cpuid_signature) {
1099 putle32(&q, cpuid_signature);
1100 putle32(&q, cpuid_features);
1101 } else {
1102 putb(&q, 0); /* cpu signature */
1103 putb(&q, 6);
1104 putb(&q, 0);
1105 putb(&q, 0);
1106 putle16(&q, 0x201); /* feature flags */
1107 putle16(&q, 0);
1109 putle16(&q, 0); /* reserved */
1110 putle16(&q, 0);
1111 putle16(&q, 0);
1112 putle16(&q, 0);
1115 /* isa bus */
1116 putb(&q, 1); /* entry type = bus */
1117 putb(&q, 0); /* bus ID */
1118 putstr(&q, "ISA ");
1120 /* ioapic */
1121 ioapic_id = smp_cpus;
1122 putb(&q, 2); /* entry type = I/O APIC */
1123 putb(&q, ioapic_id); /* apic ID */
1124 putb(&q, 0x11); /* I/O APIC version number */
1125 putb(&q, 1); /* enable */
1126 putle32(&q, 0xfec00000); /* I/O APIC addr */
1128 /* irqs */
1129 for(i = 0; i < 16; i++) {
1130 putb(&q, 3); /* entry type = I/O interrupt */
1131 putb(&q, 0); /* interrupt type = vectored interrupt */
1132 putb(&q, 0); /* flags: po=0, el=0 */
1133 putb(&q, 0);
1134 putb(&q, 0); /* source bus ID = ISA */
1135 putb(&q, i); /* source bus IRQ */
1136 putb(&q, ioapic_id); /* dest I/O APIC ID */
1137 putb(&q, i); /* dest I/O APIC interrupt in */
1139 /* patch length */
1140 len = q - mp_config_table;
1141 mp_config_table[4] = len;
1142 mp_config_table[5] = len >> 8;
1144 mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
1146 mp_config_table_size = q - mp_config_table;
1148 #ifndef BX_USE_EBDA_TABLES
1149 bios_table_cur_addr += mp_config_table_size;
1150 #endif
1152 /* floating pointer structure */
1153 #ifdef BX_USE_EBDA_TABLES
1154 ebda_cur_addr = align(ebda_cur_addr, 16);
1155 float_pointer_struct = (uint8_t *)ebda_cur_addr;
1156 #else
1157 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1158 float_pointer_struct = (uint8_t *)bios_table_cur_addr;
1159 #endif
1160 q = float_pointer_struct;
1161 putstr(&q, "_MP_");
1162 /* pointer to MP config table */
1163 putle32(&q, (unsigned long)mp_config_table);
1165 putb(&q, 1); /* length in 16 byte units */
1166 putb(&q, 4); /* MP spec revision */
1167 putb(&q, 0); /* checksum (patched later) */
1168 putb(&q, 0); /* MP feature byte 1 */
1170 putb(&q, 0);
1171 putb(&q, 0);
1172 putb(&q, 0);
1173 putb(&q, 0);
1174 float_pointer_struct[10] =
1175 -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
1176 #ifdef BX_USE_EBDA_TABLES
1177 ebda_cur_addr += (q - float_pointer_struct);
1178 #else
1179 bios_table_cur_addr += (q - float_pointer_struct);
1180 #endif
1181 BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
1182 (unsigned long)float_pointer_struct,
1183 (unsigned long)mp_config_table,
1184 mp_config_table_size);
1187 /****************************************************/
1188 /* ACPI tables init */
1190 /* Table structure from Linux kernel (the ACPI tables are under the
1191 BSD license) */
1194 * All tables must be byte-packed to match the ACPI specification, since
1195 * the tables are provided by the system BIOS.
1198 #define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
1199 uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\
1200 uint32_t length; /* Length of table, in bytes, including header */\
1201 uint8_t revision; /* ACPI Specification minor version # */\
1202 uint8_t checksum; /* To make sum of entire table == 0 */\
1203 uint8_t oem_id [6]; /* OEM identification */\
1204 uint8_t oem_table_id [8]; /* OEM table identification */\
1205 uint32_t oem_revision; /* OEM revision number */\
1206 uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\
1207 uint32_t asl_compiler_revision; /* ASL compiler revision number */
1210 struct acpi_table_header /* ACPI common table header */
1212 ACPI_TABLE_HEADER_DEF
1213 } __attribute__((__packed__));
1215 struct rsdp_descriptor /* Root System Descriptor Pointer */
1217 uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */
1218 uint8_t checksum; /* To make sum of struct == 0 */
1219 uint8_t oem_id [6]; /* OEM identification */
1220 uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */
1221 uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */
1222 uint32_t length; /* XSDT Length in bytes including hdr */
1223 uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */
1224 uint8_t extended_checksum; /* Checksum of entire table */
1225 uint8_t reserved [3]; /* Reserved field must be 0 */
1226 } __attribute__((__packed__));
1229 * ACPI 1.0 Root System Description Table (RSDT)
1231 struct rsdt_descriptor_rev1
1233 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1234 #ifdef BX_QEMU
1235 uint32_t table_offset_entry [4]; /* Array of pointers to other */
1236 #else
1237 uint32_t table_offset_entry [3]; /* Array of pointers to other */
1238 #endif
1239 /* ACPI tables */
1240 } __attribute__((__packed__));
1243 * ACPI 1.0 Firmware ACPI Control Structure (FACS)
1245 struct facs_descriptor_rev1
1247 uint8_t signature[4]; /* ACPI Signature */
1248 uint32_t length; /* Length of structure, in bytes */
1249 uint32_t hardware_signature; /* Hardware configuration signature */
1250 uint32_t firmware_waking_vector; /* ACPI OS waking vector */
1251 uint32_t global_lock; /* Global Lock */
1252 uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */
1253 uint32_t reserved1 : 31; /* Must be 0 */
1254 uint8_t resverved3 [40]; /* Reserved - must be zero */
1255 } __attribute__((__packed__));
1259 * ACPI 1.0 Fixed ACPI Description Table (FADT)
1261 struct fadt_descriptor_rev1
1263 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1264 uint32_t firmware_ctrl; /* Physical address of FACS */
1265 uint32_t dsdt; /* Physical address of DSDT */
1266 uint8_t model; /* System Interrupt Model */
1267 uint8_t reserved1; /* Reserved */
1268 uint16_t sci_int; /* System vector of SCI interrupt */
1269 uint32_t smi_cmd; /* Port address of SMI command port */
1270 uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */
1271 uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */
1272 uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
1273 uint8_t reserved2; /* Reserved - must be zero */
1274 uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
1275 uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
1276 uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
1277 uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
1278 uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
1279 uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
1280 uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
1281 uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
1282 uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
1283 uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
1284 uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
1285 uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
1286 uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
1287 uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
1288 uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */
1289 uint8_t reserved3; /* Reserved */
1290 uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
1291 uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
1292 uint16_t flush_size; /* Size of area read to flush caches */
1293 uint16_t flush_stride; /* Stride used in flushing caches */
1294 uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */
1295 uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */
1296 uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
1297 uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
1298 uint8_t century; /* Index to century in RTC CMOS RAM */
1299 uint8_t reserved4; /* Reserved */
1300 uint8_t reserved4a; /* Reserved */
1301 uint8_t reserved4b; /* Reserved */
1302 #if 0
1303 uint32_t wb_invd : 1; /* The wbinvd instruction works properly */
1304 uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
1305 uint32_t proc_c1 : 1; /* All processors support C1 state */
1306 uint32_t plvl2_up : 1; /* C2 state works on MP system */
1307 uint32_t pwr_button : 1; /* Power button is handled as a generic feature */
1308 uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
1309 uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
1310 uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
1311 uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */
1312 uint32_t reserved5 : 23; /* Reserved - must be zero */
1313 #else
1314 uint32_t flags;
1315 #endif
1316 } __attribute__((__packed__));
1319 * MADT values and structures
1322 /* Values for MADT PCATCompat */
1324 #define DUAL_PIC 0
1325 #define MULTIPLE_APIC 1
1328 /* Master MADT */
1330 struct multiple_apic_table
1332 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1333 uint32_t local_apic_address; /* Physical address of local APIC */
1334 #if 0
1335 uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */
1336 uint32_t reserved1 : 31;
1337 #else
1338 uint32_t flags;
1339 #endif
1340 } __attribute__((__packed__));
1343 /* Values for Type in APIC_HEADER_DEF */
1345 #define APIC_PROCESSOR 0
1346 #define APIC_IO 1
1347 #define APIC_XRUPT_OVERRIDE 2
1348 #define APIC_NMI 3
1349 #define APIC_LOCAL_NMI 4
1350 #define APIC_ADDRESS_OVERRIDE 5
1351 #define APIC_IO_SAPIC 6
1352 #define APIC_LOCAL_SAPIC 7
1353 #define APIC_XRUPT_SOURCE 8
1354 #define APIC_RESERVED 9 /* 9 and greater are reserved */
1357 * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
1359 #define APIC_HEADER_DEF /* Common APIC sub-structure header */\
1360 uint8_t type; \
1361 uint8_t length;
1363 /* Sub-structures for MADT */
1365 struct madt_processor_apic
1367 APIC_HEADER_DEF
1368 uint8_t processor_id; /* ACPI processor id */
1369 uint8_t local_apic_id; /* Processor's local APIC id */
1370 #if 0
1371 uint32_t processor_enabled: 1; /* Processor is usable if set */
1372 uint32_t reserved2 : 31; /* Reserved, must be zero */
1373 #else
1374 uint32_t flags;
1375 #endif
1376 } __attribute__((__packed__));
1378 #ifdef BX_QEMU
1380 * * ACPI 2.0 Generic Address Space definition.
1381 * */
1382 struct acpi_20_generic_address {
1383 uint8_t address_space_id;
1384 uint8_t register_bit_width;
1385 uint8_t register_bit_offset;
1386 uint8_t reserved;
1387 uint64_t address;
1388 } __attribute__((__packed__));
1391 * * HPET Description Table
1392 * */
1393 struct acpi_20_hpet {
1394 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1395 uint32_t timer_block_id;
1396 struct acpi_20_generic_address addr;
1397 uint8_t hpet_number;
1398 uint16_t min_tick;
1399 uint8_t page_protect;
1400 } __attribute__((__packed__));
1401 #define ACPI_HPET_ADDRESS 0xFED00000UL
1402 #endif
1404 struct madt_io_apic
1406 APIC_HEADER_DEF
1407 uint8_t io_apic_id; /* I/O APIC ID */
1408 uint8_t reserved; /* Reserved - must be zero */
1409 uint32_t address; /* APIC physical address */
1410 uint32_t interrupt; /* Global system interrupt where INTI
1411 * lines start */
1412 } __attribute__((__packed__));
1414 #ifdef BX_QEMU
1415 struct madt_int_override
1417 APIC_HEADER_DEF
1418 uint8_t bus; /* Identifies ISA Bus */
1419 uint8_t source; /* Bus-relative interrupt source */
1420 uint32_t gsi; /* GSI that source will signal */
1421 uint16_t flags; /* MPS INTI flags */
1422 } __attribute__((__packed__));
1423 #endif
1425 #include "acpi-dsdt.hex"
1427 static inline uint16_t cpu_to_le16(uint16_t x)
1429 return x;
1432 static inline uint32_t cpu_to_le32(uint32_t x)
1434 return x;
1437 static int acpi_checksum(const uint8_t *data, int len)
1439 int sum, i;
1440 sum = 0;
1441 for(i = 0; i < len; i++)
1442 sum += data[i];
1443 return (-sum) & 0xff;
1446 static void acpi_build_table_header(struct acpi_table_header *h,
1447 char *sig, int len, uint8_t rev)
1449 memcpy(h->signature, sig, 4);
1450 h->length = cpu_to_le32(len);
1451 h->revision = rev;
1452 #ifdef BX_QEMU
1453 memcpy(h->oem_id, "QEMU ", 6);
1454 memcpy(h->oem_table_id, "QEMU", 4);
1455 #else
1456 memcpy(h->oem_id, "BOCHS ", 6);
1457 memcpy(h->oem_table_id, "BXPC", 4);
1458 #endif
1459 memcpy(h->oem_table_id + 4, sig, 4);
1460 h->oem_revision = cpu_to_le32(1);
1461 #ifdef BX_QEMU
1462 memcpy(h->asl_compiler_id, "QEMU", 4);
1463 #else
1464 memcpy(h->asl_compiler_id, "BXPC", 4);
1465 #endif
1466 h->asl_compiler_revision = cpu_to_le32(1);
1467 h->checksum = acpi_checksum((void *)h, len);
1470 int acpi_build_processor_ssdt(uint8_t *ssdt)
1472 uint8_t *ssdt_ptr = ssdt;
1473 int i, length;
1474 int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
1476 ssdt_ptr[9] = 0; // checksum;
1477 ssdt_ptr += sizeof(struct acpi_table_header);
1479 // caluculate the length of processor block and scope block excluding PkgLength
1480 length = 0x0d * acpi_cpus + 4;
1482 // build processor scope header
1483 *(ssdt_ptr++) = 0x10; // ScopeOp
1484 if (length <= 0x3e) {
1485 *(ssdt_ptr++) = length + 1;
1486 } else {
1487 *(ssdt_ptr++) = 0x7F;
1488 *(ssdt_ptr++) = (length + 2) >> 6;
1490 *(ssdt_ptr++) = '_'; // Name
1491 *(ssdt_ptr++) = 'P';
1492 *(ssdt_ptr++) = 'R';
1493 *(ssdt_ptr++) = '_';
1495 // build object for each processor
1496 for(i=0;i<acpi_cpus;i++) {
1497 *(ssdt_ptr++) = 0x5B; // ProcessorOp
1498 *(ssdt_ptr++) = 0x83;
1499 *(ssdt_ptr++) = 0x0B; // Length
1500 *(ssdt_ptr++) = 'C'; // Name (CPUxx)
1501 *(ssdt_ptr++) = 'P';
1502 if ((i & 0xf0) != 0)
1503 *(ssdt_ptr++) = (i >> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa;
1504 else
1505 *(ssdt_ptr++) = 'U';
1506 *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa;
1507 *(ssdt_ptr++) = i;
1508 *(ssdt_ptr++) = 0x10; // Processor block address
1509 *(ssdt_ptr++) = 0xb0;
1510 *(ssdt_ptr++) = 0;
1511 *(ssdt_ptr++) = 0;
1512 *(ssdt_ptr++) = 6; // Processor block length
1515 acpi_build_table_header((struct acpi_table_header *)ssdt,
1516 "SSDT", ssdt_ptr - ssdt, 1);
1518 return ssdt_ptr - ssdt;
1521 /* base_addr must be a multiple of 4KB */
1522 void acpi_bios_init(void)
1524 struct rsdp_descriptor *rsdp;
1525 struct rsdt_descriptor_rev1 *rsdt;
1526 struct fadt_descriptor_rev1 *fadt;
1527 struct facs_descriptor_rev1 *facs;
1528 struct multiple_apic_table *madt;
1529 uint8_t *dsdt, *ssdt;
1530 #ifdef BX_QEMU
1531 struct acpi_20_hpet *hpet;
1532 uint32_t hpet_addr;
1533 #endif
1534 uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
1535 uint32_t acpi_tables_size, madt_addr, madt_size;
1536 int i;
1538 /* reserve memory space for tables */
1539 #ifdef BX_USE_EBDA_TABLES
1540 ebda_cur_addr = align(ebda_cur_addr, 16);
1541 rsdp = (void *)(ebda_cur_addr);
1542 ebda_cur_addr += sizeof(*rsdp);
1543 #else
1544 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1545 rsdp = (void *)(bios_table_cur_addr);
1546 bios_table_cur_addr += sizeof(*rsdp);
1547 #endif
1549 addr = base_addr = ram_size - ACPI_DATA_SIZE;
1550 rsdt_addr = addr;
1551 rsdt = (void *)(addr);
1552 addr += sizeof(*rsdt);
1554 fadt_addr = addr;
1555 fadt = (void *)(addr);
1556 addr += sizeof(*fadt);
1558 /* XXX: FACS should be in RAM */
1559 addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
1560 facs_addr = addr;
1561 facs = (void *)(addr);
1562 addr += sizeof(*facs);
1564 dsdt_addr = addr;
1565 dsdt = (void *)(addr);
1566 addr += sizeof(AmlCode);
1568 ssdt_addr = addr;
1569 ssdt = (void *)(addr);
1570 addr += acpi_build_processor_ssdt(ssdt);
1572 addr = (addr + 7) & ~7;
1573 madt_addr = addr;
1574 madt_size = sizeof(*madt) +
1575 sizeof(struct madt_processor_apic) * smp_cpus +
1576 #ifdef BX_QEMU
1577 sizeof(struct madt_io_apic) + sizeof(struct madt_int_override);
1578 #else
1579 sizeof(struct madt_io_apic);
1580 #endif
1581 madt = (void *)(addr);
1582 addr += madt_size;
1584 #ifdef BX_QEMU
1585 addr = (addr + 7) & ~7;
1586 hpet_addr = addr;
1587 hpet = (void *)(addr);
1588 addr += sizeof(*hpet);
1589 #endif
1591 acpi_tables_size = addr - base_addr;
1593 BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
1594 (unsigned long)rsdp,
1595 (unsigned long)rsdt, acpi_tables_size);
1597 /* RSDP */
1598 memset(rsdp, 0, sizeof(*rsdp));
1599 memcpy(rsdp->signature, "RSD PTR ", 8);
1600 #ifdef BX_QEMU
1601 memcpy(rsdp->oem_id, "QEMU ", 6);
1602 #else
1603 memcpy(rsdp->oem_id, "BOCHS ", 6);
1604 #endif
1605 rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
1606 rsdp->checksum = acpi_checksum((void *)rsdp, 20);
1608 /* RSDT */
1609 memset(rsdt, 0, sizeof(*rsdt));
1610 rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
1611 rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
1612 rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
1613 #ifdef BX_QEMU
1614 rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr);
1615 #endif
1616 acpi_build_table_header((struct acpi_table_header *)rsdt,
1617 "RSDT", sizeof(*rsdt), 1);
1619 /* FADT */
1620 memset(fadt, 0, sizeof(*fadt));
1621 fadt->firmware_ctrl = cpu_to_le32(facs_addr);
1622 fadt->dsdt = cpu_to_le32(dsdt_addr);
1623 fadt->model = 1;
1624 fadt->reserved1 = 0;
1625 fadt->sci_int = cpu_to_le16(pm_sci_int);
1626 fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
1627 fadt->acpi_enable = 0xf1;
1628 fadt->acpi_disable = 0xf0;
1629 fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
1630 fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
1631 fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
1632 fadt->pm1_evt_len = 4;
1633 fadt->pm1_cnt_len = 2;
1634 fadt->pm_tmr_len = 4;
1635 fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
1636 fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
1637 /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
1638 fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
1639 acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
1640 sizeof(*fadt), 1);
1642 /* FACS */
1643 memset(facs, 0, sizeof(*facs));
1644 memcpy(facs->signature, "FACS", 4);
1645 facs->length = cpu_to_le32(sizeof(*facs));
1646 BX_INFO("Firmware waking vector %p\n", &facs->firmware_waking_vector);
1648 /* DSDT */
1649 memcpy(dsdt, AmlCode, sizeof(AmlCode));
1651 /* MADT */
1653 struct madt_processor_apic *apic;
1654 struct madt_io_apic *io_apic;
1655 #ifdef BX_QEMU
1656 struct madt_int_override *int_override;
1657 #endif
1659 memset(madt, 0, madt_size);
1660 madt->local_apic_address = cpu_to_le32(0xfee00000);
1661 madt->flags = cpu_to_le32(1);
1662 apic = (void *)(madt + 1);
1663 for(i=0;i<smp_cpus;i++) {
1664 apic->type = APIC_PROCESSOR;
1665 apic->length = sizeof(*apic);
1666 apic->processor_id = i;
1667 apic->local_apic_id = i;
1668 apic->flags = cpu_to_le32(1);
1669 apic++;
1671 io_apic = (void *)apic;
1672 io_apic->type = APIC_IO;
1673 io_apic->length = sizeof(*io_apic);
1674 io_apic->io_apic_id = smp_cpus;
1675 io_apic->address = cpu_to_le32(0xfec00000);
1676 io_apic->interrupt = cpu_to_le32(0);
1677 #ifdef BX_QEMU
1678 io_apic++;
1680 int_override = (void *)io_apic;
1681 int_override->type = APIC_XRUPT_OVERRIDE;
1682 int_override->length = sizeof(*int_override);
1683 int_override->bus = cpu_to_le32(0);
1684 int_override->source = cpu_to_le32(0);
1685 int_override->gsi = cpu_to_le32(2);
1686 int_override->flags = cpu_to_le32(0);
1687 #endif
1689 acpi_build_table_header((struct acpi_table_header *)madt,
1690 "APIC", madt_size, 1);
1693 #ifdef BX_QEMU
1694 /* HPET */
1695 memset(hpet, 0, sizeof(*hpet));
1696 /* Note timer_block_id value must be kept in sync with value advertised by
1697 * emulated hpet
1699 hpet->timer_block_id = cpu_to_le32(0x8086a201);
1700 hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS);
1701 acpi_build_table_header((struct acpi_table_header *)hpet,
1702 "HPET", sizeof(*hpet), 1);
1703 #endif
1707 /* SMBIOS entry point -- must be written to a 16-bit aligned address
1708 between 0xf0000 and 0xfffff.
1710 struct smbios_entry_point {
1711 char anchor_string[4];
1712 uint8_t checksum;
1713 uint8_t length;
1714 uint8_t smbios_major_version;
1715 uint8_t smbios_minor_version;
1716 uint16_t max_structure_size;
1717 uint8_t entry_point_revision;
1718 uint8_t formatted_area[5];
1719 char intermediate_anchor_string[5];
1720 uint8_t intermediate_checksum;
1721 uint16_t structure_table_length;
1722 uint32_t structure_table_address;
1723 uint16_t number_of_structures;
1724 uint8_t smbios_bcd_revision;
1725 } __attribute__((__packed__));
1727 /* This goes at the beginning of every SMBIOS structure. */
1728 struct smbios_structure_header {
1729 uint8_t type;
1730 uint8_t length;
1731 uint16_t handle;
1732 } __attribute__((__packed__));
1734 /* SMBIOS type 0 - BIOS Information */
1735 struct smbios_type_0 {
1736 struct smbios_structure_header header;
1737 uint8_t vendor_str;
1738 uint8_t bios_version_str;
1739 uint16_t bios_starting_address_segment;
1740 uint8_t bios_release_date_str;
1741 uint8_t bios_rom_size;
1742 uint8_t bios_characteristics[8];
1743 uint8_t bios_characteristics_extension_bytes[2];
1744 uint8_t system_bios_major_release;
1745 uint8_t system_bios_minor_release;
1746 uint8_t embedded_controller_major_release;
1747 uint8_t embedded_controller_minor_release;
1748 } __attribute__((__packed__));
1750 /* SMBIOS type 1 - System Information */
1751 struct smbios_type_1 {
1752 struct smbios_structure_header header;
1753 uint8_t manufacturer_str;
1754 uint8_t product_name_str;
1755 uint8_t version_str;
1756 uint8_t serial_number_str;
1757 uint8_t uuid[16];
1758 uint8_t wake_up_type;
1759 uint8_t sku_number_str;
1760 uint8_t family_str;
1761 } __attribute__((__packed__));
1763 /* SMBIOS type 3 - System Enclosure (v2.3) */
1764 struct smbios_type_3 {
1765 struct smbios_structure_header header;
1766 uint8_t manufacturer_str;
1767 uint8_t type;
1768 uint8_t version_str;
1769 uint8_t serial_number_str;
1770 uint8_t asset_tag_number_str;
1771 uint8_t boot_up_state;
1772 uint8_t power_supply_state;
1773 uint8_t thermal_state;
1774 uint8_t security_status;
1775 uint32_t oem_defined;
1776 uint8_t height;
1777 uint8_t number_of_power_cords;
1778 uint8_t contained_element_count;
1779 // contained elements follow
1780 } __attribute__((__packed__));
1782 /* SMBIOS type 4 - Processor Information (v2.0) */
1783 struct smbios_type_4 {
1784 struct smbios_structure_header header;
1785 uint8_t socket_designation_str;
1786 uint8_t processor_type;
1787 uint8_t processor_family;
1788 uint8_t processor_manufacturer_str;
1789 uint32_t processor_id[2];
1790 uint8_t processor_version_str;
1791 uint8_t voltage;
1792 uint16_t external_clock;
1793 uint16_t max_speed;
1794 uint16_t current_speed;
1795 uint8_t status;
1796 uint8_t processor_upgrade;
1797 uint16_t l1_cache_handle;
1798 uint16_t l2_cache_handle;
1799 uint16_t l3_cache_handle;
1800 } __attribute__((__packed__));
1802 /* SMBIOS type 16 - Physical Memory Array
1803 * Associated with one type 17 (Memory Device).
1805 struct smbios_type_16 {
1806 struct smbios_structure_header header;
1807 uint8_t location;
1808 uint8_t use;
1809 uint8_t error_correction;
1810 uint32_t maximum_capacity;
1811 uint16_t memory_error_information_handle;
1812 uint16_t number_of_memory_devices;
1813 } __attribute__((__packed__));
1815 /* SMBIOS type 17 - Memory Device
1816 * Associated with one type 19
1818 struct smbios_type_17 {
1819 struct smbios_structure_header header;
1820 uint16_t physical_memory_array_handle;
1821 uint16_t memory_error_information_handle;
1822 uint16_t total_width;
1823 uint16_t data_width;
1824 uint16_t size;
1825 uint8_t form_factor;
1826 uint8_t device_set;
1827 uint8_t device_locator_str;
1828 uint8_t bank_locator_str;
1829 uint8_t memory_type;
1830 uint16_t type_detail;
1831 } __attribute__((__packed__));
1833 /* SMBIOS type 19 - Memory Array Mapped Address */
1834 struct smbios_type_19 {
1835 struct smbios_structure_header header;
1836 uint32_t starting_address;
1837 uint32_t ending_address;
1838 uint16_t memory_array_handle;
1839 uint8_t partition_width;
1840 } __attribute__((__packed__));
1842 /* SMBIOS type 20 - Memory Device Mapped Address */
1843 struct smbios_type_20 {
1844 struct smbios_structure_header header;
1845 uint32_t starting_address;
1846 uint32_t ending_address;
1847 uint16_t memory_device_handle;
1848 uint16_t memory_array_mapped_address_handle;
1849 uint8_t partition_row_position;
1850 uint8_t interleave_position;
1851 uint8_t interleaved_data_depth;
1852 } __attribute__((__packed__));
1854 /* SMBIOS type 32 - System Boot Information */
1855 struct smbios_type_32 {
1856 struct smbios_structure_header header;
1857 uint8_t reserved[6];
1858 uint8_t boot_status;
1859 } __attribute__((__packed__));
1861 /* SMBIOS type 127 -- End-of-table */
1862 struct smbios_type_127 {
1863 struct smbios_structure_header header;
1864 } __attribute__((__packed__));
1866 static void
1867 smbios_entry_point_init(void *start,
1868 uint16_t max_structure_size,
1869 uint16_t structure_table_length,
1870 uint32_t structure_table_address,
1871 uint16_t number_of_structures)
1873 uint8_t sum;
1874 int i;
1875 struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
1877 memcpy(ep->anchor_string, "_SM_", 4);
1878 ep->length = 0x1f;
1879 ep->smbios_major_version = 2;
1880 ep->smbios_minor_version = 4;
1881 ep->max_structure_size = max_structure_size;
1882 ep->entry_point_revision = 0;
1883 memset(ep->formatted_area, 0, 5);
1884 memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
1886 ep->structure_table_length = structure_table_length;
1887 ep->structure_table_address = structure_table_address;
1888 ep->number_of_structures = number_of_structures;
1889 ep->smbios_bcd_revision = 0x24;
1891 ep->checksum = 0;
1892 ep->intermediate_checksum = 0;
1894 sum = 0;
1895 for (i = 0; i < 0x10; i++)
1896 sum += ((int8_t *)start)[i];
1897 ep->checksum = -sum;
1899 sum = 0;
1900 for (i = 0x10; i < ep->length; i++)
1901 sum += ((int8_t *)start)[i];
1902 ep->intermediate_checksum = -sum;
1905 /* Type 0 -- BIOS Information */
1906 #define RELEASE_DATE_STR "01/01/2007"
1907 static void *
1908 smbios_type_0_init(void *start)
1910 struct smbios_type_0 *p = (struct smbios_type_0 *)start;
1912 p->header.type = 0;
1913 p->header.length = sizeof(struct smbios_type_0);
1914 p->header.handle = 0;
1916 p->vendor_str = 1;
1917 p->bios_version_str = 1;
1918 p->bios_starting_address_segment = 0xe800;
1919 p->bios_release_date_str = 2;
1920 p->bios_rom_size = 0; /* FIXME */
1922 memset(p->bios_characteristics, 0, 8);
1923 p->bios_characteristics[0] = 0x08; /* BIOS characteristics not supported */
1924 p->bios_characteristics_extension_bytes[0] = 0;
1925 p->bios_characteristics_extension_bytes[1] = 0;
1927 p->system_bios_major_release = 1;
1928 p->system_bios_minor_release = 0;
1929 p->embedded_controller_major_release = 0xff;
1930 p->embedded_controller_minor_release = 0xff;
1932 start += sizeof(struct smbios_type_0);
1933 memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
1934 start += sizeof(BX_APPNAME);
1935 memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
1936 start += sizeof(RELEASE_DATE_STR);
1937 *((uint8_t *)start) = 0;
1939 return start+1;
1942 /* Type 1 -- System Information */
1943 static void *
1944 smbios_type_1_init(void *start)
1946 struct smbios_type_1 *p = (struct smbios_type_1 *)start;
1947 p->header.type = 1;
1948 p->header.length = sizeof(struct smbios_type_1);
1949 p->header.handle = 0x100;
1951 p->manufacturer_str = 0;
1952 p->product_name_str = 0;
1953 p->version_str = 0;
1954 p->serial_number_str = 0;
1956 memcpy(p->uuid, bios_uuid, 16);
1958 p->wake_up_type = 0x06; /* power switch */
1959 p->sku_number_str = 0;
1960 p->family_str = 0;
1962 start += sizeof(struct smbios_type_1);
1963 *((uint16_t *)start) = 0;
1965 return start+2;
1968 /* Type 3 -- System Enclosure */
1969 static void *
1970 smbios_type_3_init(void *start)
1972 struct smbios_type_3 *p = (struct smbios_type_3 *)start;
1974 p->header.type = 3;
1975 p->header.length = sizeof(struct smbios_type_3);
1976 p->header.handle = 0x300;
1978 p->manufacturer_str = 0;
1979 p->type = 0x01; /* other */
1980 p->version_str = 0;
1981 p->serial_number_str = 0;
1982 p->asset_tag_number_str = 0;
1983 p->boot_up_state = 0x03; /* safe */
1984 p->power_supply_state = 0x03; /* safe */
1985 p->thermal_state = 0x03; /* safe */
1986 p->security_status = 0x02; /* unknown */
1987 p->oem_defined = 0;
1988 p->height = 0;
1989 p->number_of_power_cords = 0;
1990 p->contained_element_count = 0;
1992 start += sizeof(struct smbios_type_3);
1993 *((uint16_t *)start) = 0;
1995 return start+2;
1998 /* Type 4 -- Processor Information */
1999 static void *
2000 smbios_type_4_init(void *start, unsigned int cpu_number)
2002 struct smbios_type_4 *p = (struct smbios_type_4 *)start;
2004 p->header.type = 4;
2005 p->header.length = sizeof(struct smbios_type_4);
2006 p->header.handle = 0x400 + cpu_number;
2008 p->socket_designation_str = 1;
2009 p->processor_type = 0x03; /* CPU */
2010 p->processor_family = 0x01; /* other */
2011 p->processor_manufacturer_str = 0;
2013 p->processor_id[0] = cpuid_signature;
2014 p->processor_id[1] = cpuid_features;
2016 p->processor_version_str = 0;
2017 p->voltage = 0;
2018 p->external_clock = 0;
2020 p->max_speed = 0; /* unknown */
2021 p->current_speed = 0; /* unknown */
2023 p->status = 0x41; /* socket populated, CPU enabled */
2024 p->processor_upgrade = 0x01; /* other */
2026 p->l1_cache_handle = 0xffff; /* cache information structure not provided */
2027 p->l2_cache_handle = 0xffff;
2028 p->l3_cache_handle = 0xffff;
2030 start += sizeof(struct smbios_type_4);
2032 memcpy((char *)start, "CPU " "\0" "" "\0" "", 7);
2033 ((char *)start)[4] = cpu_number + '0';
2035 return start+7;
2038 /* Type 16 -- Physical Memory Array */
2039 static void *
2040 smbios_type_16_init(void *start, uint32_t memsize)
2042 struct smbios_type_16 *p = (struct smbios_type_16*)start;
2044 p->header.type = 16;
2045 p->header.length = sizeof(struct smbios_type_16);
2046 p->header.handle = 0x1000;
2048 p->location = 0x01; /* other */
2049 p->use = 0x03; /* system memory */
2050 p->error_correction = 0x01; /* other */
2051 p->maximum_capacity = memsize * 1024;
2052 p->memory_error_information_handle = 0xfffe; /* none provided */
2053 p->number_of_memory_devices = 1;
2055 start += sizeof(struct smbios_type_16);
2056 *((uint16_t *)start) = 0;
2058 return start + 2;
2061 /* Type 17 -- Memory Device */
2062 static void *
2063 smbios_type_17_init(void *start, uint32_t memory_size_mb)
2065 struct smbios_type_17 *p = (struct smbios_type_17 *)start;
2067 p->header.type = 17;
2068 p->header.length = sizeof(struct smbios_type_17);
2069 p->header.handle = 0x1100;
2071 p->physical_memory_array_handle = 0x1000;
2072 p->total_width = 64;
2073 p->data_width = 64;
2074 /* truncate memory_size_mb to 16 bits and clear most significant
2075 bit [indicates size in MB] */
2076 p->size = (uint16_t) memory_size_mb & 0x7fff;
2077 p->form_factor = 0x09; /* DIMM */
2078 p->device_set = 0;
2079 p->device_locator_str = 1;
2080 p->bank_locator_str = 0;
2081 p->memory_type = 0x07; /* RAM */
2082 p->type_detail = 0;
2084 start += sizeof(struct smbios_type_17);
2085 memcpy((char *)start, "DIMM 1", 7);
2086 start += 7;
2087 *((uint8_t *)start) = 0;
2089 return start+1;
2092 /* Type 19 -- Memory Array Mapped Address */
2093 static void *
2094 smbios_type_19_init(void *start, uint32_t memory_size_mb)
2096 struct smbios_type_19 *p = (struct smbios_type_19 *)start;
2098 p->header.type = 19;
2099 p->header.length = sizeof(struct smbios_type_19);
2100 p->header.handle = 0x1300;
2102 p->starting_address = 0;
2103 p->ending_address = (memory_size_mb * 1024) - 1;
2104 p->memory_array_handle = 0x1000;
2105 p->partition_width = 1;
2107 start += sizeof(struct smbios_type_19);
2108 *((uint16_t *)start) = 0;
2110 return start + 2;
2113 /* Type 20 -- Memory Device Mapped Address */
2114 static void *
2115 smbios_type_20_init(void *start, uint32_t memory_size_mb)
2117 struct smbios_type_20 *p = (struct smbios_type_20 *)start;
2119 p->header.type = 20;
2120 p->header.length = sizeof(struct smbios_type_20);
2121 p->header.handle = 0x1400;
2123 p->starting_address = 0;
2124 p->ending_address = (memory_size_mb * 1024) - 1;
2125 p->memory_device_handle = 0x1100;
2126 p->memory_array_mapped_address_handle = 0x1300;
2127 p->partition_row_position = 1;
2128 p->interleave_position = 0;
2129 p->interleaved_data_depth = 0;
2131 start += sizeof(struct smbios_type_20);
2133 *((uint16_t *)start) = 0;
2134 return start+2;
2137 /* Type 32 -- System Boot Information */
2138 static void *
2139 smbios_type_32_init(void *start)
2141 struct smbios_type_32 *p = (struct smbios_type_32 *)start;
2143 p->header.type = 32;
2144 p->header.length = sizeof(struct smbios_type_32);
2145 p->header.handle = 0x2000;
2146 memset(p->reserved, 0, 6);
2147 p->boot_status = 0; /* no errors detected */
2149 start += sizeof(struct smbios_type_32);
2150 *((uint16_t *)start) = 0;
2152 return start+2;
2155 /* Type 127 -- End of Table */
2156 static void *
2157 smbios_type_127_init(void *start)
2159 struct smbios_type_127 *p = (struct smbios_type_127 *)start;
2161 p->header.type = 127;
2162 p->header.length = sizeof(struct smbios_type_127);
2163 p->header.handle = 0x7f00;
2165 start += sizeof(struct smbios_type_127);
2166 *((uint16_t *)start) = 0;
2168 return start + 2;
2171 void smbios_init(void)
2173 unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
2174 char *start, *p, *q;
2175 int memsize = ram_size / (1024 * 1024);
2177 #ifdef BX_USE_EBDA_TABLES
2178 ebda_cur_addr = align(ebda_cur_addr, 16);
2179 start = (void *)(ebda_cur_addr);
2180 #else
2181 bios_table_cur_addr = align(bios_table_cur_addr, 16);
2182 start = (void *)(bios_table_cur_addr);
2183 #endif
2185 p = (char *)start + sizeof(struct smbios_entry_point);
2187 #define add_struct(fn) { \
2188 q = (fn); \
2189 nr_structs++; \
2190 if ((q - p) > max_struct_size) \
2191 max_struct_size = q - p; \
2192 p = q; \
2195 add_struct(smbios_type_0_init(p));
2196 add_struct(smbios_type_1_init(p));
2197 add_struct(smbios_type_3_init(p));
2198 for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
2199 add_struct(smbios_type_4_init(p, cpu_num));
2200 add_struct(smbios_type_16_init(p, memsize));
2201 add_struct(smbios_type_17_init(p, memsize));
2202 add_struct(smbios_type_19_init(p, memsize));
2203 add_struct(smbios_type_20_init(p, memsize));
2204 add_struct(smbios_type_32_init(p));
2205 add_struct(smbios_type_127_init(p));
2207 #undef add_struct
2209 smbios_entry_point_init(
2210 start, max_struct_size,
2211 (p - (char *)start) - sizeof(struct smbios_entry_point),
2212 (uint32_t)(start + sizeof(struct smbios_entry_point)),
2213 nr_structs);
2215 #ifdef BX_USE_EBDA_TABLES
2216 ebda_cur_addr += (p - (char *)start);
2217 #else
2218 bios_table_cur_addr += (p - (char *)start);
2219 #endif
2221 BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
2224 static uint32_t find_resume_vector(void)
2226 unsigned long addr, start, end;
2228 #ifdef BX_USE_EBDA_TABLES
2229 start = align(ebda_cur_addr, 16);
2230 end = 0xa000 << 4;
2231 #else
2232 if (bios_table_cur_addr == 0)
2233 return 0;
2234 start = align(bios_table_cur_addr, 16);
2235 end = bios_table_end_addr;
2236 #endif
2238 for (addr = start; addr < end; addr += 16) {
2239 if (!memcmp((void*)addr, "RSD PTR ", 8)) {
2240 struct rsdp_descriptor *rsdp = (void*)addr;
2241 struct rsdt_descriptor_rev1 *rsdt = (void*)rsdp->rsdt_physical_address;
2242 struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[0];
2243 struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
2244 return facs->firmware_waking_vector;
2248 return 0;
2251 static void find_440fx(PCIDevice *d)
2253 uint16_t vendor_id, device_id;
2255 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
2256 device_id = pci_config_readw(d, PCI_DEVICE_ID);
2258 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441)
2259 i440_pcidev = *d;
2262 static void reinit_piix4_pm(PCIDevice *d)
2264 uint16_t vendor_id, device_id;
2266 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
2267 device_id = pci_config_readw(d, PCI_DEVICE_ID);
2269 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3)
2270 piix4_pm_enable(d);
2273 void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
2275 BX_INFO("Starting rombios32\n");
2276 BX_INFO("Shutdown flag %x\n", *shutdown_flag);
2278 #ifdef BX_QEMU
2279 qemu_cfg_port = qemu_cfg_port_probe();
2280 #endif
2282 ram_probe();
2284 cpu_probe();
2286 setup_mtrr();
2288 smp_probe();
2290 find_bios_table_area();
2292 if (*shutdown_flag == 0xfe) {
2293 /* redirect bios read access to RAM */
2294 pci_for_each_device(find_440fx);
2295 bios_lock_shadow_ram(); /* bios is already copied */
2296 *s3_resume_vector = find_resume_vector();
2297 if (!*s3_resume_vector) {
2298 BX_INFO("This is S3 resume but wakeup vector is NULL\n");
2299 } else {
2300 BX_INFO("S3 resume vector %p\n", *s3_resume_vector);
2301 pci_for_each_device(reinit_piix4_pm);
2303 return;
2306 pci_bios_init();
2308 if (bios_table_cur_addr != 0) {
2310 mptable_init();
2312 uuid_probe();
2314 smbios_init();
2316 if (acpi_enabled)
2317 acpi_bios_init();
2319 bios_lock_shadow_ram();
2321 BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
2322 if (bios_table_cur_addr > bios_table_end_addr)
2323 BX_PANIC("bios_table_end_addr overflow!\n");
2324 #ifdef BX_USE_EBDA_TABLES
2325 BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
2326 if (ebda_cur_addr > 0xA0000)
2327 BX_PANIC("ebda_cur_addr overflow!\n");
2328 #endif