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