kvm: libkvm: kvm_dirty_pages_log_change: do not forget to set .slot
[kvm-userspace.git] / bios / rombios32.c
blobc57e96785ec41c356f6cb4a9a2ed203017f29aae
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: rombios32.c,v 1.11 2007/08/03 13:56:13 vruppert Exp $
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 /* IRQs 5,9,10,11 */
59 #define PCI_ISA_IRQ_MASK 0x0e20U
61 #define APIC_ENABLED 0x0100
63 #define AP_BOOT_ADDR 0x10000
65 #define MPTABLE_MAX_SIZE 0x00002000
66 #define SMI_CMD_IO_ADDR 0xb2
68 #define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */
70 #define MSR_MTRRcap 0x000000fe
71 #define MSR_MTRRfix64K_00000 0x00000250
72 #define MSR_MTRRfix16K_80000 0x00000258
73 #define MSR_MTRRfix16K_A0000 0x00000259
74 #define MSR_MTRRfix4K_C0000 0x00000268
75 #define MSR_MTRRfix4K_C8000 0x00000269
76 #define MSR_MTRRfix4K_D0000 0x0000026a
77 #define MSR_MTRRfix4K_D8000 0x0000026b
78 #define MSR_MTRRfix4K_E0000 0x0000026c
79 #define MSR_MTRRfix4K_E8000 0x0000026d
80 #define MSR_MTRRfix4K_F0000 0x0000026e
81 #define MSR_MTRRfix4K_F8000 0x0000026f
82 #define MSR_MTRRdefType 0x000002ff
84 #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
85 #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
87 static inline void outl(int addr, int val)
89 asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val));
92 static inline void outw(int addr, int val)
94 asm volatile ("outw %w1, %w0" : : "d" (addr), "a" (val));
97 static inline void outb(int addr, int val)
99 asm volatile ("outb %b1, %w0" : : "d" (addr), "a" (val));
102 static inline uint32_t inl(int addr)
104 uint32_t val;
105 asm volatile ("inl %w1, %0" : "=a" (val) : "d" (addr));
106 return val;
109 static inline uint16_t inw(int addr)
111 uint16_t val;
112 asm volatile ("inw %w1, %w0" : "=a" (val) : "d" (addr));
113 return val;
116 static inline uint8_t inb(int addr)
118 uint8_t val;
119 asm volatile ("inb %w1, %b0" : "=a" (val) : "d" (addr));
120 return val;
123 static inline void writel(void *addr, uint32_t val)
125 *(volatile uint32_t *)addr = val;
128 static inline void writew(void *addr, uint16_t val)
130 *(volatile uint16_t *)addr = val;
133 static inline void writeb(void *addr, uint8_t val)
135 *(volatile uint8_t *)addr = val;
138 static inline uint32_t readl(const void *addr)
140 return *(volatile const uint32_t *)addr;
143 static inline uint16_t readw(const void *addr)
145 return *(volatile const uint16_t *)addr;
148 static inline uint8_t readb(const void *addr)
150 return *(volatile const uint8_t *)addr;
153 static inline void putc(int c)
155 outb(INFO_PORT, c);
158 static uint64_t rdmsr(unsigned index)
160 unsigned long long ret;
162 asm ("rdmsr" : "=A"(ret) : "c"(index));
163 return ret;
166 static void wrmsr(unsigned index, uint64_t val)
168 asm volatile ("wrmsr" : : "c"(index), "A"(val));
171 static inline int isdigit(int c)
173 return c >= '0' && c <= '9';
176 void *memset(void *d1, int val, size_t len)
178 uint8_t *d = d1;
180 while (len--) {
181 *d++ = val;
183 return d1;
186 void *memcpy(void *d1, const void *s1, size_t len)
188 uint8_t *d = d1;
189 const uint8_t *s = s1;
191 while (len--) {
192 *d++ = *s++;
194 return d1;
197 void *memmove(void *d1, const void *s1, size_t len)
199 uint8_t *d = d1;
200 const uint8_t *s = s1;
202 if (d <= s) {
203 while (len--) {
204 *d++ = *s++;
206 } else {
207 d += len;
208 s += len;
209 while (len--) {
210 *--d = *--s;
213 return d1;
216 size_t strlen(const char *s)
218 const char *s1;
219 for(s1 = s; *s1 != '\0'; s1++);
220 return s1 - s;
223 /* from BSD ppp sources */
224 int vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
226 int c, i, n;
227 int width, prec, fillch;
228 int base, len, neg;
229 unsigned long val = 0;
230 const char *f;
231 char *str, *buf0;
232 char num[32];
233 static const char hexchars[] = "0123456789abcdef";
235 buf0 = buf;
236 --buflen;
237 while (buflen > 0) {
238 for (f = fmt; *f != '%' && *f != 0; ++f)
240 if (f > fmt) {
241 len = f - fmt;
242 if (len > buflen)
243 len = buflen;
244 memcpy(buf, fmt, len);
245 buf += len;
246 buflen -= len;
247 fmt = f;
249 if (*fmt == 0)
250 break;
251 c = *++fmt;
252 width = prec = 0;
253 fillch = ' ';
254 if (c == '0') {
255 fillch = '0';
256 c = *++fmt;
258 if (c == '*') {
259 width = va_arg(args, int);
260 c = *++fmt;
261 } else {
262 while (isdigit(c)) {
263 width = width * 10 + c - '0';
264 c = *++fmt;
267 if (c == '.') {
268 c = *++fmt;
269 if (c == '*') {
270 prec = va_arg(args, int);
271 c = *++fmt;
272 } else {
273 while (isdigit(c)) {
274 prec = prec * 10 + c - '0';
275 c = *++fmt;
279 /* modifiers */
280 switch(c) {
281 case 'l':
282 c = *++fmt;
283 break;
284 default:
285 break;
287 str = 0;
288 base = 0;
289 neg = 0;
290 ++fmt;
291 switch (c) {
292 case 'd':
293 i = va_arg(args, int);
294 if (i < 0) {
295 neg = 1;
296 val = -i;
297 } else
298 val = i;
299 base = 10;
300 break;
301 case 'o':
302 val = va_arg(args, unsigned int);
303 base = 8;
304 break;
305 case 'x':
306 case 'X':
307 val = va_arg(args, unsigned int);
308 base = 16;
309 break;
310 case 'p':
311 val = (unsigned long) va_arg(args, void *);
312 base = 16;
313 neg = 2;
314 break;
315 case 's':
316 str = va_arg(args, char *);
317 break;
318 case 'c':
319 num[0] = va_arg(args, int);
320 num[1] = 0;
321 str = num;
322 break;
323 default:
324 *buf++ = '%';
325 if (c != '%')
326 --fmt; /* so %z outputs %z etc. */
327 --buflen;
328 continue;
330 if (base != 0) {
331 str = num + sizeof(num);
332 *--str = 0;
333 while (str > num + neg) {
334 *--str = hexchars[val % base];
335 val = val / base;
336 if (--prec <= 0 && val == 0)
337 break;
339 switch (neg) {
340 case 1:
341 *--str = '-';
342 break;
343 case 2:
344 *--str = 'x';
345 *--str = '0';
346 break;
348 len = num + sizeof(num) - 1 - str;
349 } else {
350 len = strlen(str);
351 if (prec > 0 && len > prec)
352 len = prec;
354 if (width > 0) {
355 if (width > buflen)
356 width = buflen;
357 if ((n = width - len) > 0) {
358 buflen -= n;
359 for (; n > 0; --n)
360 *buf++ = fillch;
363 if (len > buflen)
364 len = buflen;
365 memcpy(buf, str, len);
366 buf += len;
367 buflen -= len;
369 *buf = 0;
370 return buf - buf0;
373 void bios_printf(int flags, const char *fmt, ...)
375 va_list ap;
376 char buf[1024];
377 const char *s;
379 if ((flags & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT)
380 outb(PANIC_PORT2, 0x00);
382 va_start(ap, fmt);
383 vsnprintf(buf, sizeof(buf), fmt, ap);
384 s = buf;
385 while (*s)
386 putc(*s++);
387 va_end(ap);
390 void delay_ms(int n)
392 int i, j;
393 for(i = 0; i < n; i++) {
394 #ifdef BX_QEMU
395 /* approximative ! */
396 for(j = 0; j < 1000000; j++);
397 #else
399 int r1, r2;
400 j = 66;
401 r1 = inb(0x61) & 0x10;
402 do {
403 r2 = inb(0x61) & 0x10;
404 if (r1 != r2) {
405 j--;
406 r1 = r2;
408 } while (j > 0);
410 #endif
414 int smp_cpus;
415 uint32_t cpuid_signature;
416 uint32_t cpuid_features;
417 uint32_t cpuid_ext_features;
418 unsigned long ram_size;
419 uint64_t above4g_ram_size;
420 uint8_t bios_uuid[16];
421 #ifdef BX_USE_EBDA_TABLES
422 unsigned long ebda_cur_addr;
423 #endif
424 int acpi_enabled;
425 uint32_t pm_io_base, smb_io_base;
426 int pm_sci_int;
427 unsigned long bios_table_cur_addr;
428 unsigned long bios_table_end_addr;
430 void init_smp_msrs(void)
432 *(uint32_t *)SMP_MSR_ADDR = 0;
435 void wrmsr_smp(uint32_t index, uint64_t val)
437 static struct { uint32_t ecx, eax, edx; } *p = (void *)SMP_MSR_ADDR;
439 wrmsr(index, val);
440 p->ecx = index;
441 p->eax = val;
442 p->edx = val >> 32;
443 ++p;
444 p->ecx = 0;
447 void uuid_probe(void)
449 #ifdef BX_QEMU
450 uint32_t eax, ebx, ecx, edx;
452 // check if backdoor port exists
453 asm volatile ("outl %%eax, %%dx"
454 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
455 : "a" (0x564d5868), "c" (0xa), "d" (0x5658));
456 if (ebx == 0x564d5868) {
457 uint32_t *uuid_ptr = (uint32_t *)bios_uuid;
458 // get uuid
459 asm volatile ("outl %%eax, %%dx"
460 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
461 : "a" (0x564d5868), "c" (0x13), "d" (0x5658));
462 uuid_ptr[0] = eax;
463 uuid_ptr[1] = ebx;
464 uuid_ptr[2] = ecx;
465 uuid_ptr[3] = edx;
466 } else
467 #endif
469 // UUID not set
470 memset(bios_uuid, 0, 16);
474 void cpu_probe(void)
476 uint32_t eax, ebx, ecx, edx;
477 cpuid(1, eax, ebx, ecx, edx);
478 cpuid_signature = eax;
479 cpuid_features = edx;
480 cpuid_ext_features = ecx;
483 static int cmos_readb(int addr)
485 outb(0x70, addr);
486 return inb(0x71);
489 void setup_mtrr(void)
491 int i, vcnt, fix, wc;
492 uint32_t mtrr_cap;
493 union {
494 uint8_t valb[8];
495 uint64_t val;
496 } u;
497 uint64_t vbase, vmask;
499 mtrr_cap = rdmsr(MSR_MTRRcap);
500 vcnt = mtrr_cap & 0xff;
501 fix = mtrr_cap & 0x100;
502 wc = mtrr_cap & 0x400;
503 if (!vcnt || !fix)
504 return;
505 u.val = 0;
506 for (i = 0; i < 8; ++i)
507 if (ram_size >= 65536 * (i + 1))
508 u.valb[i] = 6;
509 wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
510 u.val = 0;
511 for (i = 0; i < 8; ++i)
512 if (ram_size >= 65536 * 8 + 16384 * (i + 1))
513 u.valb[i] = 6;
514 wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
515 wrmsr_smp(MSR_MTRRfix16K_A0000, 0);
516 wrmsr_smp(MSR_MTRRfix4K_C0000, 0);
517 wrmsr_smp(MSR_MTRRfix4K_C8000, 0);
518 wrmsr_smp(MSR_MTRRfix4K_D0000, 0);
519 wrmsr_smp(MSR_MTRRfix4K_D8000, 0);
520 wrmsr_smp(MSR_MTRRfix4K_E0000, 0);
521 wrmsr_smp(MSR_MTRRfix4K_E8000, 0);
522 wrmsr_smp(MSR_MTRRfix4K_F0000, 0);
523 wrmsr_smp(MSR_MTRRfix4K_F8000, 0);
524 vbase = 0;
525 --vcnt; /* leave one mtrr for VRAM */
526 for (i = 0; i < vcnt && vbase < ram_size; ++i) {
527 vmask = (1ull << 40) - 1;
528 while (vbase + vmask + 1 > ram_size)
529 vmask >>= 1;
530 wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6);
531 wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800);
532 vbase += vmask + 1;
534 for (vbase = 1ull << 32; i < vcnt && vbase < above4g_ram_size; ++i) {
535 vmask = (1ull << 40) - 1;
536 while (vbase + vmask + 1 > above4g_ram_size)
537 vmask >>= 1;
538 wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6);
539 wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800);
540 vbase += vmask + 1;
542 wrmsr_smp(MSR_MTRRdefType, 0xc00);
545 void ram_probe(void)
547 if (cmos_readb(0x34) | cmos_readb(0x35))
548 ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 +
549 16 * 1024 * 1024;
550 else
551 ram_size = (cmos_readb(0x17) | (cmos_readb(0x18) << 8)) * 1024;
553 if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d))
554 above4g_ram_size = ((uint64_t)cmos_readb(0x5b) << 16) |
555 ((uint64_t)cmos_readb(0x5c) << 24) | ((uint64_t)cmos_readb(0x5d) << 32);
557 if (above4g_ram_size)
558 above4g_ram_size += 1ull << 32;
560 #ifdef BX_USE_EBDA_TABLES
561 ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
562 #endif
563 BX_INFO("ram_size=0x%08lx\n", ram_size);
564 BX_INFO("top of ram %ldMB\n", above4g_ram_size >> 20);
565 setup_mtrr();
568 /****************************************************/
569 /* SMP probe */
571 extern uint8_t smp_ap_boot_code_start;
572 extern uint8_t smp_ap_boot_code_end;
574 /* find the number of CPUs by launching a SIPI to them */
575 void smp_probe(void)
577 uint32_t val, sipi_vector;
579 smp_cpus = 1;
580 if (cpuid_features & CPUID_APIC) {
582 /* enable local APIC */
583 val = readl(APIC_BASE + APIC_SVR);
584 val |= APIC_ENABLED;
585 writel(APIC_BASE + APIC_SVR, val);
587 writew((void *)CPU_COUNT_ADDR, 1);
588 /* copy AP boot code */
589 memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start,
590 &smp_ap_boot_code_end - &smp_ap_boot_code_start);
592 /* broadcast SIPI */
593 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500);
594 sipi_vector = AP_BOOT_ADDR >> 12;
595 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector);
596 asm volatile(
597 "xor %%eax, %%eax \n\t"
598 "xor %%edx, %%edx \n\t"
599 "mov $0x10, %%ecx \n\t"
600 "wrmsr"
601 : : : "eax", "ecx", "edx");
603 #ifndef BX_QEMU
604 delay_ms(10);
605 #else
606 while (cmos_readb(0x5f) + 1 != readw((void *)CPU_COUNT_ADDR))
608 #endif
610 smp_cpus = readw((void *)CPU_COUNT_ADDR);
612 BX_INFO("Found %d cpu(s)\n", smp_cpus);
615 /****************************************************/
616 /* PCI init */
618 #define PCI_ADDRESS_SPACE_MEM 0x00
619 #define PCI_ADDRESS_SPACE_IO 0x01
620 #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
622 #define PCI_ROM_SLOT 6
623 #define PCI_NUM_REGIONS 7
625 #define PCI_DEVICES_MAX 64
627 #define PCI_VENDOR_ID 0x00 /* 16 bits */
628 #define PCI_DEVICE_ID 0x02 /* 16 bits */
629 #define PCI_COMMAND 0x04 /* 16 bits */
630 #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
631 #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
632 #define PCI_CLASS_DEVICE 0x0a /* Device class */
633 #define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
634 #define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
635 #define PCI_MIN_GNT 0x3e /* 8 bits */
636 #define PCI_MAX_LAT 0x3f /* 8 bits */
638 typedef struct PCIDevice {
639 int bus;
640 int devfn;
641 } PCIDevice;
643 static uint32_t pci_bios_io_addr;
644 static uint32_t pci_bios_mem_addr;
645 static uint32_t pci_bios_bigmem_addr;
646 /* host irqs corresponding to PCI irqs A-D */
647 static uint8_t pci_irqs[4] = { 10, 10, 11, 11 };
648 static PCIDevice i440_pcidev;
650 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
652 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
653 outl(0xcfc, val);
656 static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
658 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
659 outw(0xcfc + (addr & 2), val);
662 static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
664 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
665 outb(0xcfc + (addr & 3), val);
668 static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
670 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
671 return inl(0xcfc);
674 static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
676 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
677 return inw(0xcfc + (addr & 2));
680 static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
682 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
683 return inb(0xcfc + (addr & 3));
686 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
688 uint16_t cmd;
689 uint32_t ofs, old_addr;
691 if ( region_num == PCI_ROM_SLOT ) {
692 ofs = 0x30;
693 }else{
694 ofs = 0x10 + region_num * 4;
697 old_addr = pci_config_readl(d, ofs);
699 pci_config_writel(d, ofs, addr);
700 BX_INFO("region %d: 0x%08x\n", region_num, addr);
702 /* enable memory mappings */
703 cmd = pci_config_readw(d, PCI_COMMAND);
704 if ( region_num == PCI_ROM_SLOT )
705 cmd |= 2;
706 else if (old_addr & PCI_ADDRESS_SPACE_IO)
707 cmd |= 1;
708 else
709 cmd |= 2;
710 pci_config_writew(d, PCI_COMMAND, cmd);
713 /* return the global irq number corresponding to a given device irq
714 pin. We could also use the bus number to have a more precise
715 mapping. */
716 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
718 int slot_addend;
719 slot_addend = (pci_dev->devfn >> 3) - 1;
720 return (irq_num + slot_addend) & 3;
723 static int find_bios_table_area(void)
725 unsigned long addr;
726 for(addr = 0xf0000; addr < 0x100000; addr += 16) {
727 if (*(uint32_t *)addr == 0xaafb4442) {
728 bios_table_cur_addr = addr + 8;
729 bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
730 BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
731 bios_table_cur_addr, bios_table_end_addr);
732 return 0;
735 return -1;
738 static void bios_shadow_init(PCIDevice *d)
740 int v;
742 if (find_bios_table_area() < 0)
743 return;
745 /* remap the BIOS to shadow RAM an keep it read/write while we
746 are writing tables */
747 v = pci_config_readb(d, 0x59);
748 v &= 0xcf;
749 pci_config_writeb(d, 0x59, v);
750 memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);
751 v |= 0x30;
752 pci_config_writeb(d, 0x59, v);
753 memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);
755 i440_pcidev = *d;
758 static void bios_lock_shadow_ram(void)
760 PCIDevice *d = &i440_pcidev;
761 int v;
763 wbinvd();
764 v = pci_config_readb(d, 0x59);
765 v = (v & 0x0f) | (0x10);
766 pci_config_writeb(d, 0x59, v);
769 static void pci_bios_init_bridges(PCIDevice *d)
771 uint16_t vendor_id, device_id;
773 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
774 device_id = pci_config_readw(d, PCI_DEVICE_ID);
776 if (vendor_id == 0x8086 && device_id == 0x7000) {
777 int i, irq;
778 uint8_t elcr[2];
780 /* PIIX3 bridge */
782 elcr[0] = 0x00;
783 elcr[1] = 0x00;
784 for(i = 0; i < 4; i++) {
785 irq = pci_irqs[i];
786 /* set to trigger level */
787 elcr[irq >> 3] |= (1 << (irq & 7));
788 /* activate irq remapping in PIIX */
789 pci_config_writeb(d, 0x60 + i, irq);
791 outb(0x4d0, elcr[0]);
792 outb(0x4d1, elcr[1]);
793 BX_INFO("PIIX3 init: elcr=%02x %02x\n",
794 elcr[0], elcr[1]);
795 } else if (vendor_id == 0x8086 && device_id == 0x1237) {
796 /* i440 PCI bridge */
797 bios_shadow_init(d);
801 extern uint8_t smm_relocation_start, smm_relocation_end;
802 extern uint8_t smm_code_start, smm_code_end;
804 #ifdef BX_USE_SMM
805 static void smm_init(PCIDevice *d)
807 uint32_t value;
809 /* check if SMM init is already done */
810 value = pci_config_readl(d, 0x58);
811 if ((value & (1 << 25)) == 0) {
813 /* copy the SMM relocation code */
814 memcpy((void *)0x38000, &smm_relocation_start,
815 &smm_relocation_end - &smm_relocation_start);
817 /* enable SMI generation when writing to the APMC register */
818 pci_config_writel(d, 0x58, value | (1 << 25));
820 /* init APM status port */
821 outb(0xb3, 0x01);
823 /* raise an SMI interrupt */
824 outb(0xb2, 0x00);
826 /* wait until SMM code executed */
827 while (inb(0xb3) != 0x00);
829 /* enable the SMM memory window */
830 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x48);
832 /* copy the SMM code */
833 memcpy((void *)0xa8000, &smm_code_start,
834 &smm_code_end - &smm_code_start);
835 wbinvd();
837 /* close the SMM memory window and enable normal SMM */
838 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x08);
841 #endif
843 static void pci_bios_init_device(PCIDevice *d)
845 int class;
846 uint32_t *paddr;
847 int i, pin, pic_irq, vendor_id, device_id;
849 class = pci_config_readw(d, PCI_CLASS_DEVICE);
850 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
851 device_id = pci_config_readw(d, PCI_DEVICE_ID);
852 BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n",
853 d->bus, d->devfn, vendor_id, device_id);
854 switch(class) {
855 case 0x0101:
856 if (vendor_id == 0x8086 && device_id == 0x7010) {
857 /* PIIX3 IDE */
858 pci_config_writew(d, 0x40, 0x8000); // enable IDE0
859 pci_config_writew(d, 0x42, 0x8000); // enable IDE1
860 goto default_map;
861 } else {
862 /* IDE: we map it as in ISA mode */
863 pci_set_io_region_addr(d, 0, 0x1f0);
864 pci_set_io_region_addr(d, 1, 0x3f4);
865 pci_set_io_region_addr(d, 2, 0x170);
866 pci_set_io_region_addr(d, 3, 0x374);
868 break;
869 case 0x0300:
870 if (vendor_id != 0x1234)
871 goto default_map;
872 /* VGA: map frame buffer to default Bochs VBE address */
873 pci_set_io_region_addr(d, 0, 0xE0000000);
874 break;
875 case 0x0800:
876 /* PIC */
877 if (vendor_id == 0x1014) {
878 /* IBM */
879 if (device_id == 0x0046 || device_id == 0xFFFF) {
880 /* MPIC & MPIC2 */
881 pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
884 break;
885 case 0xff00:
886 if (vendor_id == 0x0106b &&
887 (device_id == 0x0017 || device_id == 0x0022)) {
888 /* macio bridge */
889 pci_set_io_region_addr(d, 0, 0x80800000);
891 break;
892 default:
893 default_map:
894 /* default memory mappings */
895 for(i = 0; i < PCI_NUM_REGIONS; i++) {
896 int ofs;
897 uint32_t val, size ;
899 if (i == PCI_ROM_SLOT)
900 ofs = 0x30;
901 else
902 ofs = 0x10 + i * 4;
903 pci_config_writel(d, ofs, 0xffffffff);
904 val = pci_config_readl(d, ofs);
905 if (val != 0) {
906 size = (~(val & ~0xf)) + 1;
907 if (val & PCI_ADDRESS_SPACE_IO)
908 paddr = &pci_bios_io_addr;
909 else if (size >= 0x04000000)
910 paddr = &pci_bios_bigmem_addr;
911 else
912 paddr = &pci_bios_mem_addr;
913 *paddr = (*paddr + size - 1) & ~(size - 1);
914 pci_set_io_region_addr(d, i, *paddr);
915 *paddr += size;
918 break;
921 /* map the interrupt */
922 pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
923 if (pin != 0) {
924 pin = pci_slot_get_pirq(d, pin - 1);
925 pic_irq = pci_irqs[pin];
926 pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
929 if (vendor_id == 0x8086 && device_id == 0x7113) {
930 /* PIIX4 Power Management device (for ACPI) */
932 // acpi sci is hardwired to 9
933 pci_config_writeb(d, PCI_INTERRUPT_LINE, 9);
935 pm_io_base = PM_IO_BASE;
936 pci_config_writel(d, 0x40, pm_io_base | 1);
937 pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
938 smb_io_base = SMB_IO_BASE;
939 pci_config_writel(d, 0x90, smb_io_base | 1);
940 pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
941 pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
942 #ifdef BX_USE_SMM
943 smm_init(d);
944 #endif
945 acpi_enabled = 1;
949 void pci_for_each_device(void (*init_func)(PCIDevice *d))
951 PCIDevice d1, *d = &d1;
952 int bus, devfn;
953 uint16_t vendor_id, device_id;
955 for(bus = 0; bus < 1; bus++) {
956 for(devfn = 0; devfn < 256; devfn++) {
957 d->bus = bus;
958 d->devfn = devfn;
959 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
960 device_id = pci_config_readw(d, PCI_DEVICE_ID);
961 if (vendor_id != 0xffff || device_id != 0xffff) {
962 init_func(d);
968 void pci_bios_init(void)
970 pci_bios_io_addr = 0xc000;
971 pci_bios_mem_addr = 0xf0000000;
972 pci_bios_bigmem_addr = ram_size;
973 if (pci_bios_bigmem_addr < 0x90000000)
974 pci_bios_bigmem_addr = 0x90000000;
976 pci_for_each_device(pci_bios_init_bridges);
978 pci_for_each_device(pci_bios_init_device);
981 /****************************************************/
982 /* Multi Processor table init */
984 static void putb(uint8_t **pp, int val)
986 uint8_t *q;
987 q = *pp;
988 *q++ = val;
989 *pp = q;
992 static void putstr(uint8_t **pp, const char *str)
994 uint8_t *q;
995 q = *pp;
996 while (*str)
997 *q++ = *str++;
998 *pp = q;
1001 static void putle16(uint8_t **pp, int val)
1003 uint8_t *q;
1004 q = *pp;
1005 *q++ = val;
1006 *q++ = val >> 8;
1007 *pp = q;
1010 static void putle32(uint8_t **pp, int val)
1012 uint8_t *q;
1013 q = *pp;
1014 *q++ = val;
1015 *q++ = val >> 8;
1016 *q++ = val >> 16;
1017 *q++ = val >> 24;
1018 *pp = q;
1021 static int mpf_checksum(const uint8_t *data, int len)
1023 int sum, i;
1024 sum = 0;
1025 for(i = 0; i < len; i++)
1026 sum += data[i];
1027 return sum & 0xff;
1030 static unsigned long align(unsigned long addr, unsigned long v)
1032 return (addr + v - 1) & ~(v - 1);
1035 static void mptable_init(void)
1037 uint8_t *mp_config_table, *q, *float_pointer_struct;
1038 int ioapic_id, i, len;
1039 int mp_config_table_size;
1041 #ifdef BX_USE_EBDA_TABLES
1042 mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
1043 #else
1044 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1045 mp_config_table = (uint8_t *)bios_table_cur_addr;
1046 #endif
1047 q = mp_config_table;
1048 putstr(&q, "PCMP"); /* "PCMP signature */
1049 putle16(&q, 0); /* table length (patched later) */
1050 putb(&q, 4); /* spec rev */
1051 putb(&q, 0); /* checksum (patched later) */
1052 #ifdef BX_QEMU
1053 putstr(&q, "QEMUCPU "); /* OEM id */
1054 #else
1055 putstr(&q, "BOCHSCPU");
1056 #endif
1057 putstr(&q, "0.1 "); /* vendor id */
1058 putle32(&q, 0); /* OEM table ptr */
1059 putle16(&q, 0); /* OEM table size */
1060 putle16(&q, MAX_CPUS + 18); /* entry count */
1061 putle32(&q, 0xfee00000); /* local APIC addr */
1062 putle16(&q, 0); /* ext table length */
1063 putb(&q, 0); /* ext table checksum */
1064 putb(&q, 0); /* reserved */
1066 for(i = 0; i < MAX_CPUS ; i++) {
1067 putb(&q, 0); /* entry type = processor */
1068 putb(&q, i); /* APIC id */
1069 putb(&q, 0x11); /* local APIC version number */
1070 if (i == 0)
1071 putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
1072 else if ( i < smp_cpus)
1073 putb(&q, 1); /* cpu flags: enabled */
1074 else
1075 putb(&q, 0); /* cpu flags: disabled */
1076 putb(&q, 0); /* cpu signature */
1077 putb(&q, 6);
1078 putb(&q, 0);
1079 putb(&q, 0);
1080 putle16(&q, 0x201); /* feature flags */
1081 putle16(&q, 0);
1083 putle16(&q, 0); /* reserved */
1084 putle16(&q, 0);
1085 putle16(&q, 0);
1086 putle16(&q, 0);
1089 /* isa bus */
1090 putb(&q, 1); /* entry type = bus */
1091 putb(&q, 0); /* bus ID */
1092 putstr(&q, "ISA ");
1094 /* ioapic */
1095 ioapic_id = smp_cpus;
1096 putb(&q, 2); /* entry type = I/O APIC */
1097 putb(&q, ioapic_id); /* apic ID */
1098 putb(&q, 0x11); /* I/O APIC version number */
1099 putb(&q, 1); /* enable */
1100 putle32(&q, 0xfec00000); /* I/O APIC addr */
1102 /* irqs */
1103 for(i = 0; i < 16; i++) {
1104 putb(&q, 3); /* entry type = I/O interrupt */
1105 putb(&q, 0); /* interrupt type = vectored interrupt */
1106 putb(&q, 0); /* flags: po=0, el=0 */
1107 putb(&q, 0);
1108 putb(&q, 0); /* source bus ID = ISA */
1109 putb(&q, i); /* source bus IRQ */
1110 putb(&q, ioapic_id); /* dest I/O APIC ID */
1111 putb(&q, i); /* dest I/O APIC interrupt in */
1113 /* patch length */
1114 len = q - mp_config_table;
1115 mp_config_table[4] = len;
1116 mp_config_table[5] = len >> 8;
1118 mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
1120 mp_config_table_size = q - mp_config_table;
1122 #ifndef BX_USE_EBDA_TABLES
1123 bios_table_cur_addr += mp_config_table_size;
1124 #endif
1126 /* floating pointer structure */
1127 #ifdef BX_USE_EBDA_TABLES
1128 ebda_cur_addr = align(ebda_cur_addr, 16);
1129 float_pointer_struct = (uint8_t *)ebda_cur_addr;
1130 #else
1131 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1132 float_pointer_struct = (uint8_t *)bios_table_cur_addr;
1133 #endif
1134 q = float_pointer_struct;
1135 putstr(&q, "_MP_");
1136 /* pointer to MP config table */
1137 putle32(&q, (unsigned long)mp_config_table);
1139 putb(&q, 1); /* length in 16 byte units */
1140 putb(&q, 4); /* MP spec revision */
1141 putb(&q, 0); /* checksum (patched later) */
1142 putb(&q, 0); /* MP feature byte 1 */
1144 putb(&q, 0);
1145 putb(&q, 0);
1146 putb(&q, 0);
1147 putb(&q, 0);
1148 float_pointer_struct[10] =
1149 -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
1150 #ifdef BX_USE_EBDA_TABLES
1151 ebda_cur_addr += (q - float_pointer_struct);
1152 #else
1153 bios_table_cur_addr += (q - float_pointer_struct);
1154 #endif
1155 BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
1156 (unsigned long)float_pointer_struct,
1157 (unsigned long)mp_config_table,
1158 mp_config_table_size);
1161 /****************************************************/
1162 /* ACPI tables init */
1164 /* Table structure from Linux kernel (the ACPI tables are under the
1165 BSD license) */
1167 #define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
1168 uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\
1169 uint32_t length; /* Length of table, in bytes, including header */\
1170 uint8_t revision; /* ACPI Specification minor version # */\
1171 uint8_t checksum; /* To make sum of entire table == 0 */\
1172 uint8_t oem_id [6]; /* OEM identification */\
1173 uint8_t oem_table_id [8]; /* OEM table identification */\
1174 uint32_t oem_revision; /* OEM revision number */\
1175 uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\
1176 uint32_t asl_compiler_revision; /* ASL compiler revision number */
1179 struct acpi_table_header /* ACPI common table header */
1181 ACPI_TABLE_HEADER_DEF
1184 struct rsdp_descriptor /* Root System Descriptor Pointer */
1186 uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */
1187 uint8_t checksum; /* To make sum of struct == 0 */
1188 uint8_t oem_id [6]; /* OEM identification */
1189 uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */
1190 uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */
1191 uint32_t length; /* XSDT Length in bytes including hdr */
1192 uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */
1193 uint8_t extended_checksum; /* Checksum of entire table */
1194 uint8_t reserved [3]; /* Reserved field must be 0 */
1198 * ACPI 1.0 Root System Description Table (RSDT)
1200 struct rsdt_descriptor_rev1
1202 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1203 uint32_t table_offset_entry [2]; /* Array of pointers to other */
1204 /* ACPI tables */
1208 * ACPI 1.0 Firmware ACPI Control Structure (FACS)
1210 struct facs_descriptor_rev1
1212 uint8_t signature[4]; /* ACPI Signature */
1213 uint32_t length; /* Length of structure, in bytes */
1214 uint32_t hardware_signature; /* Hardware configuration signature */
1215 uint32_t firmware_waking_vector; /* ACPI OS waking vector */
1216 uint32_t global_lock; /* Global Lock */
1217 uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */
1218 uint32_t reserved1 : 31; /* Must be 0 */
1219 uint8_t resverved3 [40]; /* Reserved - must be zero */
1224 * ACPI 1.0 Fixed ACPI Description Table (FADT)
1226 struct fadt_descriptor_rev1
1228 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1229 uint32_t firmware_ctrl; /* Physical address of FACS */
1230 uint32_t dsdt; /* Physical address of DSDT */
1231 uint8_t model; /* System Interrupt Model */
1232 uint8_t reserved1; /* Reserved */
1233 uint16_t sci_int; /* System vector of SCI interrupt */
1234 uint32_t smi_cmd; /* Port address of SMI command port */
1235 uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */
1236 uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */
1237 uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
1238 uint8_t reserved2; /* Reserved - must be zero */
1239 uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
1240 uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
1241 uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
1242 uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
1243 uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
1244 uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
1245 uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
1246 uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
1247 uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
1248 uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
1249 uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
1250 uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
1251 uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
1252 uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
1253 uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */
1254 uint8_t reserved3; /* Reserved */
1255 uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
1256 uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
1257 uint16_t flush_size; /* Size of area read to flush caches */
1258 uint16_t flush_stride; /* Stride used in flushing caches */
1259 uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */
1260 uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */
1261 uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
1262 uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
1263 uint8_t century; /* Index to century in RTC CMOS RAM */
1264 uint8_t reserved4; /* Reserved */
1265 uint8_t reserved4a; /* Reserved */
1266 uint8_t reserved4b; /* Reserved */
1267 #if 0
1268 uint32_t wb_invd : 1; /* The wbinvd instruction works properly */
1269 uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
1270 uint32_t proc_c1 : 1; /* All processors support C1 state */
1271 uint32_t plvl2_up : 1; /* C2 state works on MP system */
1272 uint32_t pwr_button : 1; /* Power button is handled as a generic feature */
1273 uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
1274 uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
1275 uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
1276 uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */
1277 uint32_t reserved5 : 23; /* Reserved - must be zero */
1278 #else
1279 uint32_t flags;
1280 #endif
1284 * MADT values and structures
1287 /* Values for MADT PCATCompat */
1289 #define DUAL_PIC 0
1290 #define MULTIPLE_APIC 1
1293 /* Master MADT */
1295 struct multiple_apic_table
1297 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1298 uint32_t local_apic_address; /* Physical address of local APIC */
1299 #if 0
1300 uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */
1301 uint32_t reserved1 : 31;
1302 #else
1303 uint32_t flags;
1304 #endif
1308 /* Values for Type in APIC_HEADER_DEF */
1310 #define APIC_PROCESSOR 0
1311 #define APIC_IO 1
1312 #define APIC_XRUPT_OVERRIDE 2
1313 #define APIC_NMI 3
1314 #define APIC_LOCAL_NMI 4
1315 #define APIC_ADDRESS_OVERRIDE 5
1316 #define APIC_IO_SAPIC 6
1317 #define APIC_LOCAL_SAPIC 7
1318 #define APIC_XRUPT_SOURCE 8
1319 #define APIC_RESERVED 9 /* 9 and greater are reserved */
1322 * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
1324 #define APIC_HEADER_DEF /* Common APIC sub-structure header */\
1325 uint8_t type; \
1326 uint8_t length;
1328 /* Sub-structures for MADT */
1330 struct madt_processor_apic
1332 APIC_HEADER_DEF
1333 uint8_t processor_id; /* ACPI processor id */
1334 uint8_t local_apic_id; /* Processor's local APIC id */
1335 #if 0
1336 uint32_t processor_enabled: 1; /* Processor is usable if set */
1337 uint32_t reserved2 : 31; /* Reserved, must be zero */
1338 #else
1339 uint32_t flags;
1340 #endif
1343 struct madt_io_apic
1345 APIC_HEADER_DEF
1346 uint8_t io_apic_id; /* I/O APIC ID */
1347 uint8_t reserved; /* Reserved - must be zero */
1348 uint32_t address; /* APIC physical address */
1349 uint32_t interrupt; /* Global system interrupt where INTI
1350 * lines start */
1353 struct madt_intsrcovr {
1354 APIC_HEADER_DEF
1355 uint8_t bus;
1356 uint8_t source;
1357 uint32_t gsi;
1358 uint16_t flags;
1359 } __attribute__((packed));
1361 #include "acpi-dsdt.hex"
1363 static inline uint16_t cpu_to_le16(uint16_t x)
1365 return x;
1368 static inline uint32_t cpu_to_le32(uint32_t x)
1370 return x;
1373 static int acpi_checksum(const uint8_t *data, int len)
1375 int sum, i;
1376 sum = 0;
1377 for(i = 0; i < len; i++)
1378 sum += data[i];
1379 return (-sum) & 0xff;
1382 static void acpi_build_table_header(struct acpi_table_header *h,
1383 char *sig, int len, uint8_t rev)
1385 memcpy(h->signature, sig, 4);
1386 h->length = cpu_to_le32(len);
1387 h->revision = rev;
1388 #ifdef BX_QEMU
1389 memcpy(h->oem_id, "QEMU ", 6);
1390 memcpy(h->oem_table_id, "QEMU", 4);
1391 #else
1392 memcpy(h->oem_id, "BOCHS ", 6);
1393 memcpy(h->oem_table_id, "BXPC", 4);
1394 #endif
1395 memcpy(h->oem_table_id + 4, sig, 4);
1396 h->oem_revision = cpu_to_le32(1);
1397 #ifdef BX_QEMU
1398 memcpy(h->asl_compiler_id, "QEMU", 4);
1399 #else
1400 memcpy(h->asl_compiler_id, "BXPC", 4);
1401 #endif
1402 h->asl_compiler_revision = cpu_to_le32(1);
1403 h->checksum = acpi_checksum((void *)h, len);
1406 /* base_addr must be a multiple of 4KB */
1407 void acpi_bios_init(void)
1409 struct rsdp_descriptor *rsdp;
1410 struct rsdt_descriptor_rev1 *rsdt;
1411 struct fadt_descriptor_rev1 *fadt;
1412 struct facs_descriptor_rev1 *facs;
1413 struct multiple_apic_table *madt;
1414 uint8_t *dsdt;
1415 uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr;
1416 uint32_t acpi_tables_size, madt_addr, madt_size;
1417 int i;
1419 /* reserve memory space for tables */
1420 #ifdef BX_USE_EBDA_TABLES
1421 ebda_cur_addr = align(ebda_cur_addr, 16);
1422 rsdp = (void *)(ebda_cur_addr);
1423 ebda_cur_addr += sizeof(*rsdp);
1424 #else
1425 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1426 rsdp = (void *)(bios_table_cur_addr);
1427 bios_table_cur_addr += sizeof(*rsdp);
1428 #endif
1430 addr = base_addr = ram_size - ACPI_DATA_SIZE;
1431 rsdt_addr = addr;
1432 rsdt = (void *)(addr);
1433 addr += sizeof(*rsdt);
1435 fadt_addr = addr;
1436 fadt = (void *)(addr);
1437 addr += sizeof(*fadt);
1439 /* XXX: FACS should be in RAM */
1440 addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
1441 facs_addr = addr;
1442 facs = (void *)(addr);
1443 addr += sizeof(*facs);
1445 dsdt_addr = addr;
1446 dsdt = (void *)(addr);
1447 addr += sizeof(AmlCode);
1449 addr = (addr + 7) & ~7;
1450 madt_addr = addr;
1451 madt_size = sizeof(*madt) +
1452 sizeof(struct madt_processor_apic) * MAX_CPUS +
1453 sizeof(struct madt_io_apic);
1454 madt = (void *)(addr);
1455 addr += madt_size;
1457 acpi_tables_size = addr - base_addr;
1459 BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
1460 (unsigned long)rsdp,
1461 (unsigned long)rsdt, acpi_tables_size);
1463 /* RSDP */
1464 memset(rsdp, 0, sizeof(*rsdp));
1465 memcpy(rsdp->signature, "RSD PTR ", 8);
1466 #ifdef BX_QEMU
1467 memcpy(rsdp->oem_id, "QEMU ", 6);
1468 #else
1469 memcpy(rsdp->oem_id, "BOCHS ", 6);
1470 #endif
1471 rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
1472 rsdp->checksum = acpi_checksum((void *)rsdp, 20);
1474 /* RSDT */
1475 memset(rsdt, 0, sizeof(*rsdt));
1476 rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
1477 rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
1478 acpi_build_table_header((struct acpi_table_header *)rsdt,
1479 "RSDT", sizeof(*rsdt), 1);
1481 /* FADT */
1482 memset(fadt, 0, sizeof(*fadt));
1483 fadt->firmware_ctrl = cpu_to_le32(facs_addr);
1484 fadt->dsdt = cpu_to_le32(dsdt_addr);
1485 fadt->model = 1;
1486 fadt->reserved1 = 0;
1487 fadt->sci_int = cpu_to_le16(pm_sci_int);
1488 fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
1489 fadt->acpi_enable = 0xf1;
1490 fadt->acpi_disable = 0xf0;
1491 fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
1492 fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
1493 fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
1494 fadt->pm1_evt_len = 4;
1495 fadt->pm1_cnt_len = 2;
1496 fadt->pm_tmr_len = 4;
1497 fadt->plvl2_lat = cpu_to_le16(0x0fff); // C2 state not supported
1498 fadt->plvl3_lat = cpu_to_le16(0x0fff); // C3 state not supported
1499 fadt->gpe0_blk = cpu_to_le32(0xafe0);
1500 fadt->gpe0_blk_len = 4;
1501 /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */
1502 fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6));
1503 acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
1504 sizeof(*fadt), 1);
1506 /* FACS */
1507 memset(facs, 0, sizeof(*facs));
1508 memcpy(facs->signature, "FACS", 4);
1509 facs->length = cpu_to_le32(sizeof(*facs));
1511 /* DSDT */
1512 memcpy(dsdt, AmlCode, sizeof(AmlCode));
1514 /* MADT */
1516 struct madt_processor_apic *apic;
1517 struct madt_io_apic *io_apic;
1518 struct madt_intsrcovr *intsrcovr;
1520 memset(madt, 0, madt_size);
1521 madt->local_apic_address = cpu_to_le32(0xfee00000);
1522 madt->flags = cpu_to_le32(1);
1523 apic = (void *)(madt + 1);
1524 for(i=0;i<MAX_CPUS;i++) {
1525 apic->type = APIC_PROCESSOR;
1526 apic->length = sizeof(*apic);
1527 apic->processor_id = i;
1528 apic->local_apic_id = i;
1529 if (i < smp_cpus)
1530 apic->flags = cpu_to_le32(1);
1531 else
1532 apic->flags = 0;
1533 apic++;
1535 io_apic = (void *)apic;
1536 io_apic->type = APIC_IO;
1537 io_apic->length = sizeof(*io_apic);
1538 io_apic->io_apic_id = smp_cpus;
1539 io_apic->address = cpu_to_le32(0xfec00000);
1540 io_apic->interrupt = cpu_to_le32(0);
1542 intsrcovr = (struct madt_intsrcovr*)(io_apic + 1);
1543 for ( i = 0; i < 16; i++ ) {
1544 if ( PCI_ISA_IRQ_MASK & (1U << i) ) {
1545 memset(intsrcovr, 0, sizeof(*intsrcovr));
1546 intsrcovr->type = APIC_XRUPT_OVERRIDE;
1547 intsrcovr->length = sizeof(*intsrcovr);
1548 intsrcovr->source = i;
1549 intsrcovr->gsi = i;
1550 intsrcovr->flags = 0xd; /* active high, level triggered */
1551 } else {
1552 /* No need for a INT source override structure. */
1553 continue;
1555 intsrcovr++;
1556 madt_size += sizeof(struct madt_intsrcovr);
1558 acpi_build_table_header((struct acpi_table_header *)madt,
1559 "APIC", madt_size, 1);
1563 /* SMBIOS entry point -- must be written to a 16-bit aligned address
1564 between 0xf0000 and 0xfffff.
1566 struct smbios_entry_point {
1567 char anchor_string[4];
1568 uint8_t checksum;
1569 uint8_t length;
1570 uint8_t smbios_major_version;
1571 uint8_t smbios_minor_version;
1572 uint16_t max_structure_size;
1573 uint8_t entry_point_revision;
1574 uint8_t formatted_area[5];
1575 char intermediate_anchor_string[5];
1576 uint8_t intermediate_checksum;
1577 uint16_t structure_table_length;
1578 uint32_t structure_table_address;
1579 uint16_t number_of_structures;
1580 uint8_t smbios_bcd_revision;
1581 } __attribute__((__packed__));
1583 /* This goes at the beginning of every SMBIOS structure. */
1584 struct smbios_structure_header {
1585 uint8_t type;
1586 uint8_t length;
1587 uint16_t handle;
1588 } __attribute__((__packed__));
1590 /* SMBIOS type 0 - BIOS Information */
1591 struct smbios_type_0 {
1592 struct smbios_structure_header header;
1593 uint8_t vendor_str;
1594 uint8_t bios_version_str;
1595 uint16_t bios_starting_address_segment;
1596 uint8_t bios_release_date_str;
1597 uint8_t bios_rom_size;
1598 uint8_t bios_characteristics[8];
1599 uint8_t bios_characteristics_extension_bytes[2];
1600 uint8_t system_bios_major_release;
1601 uint8_t system_bios_minor_release;
1602 uint8_t embedded_controller_major_release;
1603 uint8_t embedded_controller_minor_release;
1604 } __attribute__((__packed__));
1606 /* SMBIOS type 1 - System Information */
1607 struct smbios_type_1 {
1608 struct smbios_structure_header header;
1609 uint8_t manufacturer_str;
1610 uint8_t product_name_str;
1611 uint8_t version_str;
1612 uint8_t serial_number_str;
1613 uint8_t uuid[16];
1614 uint8_t wake_up_type;
1615 uint8_t sku_number_str;
1616 uint8_t family_str;
1617 } __attribute__((__packed__));
1619 /* SMBIOS type 3 - System Enclosure (v2.3) */
1620 struct smbios_type_3 {
1621 struct smbios_structure_header header;
1622 uint8_t manufacturer_str;
1623 uint8_t type;
1624 uint8_t version_str;
1625 uint8_t serial_number_str;
1626 uint8_t asset_tag_number_str;
1627 uint8_t boot_up_state;
1628 uint8_t power_supply_state;
1629 uint8_t thermal_state;
1630 uint8_t security_status;
1631 uint32_t oem_defined;
1632 uint8_t height;
1633 uint8_t number_of_power_cords;
1634 uint8_t contained_element_count;
1635 // contained elements follow
1636 } __attribute__((__packed__));
1638 /* SMBIOS type 4 - Processor Information (v2.0) */
1639 struct smbios_type_4 {
1640 struct smbios_structure_header header;
1641 uint8_t socket_designation_str;
1642 uint8_t processor_type;
1643 uint8_t processor_family;
1644 uint8_t processor_manufacturer_str;
1645 uint32_t processor_id[2];
1646 uint8_t processor_version_str;
1647 uint8_t voltage;
1648 uint16_t external_clock;
1649 uint16_t max_speed;
1650 uint16_t current_speed;
1651 uint8_t status;
1652 uint8_t processor_upgrade;
1653 } __attribute__((__packed__));
1655 /* SMBIOS type 16 - Physical Memory Array
1656 * Associated with one type 17 (Memory Device).
1658 struct smbios_type_16 {
1659 struct smbios_structure_header header;
1660 uint8_t location;
1661 uint8_t use;
1662 uint8_t error_correction;
1663 uint32_t maximum_capacity;
1664 uint16_t memory_error_information_handle;
1665 uint16_t number_of_memory_devices;
1666 } __attribute__((__packed__));
1668 /* SMBIOS type 17 - Memory Device
1669 * Associated with one type 19
1671 struct smbios_type_17 {
1672 struct smbios_structure_header header;
1673 uint16_t physical_memory_array_handle;
1674 uint16_t memory_error_information_handle;
1675 uint16_t total_width;
1676 uint16_t data_width;
1677 uint16_t size;
1678 uint8_t form_factor;
1679 uint8_t device_set;
1680 uint8_t device_locator_str;
1681 uint8_t bank_locator_str;
1682 uint8_t memory_type;
1683 uint16_t type_detail;
1684 } __attribute__((__packed__));
1686 /* SMBIOS type 19 - Memory Array Mapped Address */
1687 struct smbios_type_19 {
1688 struct smbios_structure_header header;
1689 uint32_t starting_address;
1690 uint32_t ending_address;
1691 uint16_t memory_array_handle;
1692 uint8_t partition_width;
1693 } __attribute__((__packed__));
1695 /* SMBIOS type 20 - Memory Device Mapped Address */
1696 struct smbios_type_20 {
1697 struct smbios_structure_header header;
1698 uint32_t starting_address;
1699 uint32_t ending_address;
1700 uint16_t memory_device_handle;
1701 uint16_t memory_array_mapped_address_handle;
1702 uint8_t partition_row_position;
1703 uint8_t interleave_position;
1704 uint8_t interleaved_data_depth;
1705 } __attribute__((__packed__));
1707 /* SMBIOS type 32 - System Boot Information */
1708 struct smbios_type_32 {
1709 struct smbios_structure_header header;
1710 uint8_t reserved[6];
1711 uint8_t boot_status;
1712 } __attribute__((__packed__));
1714 /* SMBIOS type 127 -- End-of-table */
1715 struct smbios_type_127 {
1716 struct smbios_structure_header header;
1717 } __attribute__((__packed__));
1719 static void
1720 smbios_entry_point_init(void *start,
1721 uint16_t max_structure_size,
1722 uint16_t structure_table_length,
1723 uint32_t structure_table_address,
1724 uint16_t number_of_structures)
1726 uint8_t sum;
1727 int i;
1728 struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
1730 memcpy(ep->anchor_string, "_SM_", 4);
1731 ep->length = 0x1f;
1732 ep->smbios_major_version = 2;
1733 ep->smbios_minor_version = 4;
1734 ep->max_structure_size = max_structure_size;
1735 ep->entry_point_revision = 0;
1736 memset(ep->formatted_area, 0, 5);
1737 memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
1739 ep->structure_table_length = structure_table_length;
1740 ep->structure_table_address = structure_table_address;
1741 ep->number_of_structures = number_of_structures;
1742 ep->smbios_bcd_revision = 0x24;
1744 ep->checksum = 0;
1745 ep->intermediate_checksum = 0;
1747 sum = 0;
1748 for (i = 0; i < 0x10; i++)
1749 sum += ((int8_t *)start)[i];
1750 ep->checksum = -sum;
1752 sum = 0;
1753 for (i = 0x10; i < ep->length; i++)
1754 sum += ((int8_t *)start)[i];
1755 ep->intermediate_checksum = -sum;
1758 /* Type 0 -- BIOS Information */
1759 #define RELEASE_DATE_STR "01/01/2007"
1760 static void *
1761 smbios_type_0_init(void *start)
1763 struct smbios_type_0 *p = (struct smbios_type_0 *)start;
1765 p->header.type = 0;
1766 p->header.length = sizeof(struct smbios_type_0);
1767 p->header.handle = 0;
1769 p->vendor_str = 1;
1770 p->bios_version_str = 1;
1771 p->bios_starting_address_segment = 0xe800;
1772 p->bios_release_date_str = 2;
1773 p->bios_rom_size = 0; /* FIXME */
1775 memset(p->bios_characteristics, 0, 7);
1776 p->bios_characteristics[7] = 0x08; /* BIOS characteristics not supported */
1777 p->bios_characteristics_extension_bytes[0] = 0;
1778 p->bios_characteristics_extension_bytes[1] = 0;
1780 p->system_bios_major_release = 1;
1781 p->system_bios_minor_release = 0;
1782 p->embedded_controller_major_release = 0xff;
1783 p->embedded_controller_minor_release = 0xff;
1785 start += sizeof(struct smbios_type_0);
1786 memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
1787 start += sizeof(BX_APPNAME);
1788 memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
1789 start += sizeof(RELEASE_DATE_STR);
1790 *((uint8_t *)start) = 0;
1792 return start+1;
1795 /* Type 1 -- System Information */
1796 static void *
1797 smbios_type_1_init(void *start)
1799 struct smbios_type_1 *p = (struct smbios_type_1 *)start;
1800 p->header.type = 1;
1801 p->header.length = sizeof(struct smbios_type_1);
1802 p->header.handle = 0x100;
1804 p->manufacturer_str = 0;
1805 p->product_name_str = 0;
1806 p->version_str = 0;
1807 p->serial_number_str = 0;
1809 memcpy(p->uuid, bios_uuid, 16);
1811 p->wake_up_type = 0x06; /* power switch */
1812 p->sku_number_str = 0;
1813 p->family_str = 0;
1815 start += sizeof(struct smbios_type_1);
1816 *((uint16_t *)start) = 0;
1818 return start+2;
1821 /* Type 3 -- System Enclosure */
1822 static void *
1823 smbios_type_3_init(void *start)
1825 struct smbios_type_3 *p = (struct smbios_type_3 *)start;
1827 p->header.type = 3;
1828 p->header.length = sizeof(struct smbios_type_3);
1829 p->header.handle = 0x300;
1831 p->manufacturer_str = 0;
1832 p->type = 0x01; /* other */
1833 p->version_str = 0;
1834 p->serial_number_str = 0;
1835 p->asset_tag_number_str = 0;
1836 p->boot_up_state = 0x03; /* safe */
1837 p->power_supply_state = 0x03; /* safe */
1838 p->thermal_state = 0x03; /* safe */
1839 p->security_status = 0x02; /* unknown */
1840 p->oem_defined = 0;
1841 p->height = 0;
1842 p->number_of_power_cords = 0;
1843 p->contained_element_count = 0;
1845 start += sizeof(struct smbios_type_3);
1846 *((uint16_t *)start) = 0;
1848 return start+2;
1851 /* Type 4 -- Processor Information */
1852 static void *
1853 smbios_type_4_init(void *start, unsigned int cpu_number)
1855 struct smbios_type_4 *p = (struct smbios_type_4 *)start;
1857 p->header.type = 4;
1858 p->header.length = sizeof(struct smbios_type_4);
1859 p->header.handle = 0x400 + cpu_number;
1861 p->socket_designation_str = 1;
1862 p->processor_type = 0x03; /* CPU */
1863 p->processor_family = 0x01; /* other */
1864 p->processor_manufacturer_str = 0;
1866 p->processor_id[0] = cpuid_signature;
1867 p->processor_id[1] = cpuid_features;
1869 p->processor_version_str = 0;
1870 p->voltage = 0;
1871 p->external_clock = 0;
1873 p->max_speed = 0; /* unknown */
1874 p->current_speed = 0; /* unknown */
1876 p->status = 0x41; /* socket populated, CPU enabled */
1877 p->processor_upgrade = 0x01; /* other */
1879 start += sizeof(struct smbios_type_4);
1881 memcpy((char *)start, "CPU " "\0" "" "\0" "", 7);
1882 ((char *)start)[4] = cpu_number + '0';
1884 return start+7;
1887 /* Type 16 -- Physical Memory Array */
1888 static void *
1889 smbios_type_16_init(void *start, uint32_t memsize)
1891 struct smbios_type_16 *p = (struct smbios_type_16*)start;
1893 p->header.type = 16;
1894 p->header.length = sizeof(struct smbios_type_16);
1895 p->header.handle = 0x1000;
1897 p->location = 0x01; /* other */
1898 p->use = 0x03; /* system memory */
1899 p->error_correction = 0x01; /* other */
1900 p->maximum_capacity = memsize * 1024;
1901 p->memory_error_information_handle = 0xfffe; /* none provided */
1902 p->number_of_memory_devices = 1;
1904 start += sizeof(struct smbios_type_16);
1905 *((uint16_t *)start) = 0;
1907 return start + 2;
1910 /* Type 17 -- Memory Device */
1911 static void *
1912 smbios_type_17_init(void *start, uint32_t memory_size_mb)
1914 struct smbios_type_17 *p = (struct smbios_type_17 *)start;
1916 p->header.type = 17;
1917 p->header.length = sizeof(struct smbios_type_17);
1918 p->header.handle = 0x1100;
1920 p->physical_memory_array_handle = 0x1000;
1921 p->total_width = 64;
1922 p->data_width = 64;
1923 /* truncate memory_size_mb to 16 bits and clear most significant
1924 bit [indicates size in MB] */
1925 p->size = (uint16_t) memory_size_mb & 0x7fff;
1926 p->form_factor = 0x09; /* DIMM */
1927 p->device_set = 0;
1928 p->device_locator_str = 1;
1929 p->bank_locator_str = 0;
1930 p->memory_type = 0x07; /* RAM */
1931 p->type_detail = 0;
1933 start += sizeof(struct smbios_type_17);
1934 memcpy((char *)start, "DIMM 1", 7);
1935 start += 7;
1936 *((uint8_t *)start) = 0;
1938 return start+1;
1941 /* Type 19 -- Memory Array Mapped Address */
1942 static void *
1943 smbios_type_19_init(void *start, uint32_t memory_size_mb)
1945 struct smbios_type_19 *p = (struct smbios_type_19 *)start;
1947 p->header.type = 19;
1948 p->header.length = sizeof(struct smbios_type_19);
1949 p->header.handle = 0x1300;
1951 p->starting_address = 0;
1952 p->ending_address = (memory_size_mb-1) * 1024;
1953 p->memory_array_handle = 0x1000;
1954 p->partition_width = 1;
1956 start += sizeof(struct smbios_type_19);
1957 *((uint16_t *)start) = 0;
1959 return start + 2;
1962 /* Type 20 -- Memory Device Mapped Address */
1963 static void *
1964 smbios_type_20_init(void *start, uint32_t memory_size_mb)
1966 struct smbios_type_20 *p = (struct smbios_type_20 *)start;
1968 p->header.type = 20;
1969 p->header.length = sizeof(struct smbios_type_20);
1970 p->header.handle = 0x1400;
1972 p->starting_address = 0;
1973 p->ending_address = (memory_size_mb-1)*1024;
1974 p->memory_device_handle = 0x1100;
1975 p->memory_array_mapped_address_handle = 0x1300;
1976 p->partition_row_position = 1;
1977 p->interleave_position = 0;
1978 p->interleaved_data_depth = 0;
1980 start += sizeof(struct smbios_type_20);
1982 *((uint16_t *)start) = 0;
1983 return start+2;
1986 /* Type 32 -- System Boot Information */
1987 static void *
1988 smbios_type_32_init(void *start)
1990 struct smbios_type_32 *p = (struct smbios_type_32 *)start;
1992 p->header.type = 32;
1993 p->header.length = sizeof(struct smbios_type_32);
1994 p->header.handle = 0x2000;
1995 memset(p->reserved, 0, 6);
1996 p->boot_status = 0; /* no errors detected */
1998 start += sizeof(struct smbios_type_32);
1999 *((uint16_t *)start) = 0;
2001 return start+2;
2004 /* Type 127 -- End of Table */
2005 static void *
2006 smbios_type_127_init(void *start)
2008 struct smbios_type_127 *p = (struct smbios_type_127 *)start;
2010 p->header.type = 127;
2011 p->header.length = sizeof(struct smbios_type_127);
2012 p->header.handle = 0x7f00;
2014 start += sizeof(struct smbios_type_127);
2015 *((uint16_t *)start) = 0;
2017 return start + 2;
2020 void smbios_init(void)
2022 unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
2023 char *start, *p, *q;
2024 int memsize = ram_size / (1024 * 1024);
2026 #ifdef BX_USE_EBDA_TABLES
2027 ebda_cur_addr = align(ebda_cur_addr, 16);
2028 start = (void *)(ebda_cur_addr);
2029 #else
2030 bios_table_cur_addr = align(bios_table_cur_addr, 16);
2031 start = (void *)(bios_table_cur_addr);
2032 #endif
2034 p = (char *)start + sizeof(struct smbios_entry_point);
2036 #define add_struct(fn) { \
2037 q = (fn); \
2038 nr_structs++; \
2039 if ((q - p) > max_struct_size) \
2040 max_struct_size = q - p; \
2041 p = q; \
2044 add_struct(smbios_type_0_init(p));
2045 add_struct(smbios_type_1_init(p));
2046 add_struct(smbios_type_3_init(p));
2047 for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
2048 add_struct(smbios_type_4_init(p, cpu_num));
2049 add_struct(smbios_type_16_init(p, memsize));
2050 add_struct(smbios_type_17_init(p, memsize));
2051 add_struct(smbios_type_19_init(p, memsize));
2052 add_struct(smbios_type_20_init(p, memsize));
2053 add_struct(smbios_type_32_init(p));
2054 add_struct(smbios_type_127_init(p));
2056 #undef add_struct
2058 smbios_entry_point_init(
2059 start, max_struct_size,
2060 (p - (char *)start) - sizeof(struct smbios_entry_point),
2061 (uint32_t)(start + sizeof(struct smbios_entry_point)),
2062 nr_structs);
2064 #ifdef BX_USE_EBDA_TABLES
2065 ebda_cur_addr += (p - (char *)start);
2066 #else
2067 bios_table_cur_addr += (p - (char *)start);
2068 #endif
2070 BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
2073 void rombios32_init(void)
2075 BX_INFO("Starting rombios32\n");
2077 init_smp_msrs();
2079 ram_probe();
2081 cpu_probe();
2083 smp_probe();
2085 uuid_probe();
2087 pci_bios_init();
2089 if (bios_table_cur_addr != 0) {
2091 mptable_init();
2093 smbios_init();
2095 if (acpi_enabled)
2096 acpi_bios_init();
2098 bios_lock_shadow_ram();
2100 BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
2101 if (bios_table_cur_addr > bios_table_end_addr)
2102 BX_PANIC("bios_table_end_addr overflow!\n");