- the HPET merge from QEMU introduced new structures which need packing (Sebastian...
[gplbios.git] / rombios32.c
blob1bfbff1a7bb1a083fc29ca01708ce172eb975be2
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_APIC (1 << 9)
52 #define APIC_BASE ((uint8_t *)0xfee00000)
53 #define APIC_ICR_LOW 0x300
54 #define APIC_SVR 0x0F0
55 #define APIC_ID 0x020
56 #define APIC_LVT3 0x370
58 #define APIC_ENABLED 0x0100
60 #define AP_BOOT_ADDR 0x9f000
62 #define MPTABLE_MAX_SIZE 0x00002000
63 #define SMI_CMD_IO_ADDR 0xb2
65 #define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */
67 static inline void outl(int addr, int val)
69 asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val));
72 static inline void outw(int addr, int val)
74 asm volatile ("outw %w1, %w0" : : "d" (addr), "a" (val));
77 static inline void outb(int addr, int val)
79 asm volatile ("outb %b1, %w0" : : "d" (addr), "a" (val));
82 static inline uint32_t inl(int addr)
84 uint32_t val;
85 asm volatile ("inl %w1, %0" : "=a" (val) : "d" (addr));
86 return val;
89 static inline uint16_t inw(int addr)
91 uint16_t val;
92 asm volatile ("inw %w1, %w0" : "=a" (val) : "d" (addr));
93 return val;
96 static inline uint8_t inb(int addr)
98 uint8_t val;
99 asm volatile ("inb %w1, %b0" : "=a" (val) : "d" (addr));
100 return val;
103 static inline void writel(void *addr, uint32_t val)
105 *(volatile uint32_t *)addr = val;
108 static inline void writew(void *addr, uint16_t val)
110 *(volatile uint16_t *)addr = val;
113 static inline void writeb(void *addr, uint8_t val)
115 *(volatile uint8_t *)addr = val;
118 static inline uint32_t readl(const void *addr)
120 return *(volatile const uint32_t *)addr;
123 static inline uint16_t readw(const void *addr)
125 return *(volatile const uint16_t *)addr;
128 static inline uint8_t readb(const void *addr)
130 return *(volatile const uint8_t *)addr;
133 static inline void putc(int c)
135 outb(INFO_PORT, c);
138 static inline int isdigit(int c)
140 return c >= '0' && c <= '9';
143 void *memset(void *d1, int val, size_t len)
145 uint8_t *d = d1;
147 while (len--) {
148 *d++ = val;
150 return d1;
153 void *memcpy(void *d1, const void *s1, size_t len)
155 uint8_t *d = d1;
156 const uint8_t *s = s1;
158 while (len--) {
159 *d++ = *s++;
161 return d1;
164 void *memmove(void *d1, const void *s1, size_t len)
166 uint8_t *d = d1;
167 const uint8_t *s = s1;
169 if (d <= s) {
170 while (len--) {
171 *d++ = *s++;
173 } else {
174 d += len;
175 s += len;
176 while (len--) {
177 *--d = *--s;
180 return d1;
183 int memcmp(const void *s1, const void *s2, size_t len)
185 const int8_t *p1 = s1;
186 const int8_t *p2 = s2;
188 while (len--) {
189 int r = *p1++ - *p2++;
190 if(r)
191 return r;
194 return 0;
197 size_t strlen(const char *s)
199 const char *s1;
200 for(s1 = s; *s1 != '\0'; s1++);
201 return s1 - s;
204 /* from BSD ppp sources */
205 int vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
207 int c, i, n;
208 int width, prec, fillch;
209 int base, len, neg;
210 unsigned long val = 0;
211 const char *f;
212 char *str, *buf0;
213 char num[32];
214 static const char hexchars[] = "0123456789abcdef";
216 buf0 = buf;
217 --buflen;
218 while (buflen > 0) {
219 for (f = fmt; *f != '%' && *f != 0; ++f)
221 if (f > fmt) {
222 len = f - fmt;
223 if (len > buflen)
224 len = buflen;
225 memcpy(buf, fmt, len);
226 buf += len;
227 buflen -= len;
228 fmt = f;
230 if (*fmt == 0)
231 break;
232 c = *++fmt;
233 width = prec = 0;
234 fillch = ' ';
235 if (c == '0') {
236 fillch = '0';
237 c = *++fmt;
239 if (c == '*') {
240 width = va_arg(args, int);
241 c = *++fmt;
242 } else {
243 while (isdigit(c)) {
244 width = width * 10 + c - '0';
245 c = *++fmt;
248 if (c == '.') {
249 c = *++fmt;
250 if (c == '*') {
251 prec = va_arg(args, int);
252 c = *++fmt;
253 } else {
254 while (isdigit(c)) {
255 prec = prec * 10 + c - '0';
256 c = *++fmt;
260 /* modifiers */
261 switch(c) {
262 case 'l':
263 c = *++fmt;
264 break;
265 default:
266 break;
268 str = 0;
269 base = 0;
270 neg = 0;
271 ++fmt;
272 switch (c) {
273 case 'd':
274 i = va_arg(args, int);
275 if (i < 0) {
276 neg = 1;
277 val = -i;
278 } else
279 val = i;
280 base = 10;
281 break;
282 case 'o':
283 val = va_arg(args, unsigned int);
284 base = 8;
285 break;
286 case 'x':
287 case 'X':
288 val = va_arg(args, unsigned int);
289 base = 16;
290 break;
291 case 'p':
292 val = (unsigned long) va_arg(args, void *);
293 base = 16;
294 neg = 2;
295 break;
296 case 's':
297 str = va_arg(args, char *);
298 break;
299 case 'c':
300 num[0] = va_arg(args, int);
301 num[1] = 0;
302 str = num;
303 break;
304 default:
305 *buf++ = '%';
306 if (c != '%')
307 --fmt; /* so %z outputs %z etc. */
308 --buflen;
309 continue;
311 if (base != 0) {
312 str = num + sizeof(num);
313 *--str = 0;
314 while (str > num + neg) {
315 *--str = hexchars[val % base];
316 val = val / base;
317 if (--prec <= 0 && val == 0)
318 break;
320 switch (neg) {
321 case 1:
322 *--str = '-';
323 break;
324 case 2:
325 *--str = 'x';
326 *--str = '0';
327 break;
329 len = num + sizeof(num) - 1 - str;
330 } else {
331 len = strlen(str);
332 if (prec > 0 && len > prec)
333 len = prec;
335 if (width > 0) {
336 if (width > buflen)
337 width = buflen;
338 if ((n = width - len) > 0) {
339 buflen -= n;
340 for (; n > 0; --n)
341 *buf++ = fillch;
344 if (len > buflen)
345 len = buflen;
346 memcpy(buf, str, len);
347 buf += len;
348 buflen -= len;
350 *buf = 0;
351 return buf - buf0;
354 void bios_printf(int flags, const char *fmt, ...)
356 va_list ap;
357 char buf[1024];
358 const char *s;
360 if ((flags & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT)
361 outb(PANIC_PORT2, 0x00);
363 va_start(ap, fmt);
364 vsnprintf(buf, sizeof(buf), fmt, ap);
365 s = buf;
366 while (*s)
367 putc(*s++);
368 va_end(ap);
371 void delay_ms(int n)
373 int i, j;
374 for(i = 0; i < n; i++) {
375 #ifdef BX_QEMU
376 /* approximative ! */
377 for(j = 0; j < 1000000; j++);
378 #else
380 int r1, r2;
381 j = 66;
382 r1 = inb(0x61) & 0x10;
383 do {
384 r2 = inb(0x61) & 0x10;
385 if (r1 != r2) {
386 j--;
387 r1 = r2;
389 } while (j > 0);
391 #endif
395 uint16_t smp_cpus;
396 uint32_t cpuid_signature;
397 uint32_t cpuid_features;
398 uint32_t cpuid_ext_features;
399 unsigned long ram_size;
400 uint8_t bios_uuid[16];
401 #ifdef BX_USE_EBDA_TABLES
402 unsigned long ebda_cur_addr;
403 #endif
404 int acpi_enabled;
405 uint32_t pm_io_base, smb_io_base;
406 int pm_sci_int;
407 unsigned long bios_table_cur_addr;
408 unsigned long bios_table_end_addr;
410 #ifdef BX_QEMU
411 #define QEMU_CFG_CTL_PORT 0x510
412 #define QEMU_CFG_DATA_PORT 0x511
413 #define QEMU_CFG_SIGNATURE 0x00
414 #define QEMU_CFG_ID 0x01
415 #define QEMU_CFG_UUID 0x02
417 int qemu_cfg_port;
419 void qemu_cfg_select(int f)
421 outw(QEMU_CFG_CTL_PORT, f);
424 int qemu_cfg_port_probe()
426 char *sig = "QEMU";
427 int i;
429 qemu_cfg_select(QEMU_CFG_SIGNATURE);
431 for (i = 0; i < 4; i++)
432 if (inb(QEMU_CFG_DATA_PORT) != sig[i])
433 return 0;
435 return 1;
438 void qemu_cfg_read(uint8_t *buf, int len)
440 while (len--)
441 *(buf++) = inb(QEMU_CFG_DATA_PORT);
443 #endif
445 void uuid_probe(void)
447 #ifdef BX_QEMU
448 if(qemu_cfg_port) {
449 qemu_cfg_select(QEMU_CFG_UUID);
450 qemu_cfg_read(bios_uuid, 16);
451 return;
453 #endif
454 memset(bios_uuid, 0, 16);
457 void cpu_probe(void)
459 uint32_t eax, ebx, ecx, edx;
460 cpuid(1, eax, ebx, ecx, edx);
461 cpuid_signature = eax;
462 cpuid_features = edx;
463 cpuid_ext_features = ecx;
466 static int cmos_readb(int addr)
468 outb(0x70, addr);
469 return inb(0x71);
472 void ram_probe(void)
474 if (cmos_readb(0x34) | cmos_readb(0x35))
475 ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 +
476 16 * 1024 * 1024;
477 else
478 ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 +
479 1 * 1024 * 1024;
480 BX_INFO("ram_size=0x%08lx\n", ram_size);
481 #ifdef BX_USE_EBDA_TABLES
482 ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
483 BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
484 #endif
487 /****************************************************/
488 /* SMP probe */
490 extern uint8_t smp_ap_boot_code_start;
491 extern uint8_t smp_ap_boot_code_end;
493 /* find the number of CPUs by launching a SIPI to them */
494 void smp_probe(void)
496 uint32_t val, sipi_vector;
498 writew(&smp_cpus, 1);
499 if (cpuid_features & CPUID_APIC) {
501 /* enable local APIC */
502 val = readl(APIC_BASE + APIC_SVR);
503 val |= APIC_ENABLED;
504 writel(APIC_BASE + APIC_SVR, val);
506 /* copy AP boot code */
507 memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start,
508 &smp_ap_boot_code_end - &smp_ap_boot_code_start);
510 /* broadcast SIPI */
511 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500);
512 sipi_vector = AP_BOOT_ADDR >> 12;
513 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector);
515 #ifndef BX_QEMU
516 delay_ms(10);
517 #else
518 while (cmos_readb(0x5f) + 1 != readw(&smp_cpus))
520 #endif
522 BX_INFO("Found %d cpu(s)\n", readw(&smp_cpus));
525 /****************************************************/
526 /* PCI init */
528 #define PCI_ADDRESS_SPACE_MEM 0x00
529 #define PCI_ADDRESS_SPACE_IO 0x01
530 #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
532 #define PCI_ROM_SLOT 6
533 #define PCI_NUM_REGIONS 7
535 #define PCI_DEVICES_MAX 64
537 #define PCI_VENDOR_ID 0x00 /* 16 bits */
538 #define PCI_DEVICE_ID 0x02 /* 16 bits */
539 #define PCI_COMMAND 0x04 /* 16 bits */
540 #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
541 #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
542 #define PCI_CLASS_DEVICE 0x0a /* Device class */
543 #define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
544 #define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
545 #define PCI_MIN_GNT 0x3e /* 8 bits */
546 #define PCI_MAX_LAT 0x3f /* 8 bits */
548 #define PCI_VENDOR_ID_INTEL 0x8086
549 #define PCI_DEVICE_ID_INTEL_82441 0x1237
550 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
551 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
552 #define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
553 #define PCI_DEVICE_ID_INTEL_82371AB 0x7111
554 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
556 #define PCI_VENDOR_ID_IBM 0x1014
557 #define PCI_VENDOR_ID_APPLE 0x106b
559 typedef struct PCIDevice {
560 int bus;
561 int devfn;
562 } PCIDevice;
564 static uint32_t pci_bios_io_addr;
565 static uint32_t pci_bios_mem_addr;
566 static uint32_t pci_bios_bigmem_addr;
567 /* host irqs corresponding to PCI irqs A-D */
568 static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
569 static PCIDevice i440_pcidev;
571 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
573 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
574 outl(0xcfc, val);
577 static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
579 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
580 outw(0xcfc + (addr & 2), val);
583 static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
585 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
586 outb(0xcfc + (addr & 3), val);
589 static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
591 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
592 return inl(0xcfc);
595 static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
597 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
598 return inw(0xcfc + (addr & 2));
601 static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
603 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
604 return inb(0xcfc + (addr & 3));
607 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
609 uint16_t cmd;
610 uint32_t ofs, old_addr;
612 if ( region_num == PCI_ROM_SLOT ) {
613 ofs = 0x30;
614 }else{
615 ofs = 0x10 + region_num * 4;
618 old_addr = pci_config_readl(d, ofs);
620 pci_config_writel(d, ofs, addr);
621 BX_INFO("region %d: 0x%08x\n", region_num, addr);
623 /* enable memory mappings */
624 cmd = pci_config_readw(d, PCI_COMMAND);
625 if ( region_num == PCI_ROM_SLOT )
626 cmd |= 2;
627 else if (old_addr & PCI_ADDRESS_SPACE_IO)
628 cmd |= 1;
629 else
630 cmd |= 2;
631 pci_config_writew(d, PCI_COMMAND, cmd);
634 /* return the global irq number corresponding to a given device irq
635 pin. We could also use the bus number to have a more precise
636 mapping. */
637 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
639 int slot_addend;
640 slot_addend = (pci_dev->devfn >> 3) - 1;
641 return (irq_num + slot_addend) & 3;
644 static void find_bios_table_area(void)
646 unsigned long addr;
647 for(addr = 0xf0000; addr < 0x100000; addr += 16) {
648 if (*(uint32_t *)addr == 0xaafb4442) {
649 bios_table_cur_addr = addr + 8;
650 bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
651 BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
652 bios_table_cur_addr, bios_table_end_addr);
653 return;
656 return;
659 static void bios_shadow_init(PCIDevice *d)
661 int v;
663 if (bios_table_cur_addr == 0)
664 return;
666 /* remap the BIOS to shadow RAM an keep it read/write while we
667 are writing tables */
668 v = pci_config_readb(d, 0x59);
669 v &= 0xcf;
670 pci_config_writeb(d, 0x59, v);
671 memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);
672 v |= 0x30;
673 pci_config_writeb(d, 0x59, v);
674 memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);
676 i440_pcidev = *d;
679 static void bios_lock_shadow_ram(void)
681 PCIDevice *d = &i440_pcidev;
682 int v;
684 wbinvd();
685 v = pci_config_readb(d, 0x59);
686 v = (v & 0x0f) | (0x10);
687 pci_config_writeb(d, 0x59, v);
690 static void pci_bios_init_bridges(PCIDevice *d)
692 uint16_t vendor_id, device_id;
694 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
695 device_id = pci_config_readw(d, PCI_DEVICE_ID);
697 if (vendor_id == PCI_VENDOR_ID_INTEL &&
698 (device_id == PCI_DEVICE_ID_INTEL_82371SB_0 ||
699 device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) {
700 int i, irq;
701 uint8_t elcr[2];
703 /* PIIX3/PIIX4 PCI to ISA bridge */
705 elcr[0] = 0x00;
706 elcr[1] = 0x00;
707 for(i = 0; i < 4; i++) {
708 irq = pci_irqs[i];
709 /* set to trigger level */
710 elcr[irq >> 3] |= (1 << (irq & 7));
711 /* activate irq remapping in PIIX */
712 pci_config_writeb(d, 0x60 + i, irq);
714 outb(0x4d0, elcr[0]);
715 outb(0x4d1, elcr[1]);
716 BX_INFO("PIIX3/PIIX4 init: elcr=%02x %02x\n",
717 elcr[0], elcr[1]);
718 } else if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441) {
719 /* i440 PCI bridge */
720 bios_shadow_init(d);
724 extern uint8_t smm_relocation_start, smm_relocation_end;
725 extern uint8_t smm_code_start, smm_code_end;
727 #ifdef BX_USE_SMM
728 static void smm_init(PCIDevice *d)
730 uint32_t value;
732 /* check if SMM init is already done */
733 value = pci_config_readl(d, 0x58);
734 if ((value & (1 << 25)) == 0) {
736 /* enable the SMM memory window */
737 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x48);
739 /* save original memory content */
740 memcpy((void *)0xa8000, (void *)0x38000, 0x8000);
742 /* copy the SMM relocation code */
743 memcpy((void *)0x38000, &smm_relocation_start,
744 &smm_relocation_end - &smm_relocation_start);
746 /* enable SMI generation when writing to the APMC register */
747 pci_config_writel(d, 0x58, value | (1 << 25));
749 /* init APM status port */
750 outb(0xb3, 0x01);
752 /* raise an SMI interrupt */
753 outb(0xb2, 0x00);
755 /* wait until SMM code executed */
756 while (inb(0xb3) != 0x00);
758 /* restore original memory content */
759 memcpy((void *)0x38000, (void *)0xa8000, 0x8000);
761 /* copy the SMM code */
762 memcpy((void *)0xa8000, &smm_code_start,
763 &smm_code_end - &smm_code_start);
764 wbinvd();
766 /* close the SMM memory window and enable normal SMM */
767 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x08);
770 #endif
772 static void piix4_pm_enable(PCIDevice *d)
774 /* PIIX4 Power Management device (for ACPI) */
775 pci_config_writel(d, 0x40, PM_IO_BASE | 1);
776 pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
777 pci_config_writel(d, 0x90, SMB_IO_BASE | 1);
778 pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
779 #ifdef BX_USE_SMM
780 smm_init(d);
781 #endif
784 static void pci_bios_init_device(PCIDevice *d)
786 int class;
787 uint32_t *paddr;
788 int i, pin, pic_irq, vendor_id, device_id;
790 class = pci_config_readw(d, PCI_CLASS_DEVICE);
791 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
792 device_id = pci_config_readw(d, PCI_DEVICE_ID);
793 BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x class=0x%04x\n",
794 d->bus, d->devfn, vendor_id, device_id, class);
795 switch(class) {
796 case 0x0101: /* Mass storage controller - IDE interface */
797 if (vendor_id == PCI_VENDOR_ID_INTEL &&
798 (device_id == PCI_DEVICE_ID_INTEL_82371SB_1 ||
799 device_id == PCI_DEVICE_ID_INTEL_82371AB)) {
800 /* PIIX3/PIIX4 IDE */
801 pci_config_writew(d, 0x40, 0x8000); // enable IDE0
802 pci_config_writew(d, 0x42, 0x8000); // enable IDE1
803 goto default_map;
804 } else {
805 /* IDE: we map it as in ISA mode */
806 pci_set_io_region_addr(d, 0, 0x1f0);
807 pci_set_io_region_addr(d, 1, 0x3f4);
808 pci_set_io_region_addr(d, 2, 0x170);
809 pci_set_io_region_addr(d, 3, 0x374);
811 break;
812 case 0x0300: /* Display controller - VGA compatible controller */
813 if (vendor_id != 0x1234)
814 goto default_map;
815 /* VGA: map frame buffer to default Bochs VBE address */
816 pci_set_io_region_addr(d, 0, 0xE0000000);
817 break;
818 case 0x0800: /* Generic system peripheral - PIC */
819 if (vendor_id == PCI_VENDOR_ID_IBM) {
820 /* IBM */
821 if (device_id == 0x0046 || device_id == 0xFFFF) {
822 /* MPIC & MPIC2 */
823 pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
826 break;
827 case 0xff00:
828 if (vendor_id == PCI_VENDOR_ID_APPLE &&
829 (device_id == 0x0017 || device_id == 0x0022)) {
830 /* macio bridge */
831 pci_set_io_region_addr(d, 0, 0x80800000);
833 break;
834 default:
835 default_map:
836 /* default memory mappings */
837 for(i = 0; i < PCI_NUM_REGIONS; i++) {
838 int ofs;
839 uint32_t val, size ;
841 if (i == PCI_ROM_SLOT)
842 ofs = 0x30;
843 else
844 ofs = 0x10 + i * 4;
845 pci_config_writel(d, ofs, 0xffffffff);
846 val = pci_config_readl(d, ofs);
847 if (val != 0) {
848 size = (~(val & ~0xf)) + 1;
849 if (val & PCI_ADDRESS_SPACE_IO)
850 paddr = &pci_bios_io_addr;
851 else if (size >= 0x04000000)
852 paddr = &pci_bios_bigmem_addr;
853 else
854 paddr = &pci_bios_mem_addr;
855 *paddr = (*paddr + size - 1) & ~(size - 1);
856 pci_set_io_region_addr(d, i, *paddr);
857 *paddr += size;
860 break;
863 /* map the interrupt */
864 pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
865 if (pin != 0) {
866 pin = pci_slot_get_pirq(d, pin - 1);
867 pic_irq = pci_irqs[pin];
868 pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
871 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3) {
872 /* PIIX4 Power Management device (for ACPI) */
873 pm_io_base = PM_IO_BASE;
874 smb_io_base = SMB_IO_BASE;
875 pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
876 piix4_pm_enable(d);
877 acpi_enabled = 1;
881 void pci_for_each_device(void (*init_func)(PCIDevice *d))
883 PCIDevice d1, *d = &d1;
884 int bus, devfn;
885 uint16_t vendor_id, device_id;
887 for(bus = 0; bus < 1; bus++) {
888 for(devfn = 0; devfn < 256; devfn++) {
889 d->bus = bus;
890 d->devfn = devfn;
891 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
892 device_id = pci_config_readw(d, PCI_DEVICE_ID);
893 if (vendor_id != 0xffff || device_id != 0xffff) {
894 init_func(d);
900 void pci_bios_init(void)
902 pci_bios_io_addr = 0xc000;
903 pci_bios_mem_addr = 0xf0000000;
904 pci_bios_bigmem_addr = ram_size;
905 if (pci_bios_bigmem_addr < 0x90000000)
906 pci_bios_bigmem_addr = 0x90000000;
908 pci_for_each_device(pci_bios_init_bridges);
910 pci_for_each_device(pci_bios_init_device);
913 /****************************************************/
914 /* Multi Processor table init */
916 static void putb(uint8_t **pp, int val)
918 uint8_t *q;
919 q = *pp;
920 *q++ = val;
921 *pp = q;
924 static void putstr(uint8_t **pp, const char *str)
926 uint8_t *q;
927 q = *pp;
928 while (*str)
929 *q++ = *str++;
930 *pp = q;
933 static void putle16(uint8_t **pp, int val)
935 uint8_t *q;
936 q = *pp;
937 *q++ = val;
938 *q++ = val >> 8;
939 *pp = q;
942 static void putle32(uint8_t **pp, int val)
944 uint8_t *q;
945 q = *pp;
946 *q++ = val;
947 *q++ = val >> 8;
948 *q++ = val >> 16;
949 *q++ = val >> 24;
950 *pp = q;
953 static int mpf_checksum(const uint8_t *data, int len)
955 int sum, i;
956 sum = 0;
957 for(i = 0; i < len; i++)
958 sum += data[i];
959 return sum & 0xff;
962 static unsigned long align(unsigned long addr, unsigned long v)
964 return (addr + v - 1) & ~(v - 1);
967 static void mptable_init(void)
969 uint8_t *mp_config_table, *q, *float_pointer_struct;
970 int ioapic_id, i, len;
971 int mp_config_table_size;
973 #ifdef BX_QEMU
974 if (smp_cpus <= 1)
975 return;
976 #endif
978 #ifdef BX_USE_EBDA_TABLES
979 mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
980 #else
981 bios_table_cur_addr = align(bios_table_cur_addr, 16);
982 mp_config_table = (uint8_t *)bios_table_cur_addr;
983 #endif
984 q = mp_config_table;
985 putstr(&q, "PCMP"); /* "PCMP signature */
986 putle16(&q, 0); /* table length (patched later) */
987 putb(&q, 4); /* spec rev */
988 putb(&q, 0); /* checksum (patched later) */
989 #ifdef BX_QEMU
990 putstr(&q, "QEMUCPU "); /* OEM id */
991 #else
992 putstr(&q, "BOCHSCPU");
993 #endif
994 putstr(&q, "0.1 "); /* vendor id */
995 putle32(&q, 0); /* OEM table ptr */
996 putle16(&q, 0); /* OEM table size */
997 putle16(&q, smp_cpus + 18); /* entry count */
998 putle32(&q, 0xfee00000); /* local APIC addr */
999 putle16(&q, 0); /* ext table length */
1000 putb(&q, 0); /* ext table checksum */
1001 putb(&q, 0); /* reserved */
1003 for(i = 0; i < smp_cpus; i++) {
1004 putb(&q, 0); /* entry type = processor */
1005 putb(&q, i); /* APIC id */
1006 putb(&q, 0x11); /* local APIC version number */
1007 if (i == 0)
1008 putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
1009 else
1010 putb(&q, 1); /* cpu flags: enabled */
1011 putb(&q, 0); /* cpu signature */
1012 putb(&q, 6);
1013 putb(&q, 0);
1014 putb(&q, 0);
1015 putle16(&q, 0x201); /* feature flags */
1016 putle16(&q, 0);
1018 putle16(&q, 0); /* reserved */
1019 putle16(&q, 0);
1020 putle16(&q, 0);
1021 putle16(&q, 0);
1024 /* isa bus */
1025 putb(&q, 1); /* entry type = bus */
1026 putb(&q, 0); /* bus ID */
1027 putstr(&q, "ISA ");
1029 /* ioapic */
1030 ioapic_id = smp_cpus;
1031 putb(&q, 2); /* entry type = I/O APIC */
1032 putb(&q, ioapic_id); /* apic ID */
1033 putb(&q, 0x11); /* I/O APIC version number */
1034 putb(&q, 1); /* enable */
1035 putle32(&q, 0xfec00000); /* I/O APIC addr */
1037 /* irqs */
1038 for(i = 0; i < 16; i++) {
1039 putb(&q, 3); /* entry type = I/O interrupt */
1040 putb(&q, 0); /* interrupt type = vectored interrupt */
1041 putb(&q, 0); /* flags: po=0, el=0 */
1042 putb(&q, 0);
1043 putb(&q, 0); /* source bus ID = ISA */
1044 putb(&q, i); /* source bus IRQ */
1045 putb(&q, ioapic_id); /* dest I/O APIC ID */
1046 putb(&q, i); /* dest I/O APIC interrupt in */
1048 /* patch length */
1049 len = q - mp_config_table;
1050 mp_config_table[4] = len;
1051 mp_config_table[5] = len >> 8;
1053 mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
1055 mp_config_table_size = q - mp_config_table;
1057 #ifndef BX_USE_EBDA_TABLES
1058 bios_table_cur_addr += mp_config_table_size;
1059 #endif
1061 /* floating pointer structure */
1062 #ifdef BX_USE_EBDA_TABLES
1063 ebda_cur_addr = align(ebda_cur_addr, 16);
1064 float_pointer_struct = (uint8_t *)ebda_cur_addr;
1065 #else
1066 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1067 float_pointer_struct = (uint8_t *)bios_table_cur_addr;
1068 #endif
1069 q = float_pointer_struct;
1070 putstr(&q, "_MP_");
1071 /* pointer to MP config table */
1072 putle32(&q, (unsigned long)mp_config_table);
1074 putb(&q, 1); /* length in 16 byte units */
1075 putb(&q, 4); /* MP spec revision */
1076 putb(&q, 0); /* checksum (patched later) */
1077 putb(&q, 0); /* MP feature byte 1 */
1079 putb(&q, 0);
1080 putb(&q, 0);
1081 putb(&q, 0);
1082 putb(&q, 0);
1083 float_pointer_struct[10] =
1084 -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
1085 #ifdef BX_USE_EBDA_TABLES
1086 ebda_cur_addr += (q - float_pointer_struct);
1087 #else
1088 bios_table_cur_addr += (q - float_pointer_struct);
1089 #endif
1090 BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
1091 (unsigned long)float_pointer_struct,
1092 (unsigned long)mp_config_table,
1093 mp_config_table_size);
1096 /****************************************************/
1097 /* ACPI tables init */
1099 /* Table structure from Linux kernel (the ACPI tables are under the
1100 BSD license) */
1103 * All tables must be byte-packed to match the ACPI specification, since
1104 * the tables are provided by the system BIOS.
1107 #define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
1108 uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\
1109 uint32_t length; /* Length of table, in bytes, including header */\
1110 uint8_t revision; /* ACPI Specification minor version # */\
1111 uint8_t checksum; /* To make sum of entire table == 0 */\
1112 uint8_t oem_id [6]; /* OEM identification */\
1113 uint8_t oem_table_id [8]; /* OEM table identification */\
1114 uint32_t oem_revision; /* OEM revision number */\
1115 uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\
1116 uint32_t asl_compiler_revision; /* ASL compiler revision number */
1119 struct acpi_table_header /* ACPI common table header */
1121 ACPI_TABLE_HEADER_DEF
1122 } __attribute__((__packed__));
1124 struct rsdp_descriptor /* Root System Descriptor Pointer */
1126 uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */
1127 uint8_t checksum; /* To make sum of struct == 0 */
1128 uint8_t oem_id [6]; /* OEM identification */
1129 uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */
1130 uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */
1131 uint32_t length; /* XSDT Length in bytes including hdr */
1132 uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */
1133 uint8_t extended_checksum; /* Checksum of entire table */
1134 uint8_t reserved [3]; /* Reserved field must be 0 */
1135 } __attribute__((__packed__));
1138 * ACPI 1.0 Root System Description Table (RSDT)
1140 struct rsdt_descriptor_rev1
1142 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1143 #ifdef BX_QEMU
1144 uint32_t table_offset_entry [4]; /* Array of pointers to other */
1145 #else
1146 uint32_t table_offset_entry [3]; /* Array of pointers to other */
1147 #endif
1148 /* ACPI tables */
1149 } __attribute__((__packed__));
1152 * ACPI 1.0 Firmware ACPI Control Structure (FACS)
1154 struct facs_descriptor_rev1
1156 uint8_t signature[4]; /* ACPI Signature */
1157 uint32_t length; /* Length of structure, in bytes */
1158 uint32_t hardware_signature; /* Hardware configuration signature */
1159 uint32_t firmware_waking_vector; /* ACPI OS waking vector */
1160 uint32_t global_lock; /* Global Lock */
1161 uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */
1162 uint32_t reserved1 : 31; /* Must be 0 */
1163 uint8_t resverved3 [40]; /* Reserved - must be zero */
1164 } __attribute__((__packed__));
1168 * ACPI 1.0 Fixed ACPI Description Table (FADT)
1170 struct fadt_descriptor_rev1
1172 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1173 uint32_t firmware_ctrl; /* Physical address of FACS */
1174 uint32_t dsdt; /* Physical address of DSDT */
1175 uint8_t model; /* System Interrupt Model */
1176 uint8_t reserved1; /* Reserved */
1177 uint16_t sci_int; /* System vector of SCI interrupt */
1178 uint32_t smi_cmd; /* Port address of SMI command port */
1179 uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */
1180 uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */
1181 uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
1182 uint8_t reserved2; /* Reserved - must be zero */
1183 uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
1184 uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
1185 uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
1186 uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
1187 uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
1188 uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
1189 uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
1190 uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
1191 uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
1192 uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
1193 uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
1194 uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
1195 uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
1196 uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
1197 uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */
1198 uint8_t reserved3; /* Reserved */
1199 uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
1200 uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
1201 uint16_t flush_size; /* Size of area read to flush caches */
1202 uint16_t flush_stride; /* Stride used in flushing caches */
1203 uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */
1204 uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */
1205 uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
1206 uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
1207 uint8_t century; /* Index to century in RTC CMOS RAM */
1208 uint8_t reserved4; /* Reserved */
1209 uint8_t reserved4a; /* Reserved */
1210 uint8_t reserved4b; /* Reserved */
1211 #if 0
1212 uint32_t wb_invd : 1; /* The wbinvd instruction works properly */
1213 uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
1214 uint32_t proc_c1 : 1; /* All processors support C1 state */
1215 uint32_t plvl2_up : 1; /* C2 state works on MP system */
1216 uint32_t pwr_button : 1; /* Power button is handled as a generic feature */
1217 uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
1218 uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
1219 uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
1220 uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */
1221 uint32_t reserved5 : 23; /* Reserved - must be zero */
1222 #else
1223 uint32_t flags;
1224 #endif
1225 } __attribute__((__packed__));
1228 * MADT values and structures
1231 /* Values for MADT PCATCompat */
1233 #define DUAL_PIC 0
1234 #define MULTIPLE_APIC 1
1237 /* Master MADT */
1239 struct multiple_apic_table
1241 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1242 uint32_t local_apic_address; /* Physical address of local APIC */
1243 #if 0
1244 uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */
1245 uint32_t reserved1 : 31;
1246 #else
1247 uint32_t flags;
1248 #endif
1249 } __attribute__((__packed__));
1252 /* Values for Type in APIC_HEADER_DEF */
1254 #define APIC_PROCESSOR 0
1255 #define APIC_IO 1
1256 #define APIC_XRUPT_OVERRIDE 2
1257 #define APIC_NMI 3
1258 #define APIC_LOCAL_NMI 4
1259 #define APIC_ADDRESS_OVERRIDE 5
1260 #define APIC_IO_SAPIC 6
1261 #define APIC_LOCAL_SAPIC 7
1262 #define APIC_XRUPT_SOURCE 8
1263 #define APIC_RESERVED 9 /* 9 and greater are reserved */
1266 * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
1268 #define APIC_HEADER_DEF /* Common APIC sub-structure header */\
1269 uint8_t type; \
1270 uint8_t length;
1272 /* Sub-structures for MADT */
1274 struct madt_processor_apic
1276 APIC_HEADER_DEF
1277 uint8_t processor_id; /* ACPI processor id */
1278 uint8_t local_apic_id; /* Processor's local APIC id */
1279 #if 0
1280 uint32_t processor_enabled: 1; /* Processor is usable if set */
1281 uint32_t reserved2 : 31; /* Reserved, must be zero */
1282 #else
1283 uint32_t flags;
1284 #endif
1285 } __attribute__((__packed__));
1287 #ifdef BX_QEMU
1289 * * ACPI 2.0 Generic Address Space definition.
1290 * */
1291 struct acpi_20_generic_address {
1292 uint8_t address_space_id;
1293 uint8_t register_bit_width;
1294 uint8_t register_bit_offset;
1295 uint8_t reserved;
1296 uint64_t address;
1297 } __attribute__((__packed__));
1300 * * HPET Description Table
1301 * */
1302 struct acpi_20_hpet {
1303 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1304 uint32_t timer_block_id;
1305 struct acpi_20_generic_address addr;
1306 uint8_t hpet_number;
1307 uint16_t min_tick;
1308 uint8_t page_protect;
1309 } __attribute__((__packed__));
1310 #define ACPI_HPET_ADDRESS 0xFED00000UL
1311 #endif
1313 struct madt_io_apic
1315 APIC_HEADER_DEF
1316 uint8_t io_apic_id; /* I/O APIC ID */
1317 uint8_t reserved; /* Reserved - must be zero */
1318 uint32_t address; /* APIC physical address */
1319 uint32_t interrupt; /* Global system interrupt where INTI
1320 * lines start */
1321 } __attribute__((__packed__));
1323 #ifdef BX_QEMU
1324 struct madt_int_override
1326 APIC_HEADER_DEF
1327 uint8_t bus; /* Identifies ISA Bus */
1328 uint8_t source; /* Bus-relative interrupt source */
1329 uint32_t gsi; /* GSI that source will signal */
1330 uint16_t flags; /* MPS INTI flags */
1331 } __attribute__((__packed__));
1332 #endif
1334 #include "acpi-dsdt.hex"
1336 static inline uint16_t cpu_to_le16(uint16_t x)
1338 return x;
1341 static inline uint32_t cpu_to_le32(uint32_t x)
1343 return x;
1346 static int acpi_checksum(const uint8_t *data, int len)
1348 int sum, i;
1349 sum = 0;
1350 for(i = 0; i < len; i++)
1351 sum += data[i];
1352 return (-sum) & 0xff;
1355 static void acpi_build_table_header(struct acpi_table_header *h,
1356 char *sig, int len, uint8_t rev)
1358 memcpy(h->signature, sig, 4);
1359 h->length = cpu_to_le32(len);
1360 h->revision = rev;
1361 #ifdef BX_QEMU
1362 memcpy(h->oem_id, "QEMU ", 6);
1363 memcpy(h->oem_table_id, "QEMU", 4);
1364 #else
1365 memcpy(h->oem_id, "BOCHS ", 6);
1366 memcpy(h->oem_table_id, "BXPC", 4);
1367 #endif
1368 memcpy(h->oem_table_id + 4, sig, 4);
1369 h->oem_revision = cpu_to_le32(1);
1370 #ifdef BX_QEMU
1371 memcpy(h->asl_compiler_id, "QEMU", 4);
1372 #else
1373 memcpy(h->asl_compiler_id, "BXPC", 4);
1374 #endif
1375 h->asl_compiler_revision = cpu_to_le32(1);
1376 h->checksum = acpi_checksum((void *)h, len);
1379 int acpi_build_processor_ssdt(uint8_t *ssdt)
1381 uint8_t *ssdt_ptr = ssdt;
1382 int i, length;
1383 int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
1385 ssdt_ptr[9] = 0; // checksum;
1386 ssdt_ptr += sizeof(struct acpi_table_header);
1388 // caluculate the length of processor block and scope block excluding PkgLength
1389 length = 0x0d * acpi_cpus + 4;
1391 // build processor scope header
1392 *(ssdt_ptr++) = 0x10; // ScopeOp
1393 if (length <= 0x3e) {
1394 *(ssdt_ptr++) = length + 1;
1395 } else {
1396 *(ssdt_ptr++) = 0x7F;
1397 *(ssdt_ptr++) = (length + 2) >> 6;
1399 *(ssdt_ptr++) = '_'; // Name
1400 *(ssdt_ptr++) = 'P';
1401 *(ssdt_ptr++) = 'R';
1402 *(ssdt_ptr++) = '_';
1404 // build object for each processor
1405 for(i=0;i<acpi_cpus;i++) {
1406 *(ssdt_ptr++) = 0x5B; // ProcessorOp
1407 *(ssdt_ptr++) = 0x83;
1408 *(ssdt_ptr++) = 0x0B; // Length
1409 *(ssdt_ptr++) = 'C'; // Name (CPUxx)
1410 *(ssdt_ptr++) = 'P';
1411 if ((i & 0xf0) != 0)
1412 *(ssdt_ptr++) = (i >> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa;
1413 else
1414 *(ssdt_ptr++) = 'U';
1415 *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa;
1416 *(ssdt_ptr++) = i;
1417 *(ssdt_ptr++) = 0x10; // Processor block address
1418 *(ssdt_ptr++) = 0xb0;
1419 *(ssdt_ptr++) = 0;
1420 *(ssdt_ptr++) = 0;
1421 *(ssdt_ptr++) = 6; // Processor block length
1424 acpi_build_table_header((struct acpi_table_header *)ssdt,
1425 "SSDT", ssdt_ptr - ssdt, 1);
1427 return ssdt_ptr - ssdt;
1430 /* base_addr must be a multiple of 4KB */
1431 void acpi_bios_init(void)
1433 struct rsdp_descriptor *rsdp;
1434 struct rsdt_descriptor_rev1 *rsdt;
1435 struct fadt_descriptor_rev1 *fadt;
1436 struct facs_descriptor_rev1 *facs;
1437 struct multiple_apic_table *madt;
1438 uint8_t *dsdt, *ssdt;
1439 #ifdef BX_QEMU
1440 struct acpi_20_hpet *hpet;
1441 uint32_t hpet_addr;
1442 #endif
1443 uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
1444 uint32_t acpi_tables_size, madt_addr, madt_size;
1445 int i;
1447 /* reserve memory space for tables */
1448 #ifdef BX_USE_EBDA_TABLES
1449 ebda_cur_addr = align(ebda_cur_addr, 16);
1450 rsdp = (void *)(ebda_cur_addr);
1451 ebda_cur_addr += sizeof(*rsdp);
1452 #else
1453 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1454 rsdp = (void *)(bios_table_cur_addr);
1455 bios_table_cur_addr += sizeof(*rsdp);
1456 #endif
1458 addr = base_addr = ram_size - ACPI_DATA_SIZE;
1459 rsdt_addr = addr;
1460 rsdt = (void *)(addr);
1461 addr += sizeof(*rsdt);
1463 fadt_addr = addr;
1464 fadt = (void *)(addr);
1465 addr += sizeof(*fadt);
1467 /* XXX: FACS should be in RAM */
1468 addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
1469 facs_addr = addr;
1470 facs = (void *)(addr);
1471 addr += sizeof(*facs);
1473 dsdt_addr = addr;
1474 dsdt = (void *)(addr);
1475 addr += sizeof(AmlCode);
1477 ssdt_addr = addr;
1478 ssdt = (void *)(addr);
1479 addr += acpi_build_processor_ssdt(ssdt);
1481 addr = (addr + 7) & ~7;
1482 madt_addr = addr;
1483 madt_size = sizeof(*madt) +
1484 sizeof(struct madt_processor_apic) * smp_cpus +
1485 #ifdef BX_QEMU
1486 sizeof(struct madt_io_apic) + sizeof(struct madt_int_override);
1487 #else
1488 sizeof(struct madt_io_apic);
1489 #endif
1490 madt = (void *)(addr);
1491 addr += madt_size;
1493 #ifdef BX_QEMU
1494 addr = (addr + 7) & ~7;
1495 hpet_addr = addr;
1496 hpet = (void *)(addr);
1497 addr += sizeof(*hpet);
1498 #endif
1500 acpi_tables_size = addr - base_addr;
1502 BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
1503 (unsigned long)rsdp,
1504 (unsigned long)rsdt, acpi_tables_size);
1506 /* RSDP */
1507 memset(rsdp, 0, sizeof(*rsdp));
1508 memcpy(rsdp->signature, "RSD PTR ", 8);
1509 #ifdef BX_QEMU
1510 memcpy(rsdp->oem_id, "QEMU ", 6);
1511 #else
1512 memcpy(rsdp->oem_id, "BOCHS ", 6);
1513 #endif
1514 rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
1515 rsdp->checksum = acpi_checksum((void *)rsdp, 20);
1517 /* RSDT */
1518 memset(rsdt, 0, sizeof(*rsdt));
1519 rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
1520 rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
1521 rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
1522 #ifdef BX_QEMU
1523 rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr);
1524 #endif
1525 acpi_build_table_header((struct acpi_table_header *)rsdt,
1526 "RSDT", sizeof(*rsdt), 1);
1528 /* FADT */
1529 memset(fadt, 0, sizeof(*fadt));
1530 fadt->firmware_ctrl = cpu_to_le32(facs_addr);
1531 fadt->dsdt = cpu_to_le32(dsdt_addr);
1532 fadt->model = 1;
1533 fadt->reserved1 = 0;
1534 fadt->sci_int = cpu_to_le16(pm_sci_int);
1535 fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
1536 fadt->acpi_enable = 0xf1;
1537 fadt->acpi_disable = 0xf0;
1538 fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
1539 fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
1540 fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
1541 fadt->pm1_evt_len = 4;
1542 fadt->pm1_cnt_len = 2;
1543 fadt->pm_tmr_len = 4;
1544 fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
1545 fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
1546 /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
1547 fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
1548 acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
1549 sizeof(*fadt), 1);
1551 /* FACS */
1552 memset(facs, 0, sizeof(*facs));
1553 memcpy(facs->signature, "FACS", 4);
1554 facs->length = cpu_to_le32(sizeof(*facs));
1555 BX_INFO("Firmware waking vector %p\n", &facs->firmware_waking_vector);
1557 /* DSDT */
1558 memcpy(dsdt, AmlCode, sizeof(AmlCode));
1560 /* MADT */
1562 struct madt_processor_apic *apic;
1563 struct madt_io_apic *io_apic;
1564 #ifdef BX_QEMU
1565 struct madt_int_override *int_override;
1566 #endif
1568 memset(madt, 0, madt_size);
1569 madt->local_apic_address = cpu_to_le32(0xfee00000);
1570 madt->flags = cpu_to_le32(1);
1571 apic = (void *)(madt + 1);
1572 for(i=0;i<smp_cpus;i++) {
1573 apic->type = APIC_PROCESSOR;
1574 apic->length = sizeof(*apic);
1575 apic->processor_id = i;
1576 apic->local_apic_id = i;
1577 apic->flags = cpu_to_le32(1);
1578 apic++;
1580 io_apic = (void *)apic;
1581 io_apic->type = APIC_IO;
1582 io_apic->length = sizeof(*io_apic);
1583 io_apic->io_apic_id = smp_cpus;
1584 io_apic->address = cpu_to_le32(0xfec00000);
1585 io_apic->interrupt = cpu_to_le32(0);
1586 #ifdef BX_QEMU
1587 io_apic++;
1589 int_override = (void *)io_apic;
1590 int_override->type = APIC_XRUPT_OVERRIDE;
1591 int_override->length = sizeof(*int_override);
1592 int_override->bus = cpu_to_le32(0);
1593 int_override->source = cpu_to_le32(0);
1594 int_override->gsi = cpu_to_le32(2);
1595 int_override->flags = cpu_to_le32(0);
1596 #endif
1598 acpi_build_table_header((struct acpi_table_header *)madt,
1599 "APIC", madt_size, 1);
1602 #ifdef BX_QEMU
1603 /* HPET */
1604 memset(hpet, 0, sizeof(*hpet));
1605 /* Note timer_block_id value must be kept in sync with value advertised by
1606 * emulated hpet
1608 hpet->timer_block_id = cpu_to_le32(0x8086a201);
1609 hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS);
1610 acpi_build_table_header((struct acpi_table_header *)hpet,
1611 "HPET", sizeof(*hpet), 1);
1612 #endif
1616 /* SMBIOS entry point -- must be written to a 16-bit aligned address
1617 between 0xf0000 and 0xfffff.
1619 struct smbios_entry_point {
1620 char anchor_string[4];
1621 uint8_t checksum;
1622 uint8_t length;
1623 uint8_t smbios_major_version;
1624 uint8_t smbios_minor_version;
1625 uint16_t max_structure_size;
1626 uint8_t entry_point_revision;
1627 uint8_t formatted_area[5];
1628 char intermediate_anchor_string[5];
1629 uint8_t intermediate_checksum;
1630 uint16_t structure_table_length;
1631 uint32_t structure_table_address;
1632 uint16_t number_of_structures;
1633 uint8_t smbios_bcd_revision;
1634 } __attribute__((__packed__));
1636 /* This goes at the beginning of every SMBIOS structure. */
1637 struct smbios_structure_header {
1638 uint8_t type;
1639 uint8_t length;
1640 uint16_t handle;
1641 } __attribute__((__packed__));
1643 /* SMBIOS type 0 - BIOS Information */
1644 struct smbios_type_0 {
1645 struct smbios_structure_header header;
1646 uint8_t vendor_str;
1647 uint8_t bios_version_str;
1648 uint16_t bios_starting_address_segment;
1649 uint8_t bios_release_date_str;
1650 uint8_t bios_rom_size;
1651 uint8_t bios_characteristics[8];
1652 uint8_t bios_characteristics_extension_bytes[2];
1653 uint8_t system_bios_major_release;
1654 uint8_t system_bios_minor_release;
1655 uint8_t embedded_controller_major_release;
1656 uint8_t embedded_controller_minor_release;
1657 } __attribute__((__packed__));
1659 /* SMBIOS type 1 - System Information */
1660 struct smbios_type_1 {
1661 struct smbios_structure_header header;
1662 uint8_t manufacturer_str;
1663 uint8_t product_name_str;
1664 uint8_t version_str;
1665 uint8_t serial_number_str;
1666 uint8_t uuid[16];
1667 uint8_t wake_up_type;
1668 uint8_t sku_number_str;
1669 uint8_t family_str;
1670 } __attribute__((__packed__));
1672 /* SMBIOS type 3 - System Enclosure (v2.3) */
1673 struct smbios_type_3 {
1674 struct smbios_structure_header header;
1675 uint8_t manufacturer_str;
1676 uint8_t type;
1677 uint8_t version_str;
1678 uint8_t serial_number_str;
1679 uint8_t asset_tag_number_str;
1680 uint8_t boot_up_state;
1681 uint8_t power_supply_state;
1682 uint8_t thermal_state;
1683 uint8_t security_status;
1684 uint32_t oem_defined;
1685 uint8_t height;
1686 uint8_t number_of_power_cords;
1687 uint8_t contained_element_count;
1688 // contained elements follow
1689 } __attribute__((__packed__));
1691 /* SMBIOS type 4 - Processor Information (v2.0) */
1692 struct smbios_type_4 {
1693 struct smbios_structure_header header;
1694 uint8_t socket_designation_str;
1695 uint8_t processor_type;
1696 uint8_t processor_family;
1697 uint8_t processor_manufacturer_str;
1698 uint32_t processor_id[2];
1699 uint8_t processor_version_str;
1700 uint8_t voltage;
1701 uint16_t external_clock;
1702 uint16_t max_speed;
1703 uint16_t current_speed;
1704 uint8_t status;
1705 uint8_t processor_upgrade;
1706 uint16_t l1_cache_handle;
1707 uint16_t l2_cache_handle;
1708 uint16_t l3_cache_handle;
1709 } __attribute__((__packed__));
1711 /* SMBIOS type 16 - Physical Memory Array
1712 * Associated with one type 17 (Memory Device).
1714 struct smbios_type_16 {
1715 struct smbios_structure_header header;
1716 uint8_t location;
1717 uint8_t use;
1718 uint8_t error_correction;
1719 uint32_t maximum_capacity;
1720 uint16_t memory_error_information_handle;
1721 uint16_t number_of_memory_devices;
1722 } __attribute__((__packed__));
1724 /* SMBIOS type 17 - Memory Device
1725 * Associated with one type 19
1727 struct smbios_type_17 {
1728 struct smbios_structure_header header;
1729 uint16_t physical_memory_array_handle;
1730 uint16_t memory_error_information_handle;
1731 uint16_t total_width;
1732 uint16_t data_width;
1733 uint16_t size;
1734 uint8_t form_factor;
1735 uint8_t device_set;
1736 uint8_t device_locator_str;
1737 uint8_t bank_locator_str;
1738 uint8_t memory_type;
1739 uint16_t type_detail;
1740 } __attribute__((__packed__));
1742 /* SMBIOS type 19 - Memory Array Mapped Address */
1743 struct smbios_type_19 {
1744 struct smbios_structure_header header;
1745 uint32_t starting_address;
1746 uint32_t ending_address;
1747 uint16_t memory_array_handle;
1748 uint8_t partition_width;
1749 } __attribute__((__packed__));
1751 /* SMBIOS type 20 - Memory Device Mapped Address */
1752 struct smbios_type_20 {
1753 struct smbios_structure_header header;
1754 uint32_t starting_address;
1755 uint32_t ending_address;
1756 uint16_t memory_device_handle;
1757 uint16_t memory_array_mapped_address_handle;
1758 uint8_t partition_row_position;
1759 uint8_t interleave_position;
1760 uint8_t interleaved_data_depth;
1761 } __attribute__((__packed__));
1763 /* SMBIOS type 32 - System Boot Information */
1764 struct smbios_type_32 {
1765 struct smbios_structure_header header;
1766 uint8_t reserved[6];
1767 uint8_t boot_status;
1768 } __attribute__((__packed__));
1770 /* SMBIOS type 127 -- End-of-table */
1771 struct smbios_type_127 {
1772 struct smbios_structure_header header;
1773 } __attribute__((__packed__));
1775 static void
1776 smbios_entry_point_init(void *start,
1777 uint16_t max_structure_size,
1778 uint16_t structure_table_length,
1779 uint32_t structure_table_address,
1780 uint16_t number_of_structures)
1782 uint8_t sum;
1783 int i;
1784 struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
1786 memcpy(ep->anchor_string, "_SM_", 4);
1787 ep->length = 0x1f;
1788 ep->smbios_major_version = 2;
1789 ep->smbios_minor_version = 4;
1790 ep->max_structure_size = max_structure_size;
1791 ep->entry_point_revision = 0;
1792 memset(ep->formatted_area, 0, 5);
1793 memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
1795 ep->structure_table_length = structure_table_length;
1796 ep->structure_table_address = structure_table_address;
1797 ep->number_of_structures = number_of_structures;
1798 ep->smbios_bcd_revision = 0x24;
1800 ep->checksum = 0;
1801 ep->intermediate_checksum = 0;
1803 sum = 0;
1804 for (i = 0; i < 0x10; i++)
1805 sum += ((int8_t *)start)[i];
1806 ep->checksum = -sum;
1808 sum = 0;
1809 for (i = 0x10; i < ep->length; i++)
1810 sum += ((int8_t *)start)[i];
1811 ep->intermediate_checksum = -sum;
1814 /* Type 0 -- BIOS Information */
1815 #define RELEASE_DATE_STR "01/01/2007"
1816 static void *
1817 smbios_type_0_init(void *start)
1819 struct smbios_type_0 *p = (struct smbios_type_0 *)start;
1821 p->header.type = 0;
1822 p->header.length = sizeof(struct smbios_type_0);
1823 p->header.handle = 0;
1825 p->vendor_str = 1;
1826 p->bios_version_str = 1;
1827 p->bios_starting_address_segment = 0xe800;
1828 p->bios_release_date_str = 2;
1829 p->bios_rom_size = 0; /* FIXME */
1831 memset(p->bios_characteristics, 0, 8);
1832 p->bios_characteristics[0] = 0x08; /* BIOS characteristics not supported */
1833 p->bios_characteristics_extension_bytes[0] = 0;
1834 p->bios_characteristics_extension_bytes[1] = 0;
1836 p->system_bios_major_release = 1;
1837 p->system_bios_minor_release = 0;
1838 p->embedded_controller_major_release = 0xff;
1839 p->embedded_controller_minor_release = 0xff;
1841 start += sizeof(struct smbios_type_0);
1842 memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
1843 start += sizeof(BX_APPNAME);
1844 memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
1845 start += sizeof(RELEASE_DATE_STR);
1846 *((uint8_t *)start) = 0;
1848 return start+1;
1851 /* Type 1 -- System Information */
1852 static void *
1853 smbios_type_1_init(void *start)
1855 struct smbios_type_1 *p = (struct smbios_type_1 *)start;
1856 p->header.type = 1;
1857 p->header.length = sizeof(struct smbios_type_1);
1858 p->header.handle = 0x100;
1860 p->manufacturer_str = 0;
1861 p->product_name_str = 0;
1862 p->version_str = 0;
1863 p->serial_number_str = 0;
1865 memcpy(p->uuid, bios_uuid, 16);
1867 p->wake_up_type = 0x06; /* power switch */
1868 p->sku_number_str = 0;
1869 p->family_str = 0;
1871 start += sizeof(struct smbios_type_1);
1872 *((uint16_t *)start) = 0;
1874 return start+2;
1877 /* Type 3 -- System Enclosure */
1878 static void *
1879 smbios_type_3_init(void *start)
1881 struct smbios_type_3 *p = (struct smbios_type_3 *)start;
1883 p->header.type = 3;
1884 p->header.length = sizeof(struct smbios_type_3);
1885 p->header.handle = 0x300;
1887 p->manufacturer_str = 0;
1888 p->type = 0x01; /* other */
1889 p->version_str = 0;
1890 p->serial_number_str = 0;
1891 p->asset_tag_number_str = 0;
1892 p->boot_up_state = 0x03; /* safe */
1893 p->power_supply_state = 0x03; /* safe */
1894 p->thermal_state = 0x03; /* safe */
1895 p->security_status = 0x02; /* unknown */
1896 p->oem_defined = 0;
1897 p->height = 0;
1898 p->number_of_power_cords = 0;
1899 p->contained_element_count = 0;
1901 start += sizeof(struct smbios_type_3);
1902 *((uint16_t *)start) = 0;
1904 return start+2;
1907 /* Type 4 -- Processor Information */
1908 static void *
1909 smbios_type_4_init(void *start, unsigned int cpu_number)
1911 struct smbios_type_4 *p = (struct smbios_type_4 *)start;
1913 p->header.type = 4;
1914 p->header.length = sizeof(struct smbios_type_4);
1915 p->header.handle = 0x400 + cpu_number;
1917 p->socket_designation_str = 1;
1918 p->processor_type = 0x03; /* CPU */
1919 p->processor_family = 0x01; /* other */
1920 p->processor_manufacturer_str = 0;
1922 p->processor_id[0] = cpuid_signature;
1923 p->processor_id[1] = cpuid_features;
1925 p->processor_version_str = 0;
1926 p->voltage = 0;
1927 p->external_clock = 0;
1929 p->max_speed = 0; /* unknown */
1930 p->current_speed = 0; /* unknown */
1932 p->status = 0x41; /* socket populated, CPU enabled */
1933 p->processor_upgrade = 0x01; /* other */
1935 p->l1_cache_handle = 0xffff; /* cache information structure not provided */
1936 p->l2_cache_handle = 0xffff;
1937 p->l3_cache_handle = 0xffff;
1939 start += sizeof(struct smbios_type_4);
1941 memcpy((char *)start, "CPU " "\0" "" "\0" "", 7);
1942 ((char *)start)[4] = cpu_number + '0';
1944 return start+7;
1947 /* Type 16 -- Physical Memory Array */
1948 static void *
1949 smbios_type_16_init(void *start, uint32_t memsize)
1951 struct smbios_type_16 *p = (struct smbios_type_16*)start;
1953 p->header.type = 16;
1954 p->header.length = sizeof(struct smbios_type_16);
1955 p->header.handle = 0x1000;
1957 p->location = 0x01; /* other */
1958 p->use = 0x03; /* system memory */
1959 p->error_correction = 0x01; /* other */
1960 p->maximum_capacity = memsize * 1024;
1961 p->memory_error_information_handle = 0xfffe; /* none provided */
1962 p->number_of_memory_devices = 1;
1964 start += sizeof(struct smbios_type_16);
1965 *((uint16_t *)start) = 0;
1967 return start + 2;
1970 /* Type 17 -- Memory Device */
1971 static void *
1972 smbios_type_17_init(void *start, uint32_t memory_size_mb)
1974 struct smbios_type_17 *p = (struct smbios_type_17 *)start;
1976 p->header.type = 17;
1977 p->header.length = sizeof(struct smbios_type_17);
1978 p->header.handle = 0x1100;
1980 p->physical_memory_array_handle = 0x1000;
1981 p->total_width = 64;
1982 p->data_width = 64;
1983 /* truncate memory_size_mb to 16 bits and clear most significant
1984 bit [indicates size in MB] */
1985 p->size = (uint16_t) memory_size_mb & 0x7fff;
1986 p->form_factor = 0x09; /* DIMM */
1987 p->device_set = 0;
1988 p->device_locator_str = 1;
1989 p->bank_locator_str = 0;
1990 p->memory_type = 0x07; /* RAM */
1991 p->type_detail = 0;
1993 start += sizeof(struct smbios_type_17);
1994 memcpy((char *)start, "DIMM 1", 7);
1995 start += 7;
1996 *((uint8_t *)start) = 0;
1998 return start+1;
2001 /* Type 19 -- Memory Array Mapped Address */
2002 static void *
2003 smbios_type_19_init(void *start, uint32_t memory_size_mb)
2005 struct smbios_type_19 *p = (struct smbios_type_19 *)start;
2007 p->header.type = 19;
2008 p->header.length = sizeof(struct smbios_type_19);
2009 p->header.handle = 0x1300;
2011 p->starting_address = 0;
2012 p->ending_address = (memory_size_mb-1) * 1024;
2013 p->memory_array_handle = 0x1000;
2014 p->partition_width = 1;
2016 start += sizeof(struct smbios_type_19);
2017 *((uint16_t *)start) = 0;
2019 return start + 2;
2022 /* Type 20 -- Memory Device Mapped Address */
2023 static void *
2024 smbios_type_20_init(void *start, uint32_t memory_size_mb)
2026 struct smbios_type_20 *p = (struct smbios_type_20 *)start;
2028 p->header.type = 20;
2029 p->header.length = sizeof(struct smbios_type_20);
2030 p->header.handle = 0x1400;
2032 p->starting_address = 0;
2033 p->ending_address = (memory_size_mb-1)*1024;
2034 p->memory_device_handle = 0x1100;
2035 p->memory_array_mapped_address_handle = 0x1300;
2036 p->partition_row_position = 1;
2037 p->interleave_position = 0;
2038 p->interleaved_data_depth = 0;
2040 start += sizeof(struct smbios_type_20);
2042 *((uint16_t *)start) = 0;
2043 return start+2;
2046 /* Type 32 -- System Boot Information */
2047 static void *
2048 smbios_type_32_init(void *start)
2050 struct smbios_type_32 *p = (struct smbios_type_32 *)start;
2052 p->header.type = 32;
2053 p->header.length = sizeof(struct smbios_type_32);
2054 p->header.handle = 0x2000;
2055 memset(p->reserved, 0, 6);
2056 p->boot_status = 0; /* no errors detected */
2058 start += sizeof(struct smbios_type_32);
2059 *((uint16_t *)start) = 0;
2061 return start+2;
2064 /* Type 127 -- End of Table */
2065 static void *
2066 smbios_type_127_init(void *start)
2068 struct smbios_type_127 *p = (struct smbios_type_127 *)start;
2070 p->header.type = 127;
2071 p->header.length = sizeof(struct smbios_type_127);
2072 p->header.handle = 0x7f00;
2074 start += sizeof(struct smbios_type_127);
2075 *((uint16_t *)start) = 0;
2077 return start + 2;
2080 void smbios_init(void)
2082 unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
2083 char *start, *p, *q;
2084 int memsize = ram_size / (1024 * 1024);
2086 #ifdef BX_USE_EBDA_TABLES
2087 ebda_cur_addr = align(ebda_cur_addr, 16);
2088 start = (void *)(ebda_cur_addr);
2089 #else
2090 bios_table_cur_addr = align(bios_table_cur_addr, 16);
2091 start = (void *)(bios_table_cur_addr);
2092 #endif
2094 p = (char *)start + sizeof(struct smbios_entry_point);
2096 #define add_struct(fn) { \
2097 q = (fn); \
2098 nr_structs++; \
2099 if ((q - p) > max_struct_size) \
2100 max_struct_size = q - p; \
2101 p = q; \
2104 add_struct(smbios_type_0_init(p));
2105 add_struct(smbios_type_1_init(p));
2106 add_struct(smbios_type_3_init(p));
2107 for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
2108 add_struct(smbios_type_4_init(p, cpu_num));
2109 add_struct(smbios_type_16_init(p, memsize));
2110 add_struct(smbios_type_17_init(p, memsize));
2111 add_struct(smbios_type_19_init(p, memsize));
2112 add_struct(smbios_type_20_init(p, memsize));
2113 add_struct(smbios_type_32_init(p));
2114 add_struct(smbios_type_127_init(p));
2116 #undef add_struct
2118 smbios_entry_point_init(
2119 start, max_struct_size,
2120 (p - (char *)start) - sizeof(struct smbios_entry_point),
2121 (uint32_t)(start + sizeof(struct smbios_entry_point)),
2122 nr_structs);
2124 #ifdef BX_USE_EBDA_TABLES
2125 ebda_cur_addr += (p - (char *)start);
2126 #else
2127 bios_table_cur_addr += (p - (char *)start);
2128 #endif
2130 BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
2133 static uint32_t find_resume_vector(void)
2135 unsigned long addr, start, end;
2137 #ifdef BX_USE_EBDA_TABLES
2138 start = align(ebda_cur_addr, 16);
2139 end = 0xa000 << 4;
2140 #else
2141 if (bios_table_cur_addr == 0)
2142 return 0;
2143 start = align(bios_table_cur_addr, 16);
2144 end = bios_table_end_addr;
2145 #endif
2147 for (addr = start; addr < end; addr += 16) {
2148 if (!memcmp((void*)addr, "RSD PTR ", 8)) {
2149 struct rsdp_descriptor *rsdp = (void*)addr;
2150 struct rsdt_descriptor_rev1 *rsdt = (void*)rsdp->rsdt_physical_address;
2151 struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[0];
2152 struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
2153 return facs->firmware_waking_vector;
2157 return 0;
2160 static void find_440fx(PCIDevice *d)
2162 uint16_t vendor_id, device_id;
2164 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
2165 device_id = pci_config_readw(d, PCI_DEVICE_ID);
2167 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441)
2168 i440_pcidev = *d;
2171 static void reinit_piix4_pm(PCIDevice *d)
2173 uint16_t vendor_id, device_id;
2175 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
2176 device_id = pci_config_readw(d, PCI_DEVICE_ID);
2178 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3)
2179 piix4_pm_enable(d);
2182 void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
2184 BX_INFO("Starting rombios32\n");
2185 BX_INFO("Shutdown flag %x\n", *shutdown_flag);
2187 #ifdef BX_QEMU
2188 qemu_cfg_port = qemu_cfg_port_probe();
2189 #endif
2191 ram_probe();
2193 cpu_probe();
2195 smp_probe();
2197 find_bios_table_area();
2199 if (*shutdown_flag == 0xfe) {
2200 /* redirect bios read access to RAM */
2201 pci_for_each_device(find_440fx);
2202 bios_lock_shadow_ram(); /* bios is already copied */
2203 *s3_resume_vector = find_resume_vector();
2204 if (!*s3_resume_vector) {
2205 BX_INFO("This is S3 resume but wakeup vector is NULL\n");
2206 } else {
2207 BX_INFO("S3 resume vector %p\n", *s3_resume_vector);
2208 pci_for_each_device(reinit_piix4_pm);
2210 return;
2213 pci_bios_init();
2215 if (bios_table_cur_addr != 0) {
2217 mptable_init();
2219 uuid_probe();
2221 smbios_init();
2223 if (acpi_enabled)
2224 acpi_bios_init();
2226 bios_lock_shadow_ram();
2228 BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
2229 if (bios_table_cur_addr > bios_table_end_addr)
2230 BX_PANIC("bios_table_end_addr overflow!\n");
2231 #ifdef BX_USE_EBDA_TABLES
2232 BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
2233 if (ebda_cur_addr > 0xA0000)
2234 BX_PANIC("ebda_cur_addr overflow!\n");
2235 #endif