Merged patches from @SF tracker for BIOS
[gplbios.git] / rombios32.c
blob47b6d93be3bf87035f4bcd10807d1d0f69cf68d1
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 0x10000
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 size_t strlen(const char *s)
185 const char *s1;
186 for(s1 = s; *s1 != '\0'; s1++);
187 return s1 - s;
190 /* from BSD ppp sources */
191 int vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
193 int c, i, n;
194 int width, prec, fillch;
195 int base, len, neg;
196 unsigned long val = 0;
197 const char *f;
198 char *str, *buf0;
199 char num[32];
200 static const char hexchars[] = "0123456789abcdef";
202 buf0 = buf;
203 --buflen;
204 while (buflen > 0) {
205 for (f = fmt; *f != '%' && *f != 0; ++f)
207 if (f > fmt) {
208 len = f - fmt;
209 if (len > buflen)
210 len = buflen;
211 memcpy(buf, fmt, len);
212 buf += len;
213 buflen -= len;
214 fmt = f;
216 if (*fmt == 0)
217 break;
218 c = *++fmt;
219 width = prec = 0;
220 fillch = ' ';
221 if (c == '0') {
222 fillch = '0';
223 c = *++fmt;
225 if (c == '*') {
226 width = va_arg(args, int);
227 c = *++fmt;
228 } else {
229 while (isdigit(c)) {
230 width = width * 10 + c - '0';
231 c = *++fmt;
234 if (c == '.') {
235 c = *++fmt;
236 if (c == '*') {
237 prec = va_arg(args, int);
238 c = *++fmt;
239 } else {
240 while (isdigit(c)) {
241 prec = prec * 10 + c - '0';
242 c = *++fmt;
246 /* modifiers */
247 switch(c) {
248 case 'l':
249 c = *++fmt;
250 break;
251 default:
252 break;
254 str = 0;
255 base = 0;
256 neg = 0;
257 ++fmt;
258 switch (c) {
259 case 'd':
260 i = va_arg(args, int);
261 if (i < 0) {
262 neg = 1;
263 val = -i;
264 } else
265 val = i;
266 base = 10;
267 break;
268 case 'o':
269 val = va_arg(args, unsigned int);
270 base = 8;
271 break;
272 case 'x':
273 case 'X':
274 val = va_arg(args, unsigned int);
275 base = 16;
276 break;
277 case 'p':
278 val = (unsigned long) va_arg(args, void *);
279 base = 16;
280 neg = 2;
281 break;
282 case 's':
283 str = va_arg(args, char *);
284 break;
285 case 'c':
286 num[0] = va_arg(args, int);
287 num[1] = 0;
288 str = num;
289 break;
290 default:
291 *buf++ = '%';
292 if (c != '%')
293 --fmt; /* so %z outputs %z etc. */
294 --buflen;
295 continue;
297 if (base != 0) {
298 str = num + sizeof(num);
299 *--str = 0;
300 while (str > num + neg) {
301 *--str = hexchars[val % base];
302 val = val / base;
303 if (--prec <= 0 && val == 0)
304 break;
306 switch (neg) {
307 case 1:
308 *--str = '-';
309 break;
310 case 2:
311 *--str = 'x';
312 *--str = '0';
313 break;
315 len = num + sizeof(num) - 1 - str;
316 } else {
317 len = strlen(str);
318 if (prec > 0 && len > prec)
319 len = prec;
321 if (width > 0) {
322 if (width > buflen)
323 width = buflen;
324 if ((n = width - len) > 0) {
325 buflen -= n;
326 for (; n > 0; --n)
327 *buf++ = fillch;
330 if (len > buflen)
331 len = buflen;
332 memcpy(buf, str, len);
333 buf += len;
334 buflen -= len;
336 *buf = 0;
337 return buf - buf0;
340 void bios_printf(int flags, const char *fmt, ...)
342 va_list ap;
343 char buf[1024];
344 const char *s;
346 if ((flags & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT)
347 outb(PANIC_PORT2, 0x00);
349 va_start(ap, fmt);
350 vsnprintf(buf, sizeof(buf), fmt, ap);
351 s = buf;
352 while (*s)
353 putc(*s++);
354 va_end(ap);
357 void delay_ms(int n)
359 int i, j;
360 for(i = 0; i < n; i++) {
361 #ifdef BX_QEMU
362 /* approximative ! */
363 for(j = 0; j < 1000000; j++);
364 #else
366 int r1, r2;
367 j = 66;
368 r1 = inb(0x61) & 0x10;
369 do {
370 r2 = inb(0x61) & 0x10;
371 if (r1 != r2) {
372 j--;
373 r1 = r2;
375 } while (j > 0);
377 #endif
381 int smp_cpus;
382 uint32_t cpuid_signature;
383 uint32_t cpuid_features;
384 uint32_t cpuid_ext_features;
385 unsigned long ram_size;
386 uint8_t bios_uuid[16];
387 #ifdef BX_USE_EBDA_TABLES
388 unsigned long ebda_cur_addr;
389 #endif
390 int acpi_enabled;
391 uint32_t pm_io_base, smb_io_base;
392 int pm_sci_int;
393 unsigned long bios_table_cur_addr;
394 unsigned long bios_table_end_addr;
396 void uuid_probe(void)
398 #ifdef BX_QEMU
399 uint32_t eax, ebx, ecx, edx;
401 // check if backdoor port exists
402 asm volatile ("outl %%eax, %%dx"
403 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
404 : "a" (0x564d5868), "c" (0xa), "d" (0x5658));
405 if (ebx == 0x564d5868) {
406 uint32_t *uuid_ptr = (uint32_t *)bios_uuid;
407 // get uuid
408 asm volatile ("outl %%eax, %%dx"
409 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
410 : "a" (0x564d5868), "c" (0x13), "d" (0x5658));
411 uuid_ptr[0] = eax;
412 uuid_ptr[1] = ebx;
413 uuid_ptr[2] = ecx;
414 uuid_ptr[3] = edx;
415 } else
416 #endif
418 // UUID not set
419 memset(bios_uuid, 0, 16);
423 void cpu_probe(void)
425 uint32_t eax, ebx, ecx, edx;
426 cpuid(1, eax, ebx, ecx, edx);
427 cpuid_signature = eax;
428 cpuid_features = edx;
429 cpuid_ext_features = ecx;
432 static int cmos_readb(int addr)
434 outb(0x70, addr);
435 return inb(0x71);
438 void ram_probe(void)
440 if (cmos_readb(0x34) | cmos_readb(0x35))
441 ram_size = (cmos_readb(0x34) | (cmos_readb(0x35) << 8)) * 65536 +
442 16 * 1024 * 1024;
443 else
444 ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 +
445 1 * 1024 * 1024;
446 BX_INFO("ram_size=0x%08lx\n", ram_size);
447 #ifdef BX_USE_EBDA_TABLES
448 ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
449 BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
450 #endif
453 /****************************************************/
454 /* SMP probe */
456 extern uint8_t smp_ap_boot_code_start;
457 extern uint8_t smp_ap_boot_code_end;
459 /* find the number of CPUs by launching a SIPI to them */
460 void smp_probe(void)
462 uint32_t val, sipi_vector;
464 smp_cpus = 1;
465 if (cpuid_features & CPUID_APIC) {
467 /* enable local APIC */
468 val = readl(APIC_BASE + APIC_SVR);
469 val |= APIC_ENABLED;
470 writel(APIC_BASE + APIC_SVR, val);
472 writew((void *)CPU_COUNT_ADDR, 1);
473 /* copy AP boot code */
474 memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start,
475 &smp_ap_boot_code_end - &smp_ap_boot_code_start);
477 /* broadcast SIPI */
478 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500);
479 sipi_vector = AP_BOOT_ADDR >> 12;
480 writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector);
482 delay_ms(10);
484 smp_cpus = readw((void *)CPU_COUNT_ADDR);
486 BX_INFO("Found %d cpu(s)\n", smp_cpus);
489 /****************************************************/
490 /* PCI init */
492 #define PCI_ADDRESS_SPACE_MEM 0x00
493 #define PCI_ADDRESS_SPACE_IO 0x01
494 #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
496 #define PCI_ROM_SLOT 6
497 #define PCI_NUM_REGIONS 7
499 #define PCI_DEVICES_MAX 64
501 #define PCI_VENDOR_ID 0x00 /* 16 bits */
502 #define PCI_DEVICE_ID 0x02 /* 16 bits */
503 #define PCI_COMMAND 0x04 /* 16 bits */
504 #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
505 #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
506 #define PCI_CLASS_DEVICE 0x0a /* Device class */
507 #define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
508 #define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
509 #define PCI_MIN_GNT 0x3e /* 8 bits */
510 #define PCI_MAX_LAT 0x3f /* 8 bits */
512 #define PCI_VENDOR_ID_INTEL 0x8086
513 #define PCI_DEVICE_ID_INTEL_82441 0x1237
514 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
515 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
516 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
518 #define PCI_VENDOR_ID_IBM 0x1014
519 #define PCI_VENDOR_ID_APPLE 0x106b
521 typedef struct PCIDevice {
522 int bus;
523 int devfn;
524 } PCIDevice;
526 static uint32_t pci_bios_io_addr;
527 static uint32_t pci_bios_mem_addr;
528 static uint32_t pci_bios_bigmem_addr;
529 /* host irqs corresponding to PCI irqs A-D */
530 static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
531 static PCIDevice i440_pcidev;
533 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
535 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
536 outl(0xcfc, val);
539 static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
541 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
542 outw(0xcfc + (addr & 2), val);
545 static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
547 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
548 outb(0xcfc + (addr & 3), val);
551 static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
553 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
554 return inl(0xcfc);
557 static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
559 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
560 return inw(0xcfc + (addr & 2));
563 static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
565 outl(0xcf8, 0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc));
566 return inb(0xcfc + (addr & 3));
569 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
571 uint16_t cmd;
572 uint32_t ofs, old_addr;
574 if ( region_num == PCI_ROM_SLOT ) {
575 ofs = 0x30;
576 }else{
577 ofs = 0x10 + region_num * 4;
580 old_addr = pci_config_readl(d, ofs);
582 pci_config_writel(d, ofs, addr);
583 BX_INFO("region %d: 0x%08x\n", region_num, addr);
585 /* enable memory mappings */
586 cmd = pci_config_readw(d, PCI_COMMAND);
587 if ( region_num == PCI_ROM_SLOT )
588 cmd |= 2;
589 else if (old_addr & PCI_ADDRESS_SPACE_IO)
590 cmd |= 1;
591 else
592 cmd |= 2;
593 pci_config_writew(d, PCI_COMMAND, cmd);
596 /* return the global irq number corresponding to a given device irq
597 pin. We could also use the bus number to have a more precise
598 mapping. */
599 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
601 int slot_addend;
602 slot_addend = (pci_dev->devfn >> 3) - 1;
603 return (irq_num + slot_addend) & 3;
606 static int find_bios_table_area(void)
608 unsigned long addr;
609 for(addr = 0xf0000; addr < 0x100000; addr += 16) {
610 if (*(uint32_t *)addr == 0xaafb4442) {
611 bios_table_cur_addr = addr + 8;
612 bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
613 BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
614 bios_table_cur_addr, bios_table_end_addr);
615 return 0;
618 return -1;
621 static void bios_shadow_init(PCIDevice *d)
623 int v;
625 if (find_bios_table_area() < 0)
626 return;
628 /* remap the BIOS to shadow RAM an keep it read/write while we
629 are writing tables */
630 v = pci_config_readb(d, 0x59);
631 v &= 0xcf;
632 pci_config_writeb(d, 0x59, v);
633 memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);
634 v |= 0x30;
635 pci_config_writeb(d, 0x59, v);
636 memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);
638 i440_pcidev = *d;
641 static void bios_lock_shadow_ram(void)
643 PCIDevice *d = &i440_pcidev;
644 int v;
646 wbinvd();
647 v = pci_config_readb(d, 0x59);
648 v = (v & 0x0f) | (0x10);
649 pci_config_writeb(d, 0x59, v);
652 static void pci_bios_init_bridges(PCIDevice *d)
654 uint16_t vendor_id, device_id;
656 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
657 device_id = pci_config_readw(d, PCI_DEVICE_ID);
659 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371SB_0) {
660 int i, irq;
661 uint8_t elcr[2];
663 /* PIIX3 bridge */
665 elcr[0] = 0x00;
666 elcr[1] = 0x00;
667 for(i = 0; i < 4; i++) {
668 irq = pci_irqs[i];
669 /* set to trigger level */
670 elcr[irq >> 3] |= (1 << (irq & 7));
671 /* activate irq remapping in PIIX */
672 pci_config_writeb(d, 0x60 + i, irq);
674 outb(0x4d0, elcr[0]);
675 outb(0x4d1, elcr[1]);
676 BX_INFO("PIIX3 init: elcr=%02x %02x\n",
677 elcr[0], elcr[1]);
678 } else if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82441) {
679 /* i440 PCI bridge */
680 bios_shadow_init(d);
684 extern uint8_t smm_relocation_start, smm_relocation_end;
685 extern uint8_t smm_code_start, smm_code_end;
687 #ifdef BX_USE_SMM
688 static void smm_init(PCIDevice *d)
690 uint32_t value;
692 /* check if SMM init is already done */
693 value = pci_config_readl(d, 0x58);
694 if ((value & (1 << 25)) == 0) {
696 /* copy the SMM relocation code */
697 memcpy((void *)0x38000, &smm_relocation_start,
698 &smm_relocation_end - &smm_relocation_start);
700 /* enable SMI generation when writing to the APMC register */
701 pci_config_writel(d, 0x58, value | (1 << 25));
703 /* init APM status port */
704 outb(0xb3, 0x01);
706 /* raise an SMI interrupt */
707 outb(0xb2, 0x00);
709 /* wait until SMM code executed */
710 while (inb(0xb3) != 0x00);
712 /* enable the SMM memory window */
713 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x48);
715 /* copy the SMM code */
716 memcpy((void *)0xa8000, &smm_code_start,
717 &smm_code_end - &smm_code_start);
718 wbinvd();
720 /* close the SMM memory window and enable normal SMM */
721 pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x08);
724 #endif
726 static void pci_bios_init_device(PCIDevice *d)
728 int class;
729 uint32_t *paddr;
730 int i, pin, pic_irq, vendor_id, device_id;
732 class = pci_config_readw(d, PCI_CLASS_DEVICE);
733 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
734 device_id = pci_config_readw(d, PCI_DEVICE_ID);
735 BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n",
736 d->bus, d->devfn, vendor_id, device_id);
737 switch(class) {
738 case 0x0101:
739 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371SB_1) {
740 /* PIIX3 IDE */
741 pci_config_writew(d, 0x40, 0x8000); // enable IDE0
742 pci_config_writew(d, 0x42, 0x8000); // enable IDE1
743 goto default_map;
744 } else {
745 /* IDE: we map it as in ISA mode */
746 pci_set_io_region_addr(d, 0, 0x1f0);
747 pci_set_io_region_addr(d, 1, 0x3f4);
748 pci_set_io_region_addr(d, 2, 0x170);
749 pci_set_io_region_addr(d, 3, 0x374);
751 break;
752 case 0x0300:
753 if (vendor_id != 0x1234)
754 goto default_map;
755 /* VGA: map frame buffer to default Bochs VBE address */
756 pci_set_io_region_addr(d, 0, 0xE0000000);
757 break;
758 case 0x0800:
759 /* PIC */
760 if (vendor_id == PCI_VENDOR_ID_IBM) {
761 /* IBM */
762 if (device_id == 0x0046 || device_id == 0xFFFF) {
763 /* MPIC & MPIC2 */
764 pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
767 break;
768 case 0xff00:
769 if (vendor_id == PCI_VENDOR_ID_APPLE &&
770 (device_id == 0x0017 || device_id == 0x0022)) {
771 /* macio bridge */
772 pci_set_io_region_addr(d, 0, 0x80800000);
774 break;
775 default:
776 default_map:
777 /* default memory mappings */
778 for(i = 0; i < PCI_NUM_REGIONS; i++) {
779 int ofs;
780 uint32_t val, size ;
782 if (i == PCI_ROM_SLOT)
783 ofs = 0x30;
784 else
785 ofs = 0x10 + i * 4;
786 pci_config_writel(d, ofs, 0xffffffff);
787 val = pci_config_readl(d, ofs);
788 if (val != 0) {
789 size = (~(val & ~0xf)) + 1;
790 if (val & PCI_ADDRESS_SPACE_IO)
791 paddr = &pci_bios_io_addr;
792 else if (size >= 0x04000000)
793 paddr = &pci_bios_bigmem_addr;
794 else
795 paddr = &pci_bios_mem_addr;
796 *paddr = (*paddr + size - 1) & ~(size - 1);
797 pci_set_io_region_addr(d, i, *paddr);
798 *paddr += size;
801 break;
804 /* map the interrupt */
805 pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
806 if (pin != 0) {
807 pin = pci_slot_get_pirq(d, pin - 1);
808 pic_irq = pci_irqs[pin];
809 pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
812 if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == PCI_DEVICE_ID_INTEL_82371AB_3) {
813 /* PIIX4 Power Management device (for ACPI) */
814 pm_io_base = PM_IO_BASE;
815 pci_config_writel(d, 0x40, pm_io_base | 1);
816 pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
817 smb_io_base = SMB_IO_BASE;
818 pci_config_writel(d, 0x90, smb_io_base | 1);
819 pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
820 pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
821 #ifdef BX_USE_SMM
822 smm_init(d);
823 #endif
824 acpi_enabled = 1;
828 void pci_for_each_device(void (*init_func)(PCIDevice *d))
830 PCIDevice d1, *d = &d1;
831 int bus, devfn;
832 uint16_t vendor_id, device_id;
834 for(bus = 0; bus < 1; bus++) {
835 for(devfn = 0; devfn < 256; devfn++) {
836 d->bus = bus;
837 d->devfn = devfn;
838 vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
839 device_id = pci_config_readw(d, PCI_DEVICE_ID);
840 if (vendor_id != 0xffff || device_id != 0xffff) {
841 init_func(d);
847 void pci_bios_init(void)
849 pci_bios_io_addr = 0xc000;
850 pci_bios_mem_addr = 0xf0000000;
851 pci_bios_bigmem_addr = ram_size;
852 if (pci_bios_bigmem_addr < 0x90000000)
853 pci_bios_bigmem_addr = 0x90000000;
855 pci_for_each_device(pci_bios_init_bridges);
857 pci_for_each_device(pci_bios_init_device);
860 /****************************************************/
861 /* Multi Processor table init */
863 static void putb(uint8_t **pp, int val)
865 uint8_t *q;
866 q = *pp;
867 *q++ = val;
868 *pp = q;
871 static void putstr(uint8_t **pp, const char *str)
873 uint8_t *q;
874 q = *pp;
875 while (*str)
876 *q++ = *str++;
877 *pp = q;
880 static void putle16(uint8_t **pp, int val)
882 uint8_t *q;
883 q = *pp;
884 *q++ = val;
885 *q++ = val >> 8;
886 *pp = q;
889 static void putle32(uint8_t **pp, int val)
891 uint8_t *q;
892 q = *pp;
893 *q++ = val;
894 *q++ = val >> 8;
895 *q++ = val >> 16;
896 *q++ = val >> 24;
897 *pp = q;
900 static int mpf_checksum(const uint8_t *data, int len)
902 int sum, i;
903 sum = 0;
904 for(i = 0; i < len; i++)
905 sum += data[i];
906 return sum & 0xff;
909 static unsigned long align(unsigned long addr, unsigned long v)
911 return (addr + v - 1) & ~(v - 1);
914 static void mptable_init(void)
916 uint8_t *mp_config_table, *q, *float_pointer_struct;
917 int ioapic_id, i, len;
918 int mp_config_table_size;
920 #ifdef BX_QEMU
921 if (smp_cpus <= 1)
922 return;
923 #endif
925 #ifdef BX_USE_EBDA_TABLES
926 mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
927 #else
928 bios_table_cur_addr = align(bios_table_cur_addr, 16);
929 mp_config_table = (uint8_t *)bios_table_cur_addr;
930 #endif
931 q = mp_config_table;
932 putstr(&q, "PCMP"); /* "PCMP signature */
933 putle16(&q, 0); /* table length (patched later) */
934 putb(&q, 4); /* spec rev */
935 putb(&q, 0); /* checksum (patched later) */
936 #ifdef BX_QEMU
937 putstr(&q, "QEMUCPU "); /* OEM id */
938 #else
939 putstr(&q, "BOCHSCPU");
940 #endif
941 putstr(&q, "0.1 "); /* vendor id */
942 putle32(&q, 0); /* OEM table ptr */
943 putle16(&q, 0); /* OEM table size */
944 putle16(&q, smp_cpus + 18); /* entry count */
945 putle32(&q, 0xfee00000); /* local APIC addr */
946 putle16(&q, 0); /* ext table length */
947 putb(&q, 0); /* ext table checksum */
948 putb(&q, 0); /* reserved */
950 for(i = 0; i < smp_cpus; i++) {
951 putb(&q, 0); /* entry type = processor */
952 putb(&q, i); /* APIC id */
953 putb(&q, 0x11); /* local APIC version number */
954 if (i == 0)
955 putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
956 else
957 putb(&q, 1); /* cpu flags: enabled */
958 putb(&q, 0); /* cpu signature */
959 putb(&q, 6);
960 putb(&q, 0);
961 putb(&q, 0);
962 putle16(&q, 0x201); /* feature flags */
963 putle16(&q, 0);
965 putle16(&q, 0); /* reserved */
966 putle16(&q, 0);
967 putle16(&q, 0);
968 putle16(&q, 0);
971 /* isa bus */
972 putb(&q, 1); /* entry type = bus */
973 putb(&q, 0); /* bus ID */
974 putstr(&q, "ISA ");
976 /* ioapic */
977 ioapic_id = smp_cpus;
978 putb(&q, 2); /* entry type = I/O APIC */
979 putb(&q, ioapic_id); /* apic ID */
980 putb(&q, 0x11); /* I/O APIC version number */
981 putb(&q, 1); /* enable */
982 putle32(&q, 0xfec00000); /* I/O APIC addr */
984 /* irqs */
985 for(i = 0; i < 16; i++) {
986 putb(&q, 3); /* entry type = I/O interrupt */
987 putb(&q, 0); /* interrupt type = vectored interrupt */
988 putb(&q, 0); /* flags: po=0, el=0 */
989 putb(&q, 0);
990 putb(&q, 0); /* source bus ID = ISA */
991 putb(&q, i); /* source bus IRQ */
992 putb(&q, ioapic_id); /* dest I/O APIC ID */
993 putb(&q, i); /* dest I/O APIC interrupt in */
995 /* patch length */
996 len = q - mp_config_table;
997 mp_config_table[4] = len;
998 mp_config_table[5] = len >> 8;
1000 mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
1002 mp_config_table_size = q - mp_config_table;
1004 #ifndef BX_USE_EBDA_TABLES
1005 bios_table_cur_addr += mp_config_table_size;
1006 #endif
1008 /* floating pointer structure */
1009 #ifdef BX_USE_EBDA_TABLES
1010 ebda_cur_addr = align(ebda_cur_addr, 16);
1011 float_pointer_struct = (uint8_t *)ebda_cur_addr;
1012 #else
1013 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1014 float_pointer_struct = (uint8_t *)bios_table_cur_addr;
1015 #endif
1016 q = float_pointer_struct;
1017 putstr(&q, "_MP_");
1018 /* pointer to MP config table */
1019 putle32(&q, (unsigned long)mp_config_table);
1021 putb(&q, 1); /* length in 16 byte units */
1022 putb(&q, 4); /* MP spec revision */
1023 putb(&q, 0); /* checksum (patched later) */
1024 putb(&q, 0); /* MP feature byte 1 */
1026 putb(&q, 0);
1027 putb(&q, 0);
1028 putb(&q, 0);
1029 putb(&q, 0);
1030 float_pointer_struct[10] =
1031 -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
1032 #ifdef BX_USE_EBDA_TABLES
1033 ebda_cur_addr += (q - float_pointer_struct);
1034 #else
1035 bios_table_cur_addr += (q - float_pointer_struct);
1036 #endif
1037 BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
1038 (unsigned long)float_pointer_struct,
1039 (unsigned long)mp_config_table,
1040 mp_config_table_size);
1043 /****************************************************/
1044 /* ACPI tables init */
1046 /* Table structure from Linux kernel (the ACPI tables are under the
1047 BSD license) */
1049 #define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
1050 uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\
1051 uint32_t length; /* Length of table, in bytes, including header */\
1052 uint8_t revision; /* ACPI Specification minor version # */\
1053 uint8_t checksum; /* To make sum of entire table == 0 */\
1054 uint8_t oem_id [6]; /* OEM identification */\
1055 uint8_t oem_table_id [8]; /* OEM table identification */\
1056 uint32_t oem_revision; /* OEM revision number */\
1057 uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\
1058 uint32_t asl_compiler_revision; /* ASL compiler revision number */
1061 struct acpi_table_header /* ACPI common table header */
1063 ACPI_TABLE_HEADER_DEF
1066 struct rsdp_descriptor /* Root System Descriptor Pointer */
1068 uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */
1069 uint8_t checksum; /* To make sum of struct == 0 */
1070 uint8_t oem_id [6]; /* OEM identification */
1071 uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */
1072 uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */
1073 uint32_t length; /* XSDT Length in bytes including hdr */
1074 uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */
1075 uint8_t extended_checksum; /* Checksum of entire table */
1076 uint8_t reserved [3]; /* Reserved field must be 0 */
1080 * ACPI 1.0 Root System Description Table (RSDT)
1082 struct rsdt_descriptor_rev1
1084 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1085 uint32_t table_offset_entry [3]; /* Array of pointers to other */
1086 /* ACPI tables */
1090 * ACPI 1.0 Firmware ACPI Control Structure (FACS)
1092 struct facs_descriptor_rev1
1094 uint8_t signature[4]; /* ACPI Signature */
1095 uint32_t length; /* Length of structure, in bytes */
1096 uint32_t hardware_signature; /* Hardware configuration signature */
1097 uint32_t firmware_waking_vector; /* ACPI OS waking vector */
1098 uint32_t global_lock; /* Global Lock */
1099 uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */
1100 uint32_t reserved1 : 31; /* Must be 0 */
1101 uint8_t resverved3 [40]; /* Reserved - must be zero */
1106 * ACPI 1.0 Fixed ACPI Description Table (FADT)
1108 struct fadt_descriptor_rev1
1110 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1111 uint32_t firmware_ctrl; /* Physical address of FACS */
1112 uint32_t dsdt; /* Physical address of DSDT */
1113 uint8_t model; /* System Interrupt Model */
1114 uint8_t reserved1; /* Reserved */
1115 uint16_t sci_int; /* System vector of SCI interrupt */
1116 uint32_t smi_cmd; /* Port address of SMI command port */
1117 uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */
1118 uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */
1119 uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
1120 uint8_t reserved2; /* Reserved - must be zero */
1121 uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
1122 uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
1123 uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
1124 uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
1125 uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
1126 uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
1127 uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
1128 uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
1129 uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
1130 uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
1131 uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
1132 uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
1133 uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
1134 uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
1135 uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */
1136 uint8_t reserved3; /* Reserved */
1137 uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
1138 uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
1139 uint16_t flush_size; /* Size of area read to flush caches */
1140 uint16_t flush_stride; /* Stride used in flushing caches */
1141 uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */
1142 uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */
1143 uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
1144 uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
1145 uint8_t century; /* Index to century in RTC CMOS RAM */
1146 uint8_t reserved4; /* Reserved */
1147 uint8_t reserved4a; /* Reserved */
1148 uint8_t reserved4b; /* Reserved */
1149 #if 0
1150 uint32_t wb_invd : 1; /* The wbinvd instruction works properly */
1151 uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
1152 uint32_t proc_c1 : 1; /* All processors support C1 state */
1153 uint32_t plvl2_up : 1; /* C2 state works on MP system */
1154 uint32_t pwr_button : 1; /* Power button is handled as a generic feature */
1155 uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
1156 uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
1157 uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
1158 uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */
1159 uint32_t reserved5 : 23; /* Reserved - must be zero */
1160 #else
1161 uint32_t flags;
1162 #endif
1166 * MADT values and structures
1169 /* Values for MADT PCATCompat */
1171 #define DUAL_PIC 0
1172 #define MULTIPLE_APIC 1
1175 /* Master MADT */
1177 struct multiple_apic_table
1179 ACPI_TABLE_HEADER_DEF /* ACPI common table header */
1180 uint32_t local_apic_address; /* Physical address of local APIC */
1181 #if 0
1182 uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */
1183 uint32_t reserved1 : 31;
1184 #else
1185 uint32_t flags;
1186 #endif
1190 /* Values for Type in APIC_HEADER_DEF */
1192 #define APIC_PROCESSOR 0
1193 #define APIC_IO 1
1194 #define APIC_XRUPT_OVERRIDE 2
1195 #define APIC_NMI 3
1196 #define APIC_LOCAL_NMI 4
1197 #define APIC_ADDRESS_OVERRIDE 5
1198 #define APIC_IO_SAPIC 6
1199 #define APIC_LOCAL_SAPIC 7
1200 #define APIC_XRUPT_SOURCE 8
1201 #define APIC_RESERVED 9 /* 9 and greater are reserved */
1204 * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
1206 #define APIC_HEADER_DEF /* Common APIC sub-structure header */\
1207 uint8_t type; \
1208 uint8_t length;
1210 /* Sub-structures for MADT */
1212 struct madt_processor_apic
1214 APIC_HEADER_DEF
1215 uint8_t processor_id; /* ACPI processor id */
1216 uint8_t local_apic_id; /* Processor's local APIC id */
1217 #if 0
1218 uint32_t processor_enabled: 1; /* Processor is usable if set */
1219 uint32_t reserved2 : 31; /* Reserved, must be zero */
1220 #else
1221 uint32_t flags;
1222 #endif
1225 struct madt_io_apic
1227 APIC_HEADER_DEF
1228 uint8_t io_apic_id; /* I/O APIC ID */
1229 uint8_t reserved; /* Reserved - must be zero */
1230 uint32_t address; /* APIC physical address */
1231 uint32_t interrupt; /* Global system interrupt where INTI
1232 * lines start */
1235 #include "acpi-dsdt.hex"
1237 static inline uint16_t cpu_to_le16(uint16_t x)
1239 return x;
1242 static inline uint32_t cpu_to_le32(uint32_t x)
1244 return x;
1247 static int acpi_checksum(const uint8_t *data, int len)
1249 int sum, i;
1250 sum = 0;
1251 for(i = 0; i < len; i++)
1252 sum += data[i];
1253 return (-sum) & 0xff;
1256 static void acpi_build_table_header(struct acpi_table_header *h,
1257 char *sig, int len, uint8_t rev)
1259 memcpy(h->signature, sig, 4);
1260 h->length = cpu_to_le32(len);
1261 h->revision = rev;
1262 #ifdef BX_QEMU
1263 memcpy(h->oem_id, "QEMU ", 6);
1264 memcpy(h->oem_table_id, "QEMU", 4);
1265 #else
1266 memcpy(h->oem_id, "BOCHS ", 6);
1267 memcpy(h->oem_table_id, "BXPC", 4);
1268 #endif
1269 memcpy(h->oem_table_id + 4, sig, 4);
1270 h->oem_revision = cpu_to_le32(1);
1271 #ifdef BX_QEMU
1272 memcpy(h->asl_compiler_id, "QEMU", 4);
1273 #else
1274 memcpy(h->asl_compiler_id, "BXPC", 4);
1275 #endif
1276 h->asl_compiler_revision = cpu_to_le32(1);
1277 h->checksum = acpi_checksum((void *)h, len);
1280 int acpi_build_processor_ssdt(uint8_t *ssdt)
1282 uint8_t *ssdt_ptr = ssdt;
1283 int i, length;
1284 int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
1286 ssdt_ptr[9] = 0; // checksum;
1287 ssdt_ptr += sizeof(struct acpi_table_header);
1289 // caluculate the length of processor block and scope block excluding PkgLength
1290 length = 0x0d * acpi_cpus + 4;
1292 // build processor scope header
1293 *(ssdt_ptr++) = 0x10; // ScopeOp
1294 if (length <= 0x3e) {
1295 *(ssdt_ptr++) = length + 1;
1296 } else {
1297 *(ssdt_ptr++) = 0x7F;
1298 *(ssdt_ptr++) = (length + 2) >> 6;
1300 *(ssdt_ptr++) = '_'; // Name
1301 *(ssdt_ptr++) = 'P';
1302 *(ssdt_ptr++) = 'R';
1303 *(ssdt_ptr++) = '_';
1305 // build object for each processor
1306 for(i=0;i<acpi_cpus;i++) {
1307 *(ssdt_ptr++) = 0x5B; // ProcessorOp
1308 *(ssdt_ptr++) = 0x83;
1309 *(ssdt_ptr++) = 0x0B; // Length
1310 *(ssdt_ptr++) = 'C'; // Name (CPUxx)
1311 *(ssdt_ptr++) = 'P';
1312 if ((i & 0xf0) != 0)
1313 *(ssdt_ptr++) = (i >> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa;
1314 else
1315 *(ssdt_ptr++) = 'U';
1316 *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa;
1317 *(ssdt_ptr++) = i;
1318 *(ssdt_ptr++) = 0x10; // Processor block address
1319 *(ssdt_ptr++) = 0xb0;
1320 *(ssdt_ptr++) = 0;
1321 *(ssdt_ptr++) = 0;
1322 *(ssdt_ptr++) = 6; // Processor block length
1325 acpi_build_table_header((struct acpi_table_header *)ssdt,
1326 "SSDT", ssdt_ptr - ssdt, 1);
1328 return ssdt_ptr - ssdt;
1331 /* base_addr must be a multiple of 4KB */
1332 void acpi_bios_init(void)
1334 struct rsdp_descriptor *rsdp;
1335 struct rsdt_descriptor_rev1 *rsdt;
1336 struct fadt_descriptor_rev1 *fadt;
1337 struct facs_descriptor_rev1 *facs;
1338 struct multiple_apic_table *madt;
1339 uint8_t *dsdt, *ssdt;
1340 uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
1341 uint32_t acpi_tables_size, madt_addr, madt_size;
1342 int i;
1344 /* reserve memory space for tables */
1345 #ifdef BX_USE_EBDA_TABLES
1346 ebda_cur_addr = align(ebda_cur_addr, 16);
1347 rsdp = (void *)(ebda_cur_addr);
1348 ebda_cur_addr += sizeof(*rsdp);
1349 #else
1350 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1351 rsdp = (void *)(bios_table_cur_addr);
1352 bios_table_cur_addr += sizeof(*rsdp);
1353 #endif
1355 addr = base_addr = ram_size - ACPI_DATA_SIZE;
1356 rsdt_addr = addr;
1357 rsdt = (void *)(addr);
1358 addr += sizeof(*rsdt);
1360 fadt_addr = addr;
1361 fadt = (void *)(addr);
1362 addr += sizeof(*fadt);
1364 /* XXX: FACS should be in RAM */
1365 addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
1366 facs_addr = addr;
1367 facs = (void *)(addr);
1368 addr += sizeof(*facs);
1370 dsdt_addr = addr;
1371 dsdt = (void *)(addr);
1372 addr += sizeof(AmlCode);
1374 ssdt_addr = addr;
1375 ssdt = (void *)(addr);
1376 addr += acpi_build_processor_ssdt(ssdt);
1378 addr = (addr + 7) & ~7;
1379 madt_addr = addr;
1380 madt_size = sizeof(*madt) +
1381 sizeof(struct madt_processor_apic) * smp_cpus +
1382 sizeof(struct madt_io_apic);
1383 madt = (void *)(addr);
1384 addr += madt_size;
1386 acpi_tables_size = addr - base_addr;
1388 BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
1389 (unsigned long)rsdp,
1390 (unsigned long)rsdt, acpi_tables_size);
1392 /* RSDP */
1393 memset(rsdp, 0, sizeof(*rsdp));
1394 memcpy(rsdp->signature, "RSD PTR ", 8);
1395 #ifdef BX_QEMU
1396 memcpy(rsdp->oem_id, "QEMU ", 6);
1397 #else
1398 memcpy(rsdp->oem_id, "BOCHS ", 6);
1399 #endif
1400 rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
1401 rsdp->checksum = acpi_checksum((void *)rsdp, 20);
1403 /* RSDT */
1404 memset(rsdt, 0, sizeof(*rsdt));
1405 rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
1406 rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
1407 rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
1408 acpi_build_table_header((struct acpi_table_header *)rsdt,
1409 "RSDT", sizeof(*rsdt), 1);
1411 /* FADT */
1412 memset(fadt, 0, sizeof(*fadt));
1413 fadt->firmware_ctrl = cpu_to_le32(facs_addr);
1414 fadt->dsdt = cpu_to_le32(dsdt_addr);
1415 fadt->model = 1;
1416 fadt->reserved1 = 0;
1417 fadt->sci_int = cpu_to_le16(pm_sci_int);
1418 fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
1419 fadt->acpi_enable = 0xf1;
1420 fadt->acpi_disable = 0xf0;
1421 fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
1422 fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
1423 fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
1424 fadt->pm1_evt_len = 4;
1425 fadt->pm1_cnt_len = 2;
1426 fadt->pm_tmr_len = 4;
1427 fadt->plvl2_lat = cpu_to_le16(50);
1428 fadt->plvl3_lat = cpu_to_le16(50);
1429 /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
1430 fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
1431 acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
1432 sizeof(*fadt), 1);
1434 /* FACS */
1435 memset(facs, 0, sizeof(*facs));
1436 memcpy(facs->signature, "FACS", 4);
1437 facs->length = cpu_to_le32(sizeof(*facs));
1439 /* DSDT */
1440 memcpy(dsdt, AmlCode, sizeof(AmlCode));
1442 /* MADT */
1444 struct madt_processor_apic *apic;
1445 struct madt_io_apic *io_apic;
1447 memset(madt, 0, madt_size);
1448 madt->local_apic_address = cpu_to_le32(0xfee00000);
1449 madt->flags = cpu_to_le32(1);
1450 apic = (void *)(madt + 1);
1451 for(i=0;i<smp_cpus;i++) {
1452 apic->type = APIC_PROCESSOR;
1453 apic->length = sizeof(*apic);
1454 apic->processor_id = i;
1455 apic->local_apic_id = i;
1456 apic->flags = cpu_to_le32(1);
1457 apic++;
1459 io_apic = (void *)apic;
1460 io_apic->type = APIC_IO;
1461 io_apic->length = sizeof(*io_apic);
1462 io_apic->io_apic_id = smp_cpus;
1463 io_apic->address = cpu_to_le32(0xfec00000);
1464 io_apic->interrupt = cpu_to_le32(0);
1466 acpi_build_table_header((struct acpi_table_header *)madt,
1467 "APIC", madt_size, 1);
1471 /* SMBIOS entry point -- must be written to a 16-bit aligned address
1472 between 0xf0000 and 0xfffff.
1474 struct smbios_entry_point {
1475 char anchor_string[4];
1476 uint8_t checksum;
1477 uint8_t length;
1478 uint8_t smbios_major_version;
1479 uint8_t smbios_minor_version;
1480 uint16_t max_structure_size;
1481 uint8_t entry_point_revision;
1482 uint8_t formatted_area[5];
1483 char intermediate_anchor_string[5];
1484 uint8_t intermediate_checksum;
1485 uint16_t structure_table_length;
1486 uint32_t structure_table_address;
1487 uint16_t number_of_structures;
1488 uint8_t smbios_bcd_revision;
1489 } __attribute__((__packed__));
1491 /* This goes at the beginning of every SMBIOS structure. */
1492 struct smbios_structure_header {
1493 uint8_t type;
1494 uint8_t length;
1495 uint16_t handle;
1496 } __attribute__((__packed__));
1498 /* SMBIOS type 0 - BIOS Information */
1499 struct smbios_type_0 {
1500 struct smbios_structure_header header;
1501 uint8_t vendor_str;
1502 uint8_t bios_version_str;
1503 uint16_t bios_starting_address_segment;
1504 uint8_t bios_release_date_str;
1505 uint8_t bios_rom_size;
1506 uint8_t bios_characteristics[8];
1507 uint8_t bios_characteristics_extension_bytes[2];
1508 uint8_t system_bios_major_release;
1509 uint8_t system_bios_minor_release;
1510 uint8_t embedded_controller_major_release;
1511 uint8_t embedded_controller_minor_release;
1512 } __attribute__((__packed__));
1514 /* SMBIOS type 1 - System Information */
1515 struct smbios_type_1 {
1516 struct smbios_structure_header header;
1517 uint8_t manufacturer_str;
1518 uint8_t product_name_str;
1519 uint8_t version_str;
1520 uint8_t serial_number_str;
1521 uint8_t uuid[16];
1522 uint8_t wake_up_type;
1523 uint8_t sku_number_str;
1524 uint8_t family_str;
1525 } __attribute__((__packed__));
1527 /* SMBIOS type 3 - System Enclosure (v2.3) */
1528 struct smbios_type_3 {
1529 struct smbios_structure_header header;
1530 uint8_t manufacturer_str;
1531 uint8_t type;
1532 uint8_t version_str;
1533 uint8_t serial_number_str;
1534 uint8_t asset_tag_number_str;
1535 uint8_t boot_up_state;
1536 uint8_t power_supply_state;
1537 uint8_t thermal_state;
1538 uint8_t security_status;
1539 uint32_t oem_defined;
1540 uint8_t height;
1541 uint8_t number_of_power_cords;
1542 uint8_t contained_element_count;
1543 // contained elements follow
1544 } __attribute__((__packed__));
1546 /* SMBIOS type 4 - Processor Information (v2.0) */
1547 struct smbios_type_4 {
1548 struct smbios_structure_header header;
1549 uint8_t socket_designation_str;
1550 uint8_t processor_type;
1551 uint8_t processor_family;
1552 uint8_t processor_manufacturer_str;
1553 uint32_t processor_id[2];
1554 uint8_t processor_version_str;
1555 uint8_t voltage;
1556 uint16_t external_clock;
1557 uint16_t max_speed;
1558 uint16_t current_speed;
1559 uint8_t status;
1560 uint8_t processor_upgrade;
1561 } __attribute__((__packed__));
1563 /* SMBIOS type 16 - Physical Memory Array
1564 * Associated with one type 17 (Memory Device).
1566 struct smbios_type_16 {
1567 struct smbios_structure_header header;
1568 uint8_t location;
1569 uint8_t use;
1570 uint8_t error_correction;
1571 uint32_t maximum_capacity;
1572 uint16_t memory_error_information_handle;
1573 uint16_t number_of_memory_devices;
1574 } __attribute__((__packed__));
1576 /* SMBIOS type 17 - Memory Device
1577 * Associated with one type 19
1579 struct smbios_type_17 {
1580 struct smbios_structure_header header;
1581 uint16_t physical_memory_array_handle;
1582 uint16_t memory_error_information_handle;
1583 uint16_t total_width;
1584 uint16_t data_width;
1585 uint16_t size;
1586 uint8_t form_factor;
1587 uint8_t device_set;
1588 uint8_t device_locator_str;
1589 uint8_t bank_locator_str;
1590 uint8_t memory_type;
1591 uint16_t type_detail;
1592 } __attribute__((__packed__));
1594 /* SMBIOS type 19 - Memory Array Mapped Address */
1595 struct smbios_type_19 {
1596 struct smbios_structure_header header;
1597 uint32_t starting_address;
1598 uint32_t ending_address;
1599 uint16_t memory_array_handle;
1600 uint8_t partition_width;
1601 } __attribute__((__packed__));
1603 /* SMBIOS type 20 - Memory Device Mapped Address */
1604 struct smbios_type_20 {
1605 struct smbios_structure_header header;
1606 uint32_t starting_address;
1607 uint32_t ending_address;
1608 uint16_t memory_device_handle;
1609 uint16_t memory_array_mapped_address_handle;
1610 uint8_t partition_row_position;
1611 uint8_t interleave_position;
1612 uint8_t interleaved_data_depth;
1613 } __attribute__((__packed__));
1615 /* SMBIOS type 32 - System Boot Information */
1616 struct smbios_type_32 {
1617 struct smbios_structure_header header;
1618 uint8_t reserved[6];
1619 uint8_t boot_status;
1620 } __attribute__((__packed__));
1622 /* SMBIOS type 127 -- End-of-table */
1623 struct smbios_type_127 {
1624 struct smbios_structure_header header;
1625 } __attribute__((__packed__));
1627 static void
1628 smbios_entry_point_init(void *start,
1629 uint16_t max_structure_size,
1630 uint16_t structure_table_length,
1631 uint32_t structure_table_address,
1632 uint16_t number_of_structures)
1634 uint8_t sum;
1635 int i;
1636 struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
1638 memcpy(ep->anchor_string, "_SM_", 4);
1639 ep->length = 0x1f;
1640 ep->smbios_major_version = 2;
1641 ep->smbios_minor_version = 4;
1642 ep->max_structure_size = max_structure_size;
1643 ep->entry_point_revision = 0;
1644 memset(ep->formatted_area, 0, 5);
1645 memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
1647 ep->structure_table_length = structure_table_length;
1648 ep->structure_table_address = structure_table_address;
1649 ep->number_of_structures = number_of_structures;
1650 ep->smbios_bcd_revision = 0x24;
1652 ep->checksum = 0;
1653 ep->intermediate_checksum = 0;
1655 sum = 0;
1656 for (i = 0; i < 0x10; i++)
1657 sum += ((int8_t *)start)[i];
1658 ep->checksum = -sum;
1660 sum = 0;
1661 for (i = 0x10; i < ep->length; i++)
1662 sum += ((int8_t *)start)[i];
1663 ep->intermediate_checksum = -sum;
1666 /* Type 0 -- BIOS Information */
1667 #define RELEASE_DATE_STR "01/01/2007"
1668 static void *
1669 smbios_type_0_init(void *start)
1671 struct smbios_type_0 *p = (struct smbios_type_0 *)start;
1673 p->header.type = 0;
1674 p->header.length = sizeof(struct smbios_type_0);
1675 p->header.handle = 0;
1677 p->vendor_str = 1;
1678 p->bios_version_str = 1;
1679 p->bios_starting_address_segment = 0xe800;
1680 p->bios_release_date_str = 2;
1681 p->bios_rom_size = 0; /* FIXME */
1683 memset(p->bios_characteristics, 0, 8);
1684 p->bios_characteristics[0] = 0x08; /* BIOS characteristics not supported */
1685 p->bios_characteristics_extension_bytes[0] = 0;
1686 p->bios_characteristics_extension_bytes[1] = 0;
1688 p->system_bios_major_release = 1;
1689 p->system_bios_minor_release = 0;
1690 p->embedded_controller_major_release = 0xff;
1691 p->embedded_controller_minor_release = 0xff;
1693 start += sizeof(struct smbios_type_0);
1694 memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
1695 start += sizeof(BX_APPNAME);
1696 memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
1697 start += sizeof(RELEASE_DATE_STR);
1698 *((uint8_t *)start) = 0;
1700 return start+1;
1703 /* Type 1 -- System Information */
1704 static void *
1705 smbios_type_1_init(void *start)
1707 struct smbios_type_1 *p = (struct smbios_type_1 *)start;
1708 p->header.type = 1;
1709 p->header.length = sizeof(struct smbios_type_1);
1710 p->header.handle = 0x100;
1712 p->manufacturer_str = 0;
1713 p->product_name_str = 0;
1714 p->version_str = 0;
1715 p->serial_number_str = 0;
1717 memcpy(p->uuid, bios_uuid, 16);
1719 p->wake_up_type = 0x06; /* power switch */
1720 p->sku_number_str = 0;
1721 p->family_str = 0;
1723 start += sizeof(struct smbios_type_1);
1724 *((uint16_t *)start) = 0;
1726 return start+2;
1729 /* Type 3 -- System Enclosure */
1730 static void *
1731 smbios_type_3_init(void *start)
1733 struct smbios_type_3 *p = (struct smbios_type_3 *)start;
1735 p->header.type = 3;
1736 p->header.length = sizeof(struct smbios_type_3);
1737 p->header.handle = 0x300;
1739 p->manufacturer_str = 0;
1740 p->type = 0x01; /* other */
1741 p->version_str = 0;
1742 p->serial_number_str = 0;
1743 p->asset_tag_number_str = 0;
1744 p->boot_up_state = 0x03; /* safe */
1745 p->power_supply_state = 0x03; /* safe */
1746 p->thermal_state = 0x03; /* safe */
1747 p->security_status = 0x02; /* unknown */
1748 p->oem_defined = 0;
1749 p->height = 0;
1750 p->number_of_power_cords = 0;
1751 p->contained_element_count = 0;
1753 start += sizeof(struct smbios_type_3);
1754 *((uint16_t *)start) = 0;
1756 return start+2;
1759 /* Type 4 -- Processor Information */
1760 static void *
1761 smbios_type_4_init(void *start, unsigned int cpu_number)
1763 struct smbios_type_4 *p = (struct smbios_type_4 *)start;
1765 p->header.type = 4;
1766 p->header.length = sizeof(struct smbios_type_4);
1767 p->header.handle = 0x400 + cpu_number;
1769 p->socket_designation_str = 1;
1770 p->processor_type = 0x03; /* CPU */
1771 p->processor_family = 0x01; /* other */
1772 p->processor_manufacturer_str = 0;
1774 p->processor_id[0] = cpuid_signature;
1775 p->processor_id[1] = cpuid_features;
1777 p->processor_version_str = 0;
1778 p->voltage = 0;
1779 p->external_clock = 0;
1781 p->max_speed = 0; /* unknown */
1782 p->current_speed = 0; /* unknown */
1784 p->status = 0x41; /* socket populated, CPU enabled */
1785 p->processor_upgrade = 0x01; /* other */
1787 start += sizeof(struct smbios_type_4);
1789 memcpy((char *)start, "CPU " "\0" "" "\0" "", 7);
1790 ((char *)start)[4] = cpu_number + '0';
1792 return start+7;
1795 /* Type 16 -- Physical Memory Array */
1796 static void *
1797 smbios_type_16_init(void *start, uint32_t memsize)
1799 struct smbios_type_16 *p = (struct smbios_type_16*)start;
1801 p->header.type = 16;
1802 p->header.length = sizeof(struct smbios_type_16);
1803 p->header.handle = 0x1000;
1805 p->location = 0x01; /* other */
1806 p->use = 0x03; /* system memory */
1807 p->error_correction = 0x01; /* other */
1808 p->maximum_capacity = memsize * 1024;
1809 p->memory_error_information_handle = 0xfffe; /* none provided */
1810 p->number_of_memory_devices = 1;
1812 start += sizeof(struct smbios_type_16);
1813 *((uint16_t *)start) = 0;
1815 return start + 2;
1818 /* Type 17 -- Memory Device */
1819 static void *
1820 smbios_type_17_init(void *start, uint32_t memory_size_mb)
1822 struct smbios_type_17 *p = (struct smbios_type_17 *)start;
1824 p->header.type = 17;
1825 p->header.length = sizeof(struct smbios_type_17);
1826 p->header.handle = 0x1100;
1828 p->physical_memory_array_handle = 0x1000;
1829 p->total_width = 64;
1830 p->data_width = 64;
1831 /* truncate memory_size_mb to 16 bits and clear most significant
1832 bit [indicates size in MB] */
1833 p->size = (uint16_t) memory_size_mb & 0x7fff;
1834 p->form_factor = 0x09; /* DIMM */
1835 p->device_set = 0;
1836 p->device_locator_str = 1;
1837 p->bank_locator_str = 0;
1838 p->memory_type = 0x07; /* RAM */
1839 p->type_detail = 0;
1841 start += sizeof(struct smbios_type_17);
1842 memcpy((char *)start, "DIMM 1", 7);
1843 start += 7;
1844 *((uint8_t *)start) = 0;
1846 return start+1;
1849 /* Type 19 -- Memory Array Mapped Address */
1850 static void *
1851 smbios_type_19_init(void *start, uint32_t memory_size_mb)
1853 struct smbios_type_19 *p = (struct smbios_type_19 *)start;
1855 p->header.type = 19;
1856 p->header.length = sizeof(struct smbios_type_19);
1857 p->header.handle = 0x1300;
1859 p->starting_address = 0;
1860 p->ending_address = (memory_size_mb-1) * 1024;
1861 p->memory_array_handle = 0x1000;
1862 p->partition_width = 1;
1864 start += sizeof(struct smbios_type_19);
1865 *((uint16_t *)start) = 0;
1867 return start + 2;
1870 /* Type 20 -- Memory Device Mapped Address */
1871 static void *
1872 smbios_type_20_init(void *start, uint32_t memory_size_mb)
1874 struct smbios_type_20 *p = (struct smbios_type_20 *)start;
1876 p->header.type = 20;
1877 p->header.length = sizeof(struct smbios_type_20);
1878 p->header.handle = 0x1400;
1880 p->starting_address = 0;
1881 p->ending_address = (memory_size_mb-1)*1024;
1882 p->memory_device_handle = 0x1100;
1883 p->memory_array_mapped_address_handle = 0x1300;
1884 p->partition_row_position = 1;
1885 p->interleave_position = 0;
1886 p->interleaved_data_depth = 0;
1888 start += sizeof(struct smbios_type_20);
1890 *((uint16_t *)start) = 0;
1891 return start+2;
1894 /* Type 32 -- System Boot Information */
1895 static void *
1896 smbios_type_32_init(void *start)
1898 struct smbios_type_32 *p = (struct smbios_type_32 *)start;
1900 p->header.type = 32;
1901 p->header.length = sizeof(struct smbios_type_32);
1902 p->header.handle = 0x2000;
1903 memset(p->reserved, 0, 6);
1904 p->boot_status = 0; /* no errors detected */
1906 start += sizeof(struct smbios_type_32);
1907 *((uint16_t *)start) = 0;
1909 return start+2;
1912 /* Type 127 -- End of Table */
1913 static void *
1914 smbios_type_127_init(void *start)
1916 struct smbios_type_127 *p = (struct smbios_type_127 *)start;
1918 p->header.type = 127;
1919 p->header.length = sizeof(struct smbios_type_127);
1920 p->header.handle = 0x7f00;
1922 start += sizeof(struct smbios_type_127);
1923 *((uint16_t *)start) = 0;
1925 return start + 2;
1928 void smbios_init(void)
1930 unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
1931 char *start, *p, *q;
1932 int memsize = ram_size / (1024 * 1024);
1934 #ifdef BX_USE_EBDA_TABLES
1935 ebda_cur_addr = align(ebda_cur_addr, 16);
1936 start = (void *)(ebda_cur_addr);
1937 #else
1938 bios_table_cur_addr = align(bios_table_cur_addr, 16);
1939 start = (void *)(bios_table_cur_addr);
1940 #endif
1942 p = (char *)start + sizeof(struct smbios_entry_point);
1944 #define add_struct(fn) { \
1945 q = (fn); \
1946 nr_structs++; \
1947 if ((q - p) > max_struct_size) \
1948 max_struct_size = q - p; \
1949 p = q; \
1952 add_struct(smbios_type_0_init(p));
1953 add_struct(smbios_type_1_init(p));
1954 add_struct(smbios_type_3_init(p));
1955 for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
1956 add_struct(smbios_type_4_init(p, cpu_num));
1957 add_struct(smbios_type_16_init(p, memsize));
1958 add_struct(smbios_type_17_init(p, memsize));
1959 add_struct(smbios_type_19_init(p, memsize));
1960 add_struct(smbios_type_20_init(p, memsize));
1961 add_struct(smbios_type_32_init(p));
1962 add_struct(smbios_type_127_init(p));
1964 #undef add_struct
1966 smbios_entry_point_init(
1967 start, max_struct_size,
1968 (p - (char *)start) - sizeof(struct smbios_entry_point),
1969 (uint32_t)(start + sizeof(struct smbios_entry_point)),
1970 nr_structs);
1972 #ifdef BX_USE_EBDA_TABLES
1973 ebda_cur_addr += (p - (char *)start);
1974 #else
1975 bios_table_cur_addr += (p - (char *)start);
1976 #endif
1978 BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
1981 void rombios32_init(void)
1983 BX_INFO("Starting rombios32\n");
1985 ram_probe();
1987 cpu_probe();
1989 smp_probe();
1991 pci_bios_init();
1993 if (bios_table_cur_addr != 0) {
1995 mptable_init();
1997 uuid_probe();
1999 smbios_init();
2001 if (acpi_enabled)
2002 acpi_bios_init();
2004 bios_lock_shadow_ram();
2006 BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
2007 if (bios_table_cur_addr > bios_table_end_addr)
2008 BX_PANIC("bios_table_end_addr overflow!\n");