Port rombios32 code from bochs-bios.
[people/mcb30/legacybios.git] / src / rombios32.c
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: rombios32.c,v 1.22 2008/01/27 17:57:26 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  32 bit Bochs BIOS init code
6 //  Copyright (C) 2006 Fabrice Bellard
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2 of the License, or (at your option) any later version.
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
22 #include "util.h" // BX_INFO
23 #include "cmos.h" // inb_cmos
24
25 #define BX_APPNAME "Bochs"
26
27 #define ACPI_DATA_SIZE    0x00010000L
28 #define PM_IO_BASE        0xb000
29 #define SMB_IO_BASE       0xb100
30 #define CPU_COUNT_ADDR    0xf000
31
32 typedef signed char  int8_t;
33 typedef short int16_t;
34 typedef int   int32_t;
35 typedef long long int64_t;
36 typedef unsigned char  uint8_t;
37 typedef unsigned short uint16_t;
38 typedef unsigned int   uint32_t;
39 typedef unsigned long long uint64_t;
40
41 /* if true, put the MP float table and ACPI RSDT in EBDA and the MP
42    table in RAM. Unfortunately, Linux has bugs with that, so we prefer
43    to modify the BIOS in shadow RAM */
44 //#define BX_USE_EBDA_TABLES
45
46 /* define it if the (emulated) hardware supports SMM mode */
47 #define BX_USE_SMM
48
49 #define cpuid(index, eax, ebx, ecx, edx) \
50   asm volatile ("cpuid" \
51                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
52                 : "0" (index))
53
54 #define wbinvd() asm volatile("wbinvd")
55
56 #define CPUID_APIC (1 << 9)
57
58 #define APIC_BASE    ((uint8_t *)0xfee00000)
59 #define APIC_ICR_LOW 0x300
60 #define APIC_SVR     0x0F0
61 #define APIC_ID      0x020
62 #define APIC_LVT3    0x370
63
64 #define APIC_ENABLED 0x0100
65
66 #define AP_BOOT_ADDR 0x10000
67
68 #define MPTABLE_MAX_SIZE  0x00002000
69 #define SMI_CMD_IO_ADDR   0xb2
70
71 #define BIOS_TMP_STORAGE  0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */
72
73 static inline void writel(void *addr, uint32_t val)
74 {
75     *(volatile uint32_t *)addr = val;
76 }
77
78 static inline void writew(void *addr, uint16_t val)
79 {
80     *(volatile uint16_t *)addr = val;
81 }
82
83 static inline void writeb(void *addr, uint8_t val)
84 {
85     *(volatile uint8_t *)addr = val;
86 }
87
88 static inline uint32_t readl(const void *addr)
89 {
90     return *(volatile const uint32_t *)addr;
91 }
92
93 static inline uint16_t readw(const void *addr)
94 {
95     return *(volatile const uint16_t *)addr;
96 }
97
98 static inline uint8_t readb(const void *addr)
99 {
100     return *(volatile const uint8_t *)addr;
101 }
102
103 int smp_cpus;
104 uint32_t cpuid_signature;
105 uint32_t cpuid_features;
106 uint32_t cpuid_ext_features;
107 unsigned long ram_size;
108 uint8_t bios_uuid[16];
109 #ifdef BX_USE_EBDA_TABLES
110 unsigned long ebda_cur_addr;
111 #endif
112 int acpi_enabled;
113 uint32_t pm_io_base, smb_io_base;
114 int pm_sci_int;
115 unsigned long bios_table_cur_addr;
116 unsigned long bios_table_end_addr;
117
118 void uuid_probe(void)
119 {
120 #ifdef BX_QEMU
121     uint32_t eax, ebx, ecx, edx;
122
123     // check if backdoor port exists
124     asm volatile ("outl %%eax, %%dx"
125         : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
126         : "a" (0x564d5868), "c" (0xa), "d" (0x5658));
127     if (ebx == 0x564d5868) {
128         uint32_t *uuid_ptr = (uint32_t *)bios_uuid;
129         // get uuid
130         asm volatile ("outl %%eax, %%dx"
131             : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
132             : "a" (0x564d5868), "c" (0x13), "d" (0x5658));
133         uuid_ptr[0] = eax;
134         uuid_ptr[1] = ebx;
135         uuid_ptr[2] = ecx;
136         uuid_ptr[3] = edx;
137     } else
138 #endif
139     {
140         // UUID not set
141         memset(bios_uuid, 0, 16);
142     }
143 }
144
145 void cpu_probe(void)
146 {
147     uint32_t eax, ebx, ecx, edx;
148     cpuid(1, eax, ebx, ecx, edx);
149     cpuid_signature = eax;
150     cpuid_features = edx;
151     cpuid_ext_features = ecx;
152 }
153
154 void ram_probe(void)
155 {
156   if (inb_cmos(0x34) | inb_cmos(0x35))
157     ram_size = (inb_cmos(0x34) | (inb_cmos(0x35) << 8)) * 65536 +
158         16 * 1024 * 1024;
159   else
160     ram_size = (inb_cmos(0x17) | (inb_cmos(0x18) << 8)) * 1024;
161 #ifdef BX_USE_EBDA_TABLES
162     ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
163 #endif
164     BX_INFO("ram_size=0x%08lx\n", ram_size);
165 }
166
167 /****************************************************/
168 /* SMP probe */
169
170 extern uint8_t smp_ap_boot_code_start;
171 extern uint8_t smp_ap_boot_code_end;
172
173 /* find the number of CPUs by launching a SIPI to them */
174 void smp_probe(void)
175 {
176     uint32_t val, sipi_vector;
177
178     smp_cpus = 1;
179     if (cpuid_features & CPUID_APIC) {
180
181         /* enable local APIC */
182         val = readl(APIC_BASE + APIC_SVR);
183         val |= APIC_ENABLED;
184         writel(APIC_BASE + APIC_SVR, val);
185
186         writew((void *)CPU_COUNT_ADDR, 1);
187         /* copy AP boot code */
188         memcpy((void *)AP_BOOT_ADDR, &smp_ap_boot_code_start,
189                &smp_ap_boot_code_end - &smp_ap_boot_code_start);
190
191         /* broadcast SIPI */
192         writel(APIC_BASE + APIC_ICR_LOW, 0x000C4500);
193         sipi_vector = AP_BOOT_ADDR >> 12;
194         writel(APIC_BASE + APIC_ICR_LOW, 0x000C4600 | sipi_vector);
195
196         usleep(10*1000);
197
198         smp_cpus = readw((void *)CPU_COUNT_ADDR);
199     }
200     BX_INFO("Found %d cpu(s)\n", smp_cpus);
201 }
202
203 /****************************************************/
204 /* PCI init */
205
206 #define PCI_ADDRESS_SPACE_MEM           0x00
207 #define PCI_ADDRESS_SPACE_IO            0x01
208 #define PCI_ADDRESS_SPACE_MEM_PREFETCH  0x08
209
210 #define PCI_ROM_SLOT 6
211 #define PCI_NUM_REGIONS 7
212
213 #define PCI_DEVICES_MAX 64
214
215 #define PCI_VENDOR_ID           0x00    /* 16 bits */
216 #define PCI_DEVICE_ID           0x02    /* 16 bits */
217 #define PCI_COMMAND             0x04    /* 16 bits */
218 #define  PCI_COMMAND_IO         0x1     /* Enable response in I/O space */
219 #define  PCI_COMMAND_MEMORY     0x2     /* Enable response in Memory space */
220 #define PCI_CLASS_DEVICE        0x0a    /* Device class */
221 #define PCI_INTERRUPT_LINE      0x3c    /* 8 bits */
222 #define PCI_INTERRUPT_PIN       0x3d    /* 8 bits */
223 #define PCI_MIN_GNT             0x3e    /* 8 bits */
224 #define PCI_MAX_LAT             0x3f    /* 8 bits */
225
226 typedef struct PCIDevice {
227     int bus;
228     int devfn;
229 } PCIDevice;
230
231 static uint32_t pci_bios_io_addr;
232 static uint32_t pci_bios_mem_addr;
233 static uint32_t pci_bios_bigmem_addr;
234 /* host irqs corresponding to PCI irqs A-D */
235 static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
236 static PCIDevice i440_pcidev;
237
238 static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
239 {
240     outl(0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc), 0xcf8);
241     outl(val, 0xcfc);
242 }
243
244 static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
245 {
246     outl(0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc), 0xcf8);
247     outw(val, 0xcfc + (addr & 2));
248 }
249
250 static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
251 {
252     outl(0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc), 0xcf8);
253     outb(val, 0xcfc + (addr & 3));
254 }
255
256 static uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
257 {
258     outl(0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc), 0xcf8);
259     return inl(0xcfc);
260 }
261
262 static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
263 {
264     outl(0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc), 0xcf8);
265     return inw(0xcfc + (addr & 2));
266 }
267
268 static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
269 {
270     outl(0x80000000 | (d->bus << 16) | (d->devfn << 8) | (addr & 0xfc), 0xcf8);
271     return inb(0xcfc + (addr & 3));
272 }
273
274 static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
275 {
276     uint16_t cmd;
277     uint32_t ofs, old_addr;
278
279     if ( region_num == PCI_ROM_SLOT ) {
280         ofs = 0x30;
281     }else{
282         ofs = 0x10 + region_num * 4;
283     }
284
285     old_addr = pci_config_readl(d, ofs);
286
287     pci_config_writel(d, ofs, addr);
288     BX_INFO("region %d: 0x%08x\n", region_num, addr);
289
290     /* enable memory mappings */
291     cmd = pci_config_readw(d, PCI_COMMAND);
292     if ( region_num == PCI_ROM_SLOT )
293         cmd |= 2;
294     else if (old_addr & PCI_ADDRESS_SPACE_IO)
295         cmd |= 1;
296     else
297         cmd |= 2;
298     pci_config_writew(d, PCI_COMMAND, cmd);
299 }
300
301 /* return the global irq number corresponding to a given device irq
302    pin. We could also use the bus number to have a more precise
303    mapping. */
304 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
305 {
306     int slot_addend;
307     slot_addend = (pci_dev->devfn >> 3) - 1;
308     return (irq_num + slot_addend) & 3;
309 }
310
311 static void
312 copy_bios(PCIDevice *d, int v)
313 {
314     pci_config_writeb(d, 0x59, v);
315     memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000);
316 }
317
318 // Test if 'addr' is in the range from 'start'..'start+size'
319 #define IN_RANGE(addr, start, size) ({   \
320             u32 __addr = (addr);         \
321             u32 __start = (start);       \
322             u32 __size = (size);         \
323             (__addr - __start < __size); \
324         })
325
326 static void bios_shadow_init(PCIDevice *d)
327 {
328     bios_table_cur_addr = 0xf0000 | OFFSET_freespace2_start;
329     bios_table_end_addr = 0xf0000 | OFFSET_freespace2_end;
330     BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
331             bios_table_cur_addr, bios_table_end_addr);
332
333     /* remap the BIOS to shadow RAM an keep it read/write while we
334        are writing tables */
335     int v = pci_config_readb(d, 0x59);
336     v &= 0xcf;
337     pci_config_writeb(d, 0x59, v);
338     memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000);
339     v |= 0x30;
340
341     if (IN_RANGE((u32)copy_bios, 0xf0000, 0x10000)) {
342         // Current code is in shadowed area.  Perform the copy from
343         // the code that is in the temporary location.
344         u32 pos = (u32)copy_bios - 0xf0000 + BIOS_TMP_STORAGE;
345         void (*func)(PCIDevice *, int) = (void*)pos;
346         func(d, v);
347     } else {
348         copy_bios(d, v);
349     }
350
351     i440_pcidev = *d;
352 }
353
354 static void bios_lock_shadow_ram(void)
355 {
356     PCIDevice *d = &i440_pcidev;
357     int v;
358
359     wbinvd();
360     v = pci_config_readb(d, 0x59);
361     v = (v & 0x0f) | (0x10);
362     pci_config_writeb(d, 0x59, v);
363 }
364
365 static void pci_bios_init_bridges(PCIDevice *d)
366 {
367     uint16_t vendor_id, device_id;
368
369     vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
370     device_id = pci_config_readw(d, PCI_DEVICE_ID);
371
372     if (vendor_id == 0x8086 && device_id == 0x7000) {
373         int i, irq;
374         uint8_t elcr[2];
375
376         /* PIIX3 bridge */
377
378         elcr[0] = 0x00;
379         elcr[1] = 0x00;
380         for(i = 0; i < 4; i++) {
381             irq = pci_irqs[i];
382             /* set to trigger level */
383             elcr[irq >> 3] |= (1 << (irq & 7));
384             /* activate irq remapping in PIIX */
385             pci_config_writeb(d, 0x60 + i, irq);
386         }
387         outb(elcr[0], 0x4d0);
388         outb(elcr[1], 0x4d1);
389         BX_INFO("PIIX3 init: elcr=%02x %02x\n",
390                 elcr[0], elcr[1]);
391     } else if (vendor_id == 0x8086 && device_id == 0x1237) {
392         /* i440 PCI bridge */
393         bios_shadow_init(d);
394     }
395 }
396
397 asm(
398     ".globl smp_ap_boot_code_start\n"
399     ".globl smp_ap_boot_code_end\n"
400     ".global smm_relocation_start\n"
401     ".global smm_relocation_end\n"
402     ".global smm_code_start\n"
403     ".global smm_code_end\n"
404
405     "  .code16\n"
406     "smp_ap_boot_code_start:\n"
407     "  xor %ax, %ax\n"
408     "  mov %ax, %ds\n"
409     "  incw " __stringify(CPU_COUNT_ADDR) "\n"
410     "1:\n"
411     "  hlt\n"
412     "  jmp 1b\n"
413     "smp_ap_boot_code_end:\n"
414
415     /* code to relocate SMBASE to 0xa0000 */
416     "smm_relocation_start:\n"
417     "  mov $0x38000 + 0x7efc, %ebx\n"
418     "  addr32 mov (%ebx), %al\n"  /* revision ID to see if x86_64 or x86 */
419     "  cmp $0x64, %al\n"
420     "  je 1f\n"
421     "  mov $0x38000 + 0x7ef8, %ebx\n"
422     "  jmp 2f\n"
423     "1:\n"
424     "  mov $0x38000 + 0x7f00, %ebx\n"
425     "2:\n"
426     "  movl $0xa0000, %eax\n"
427     "  addr32 movl %eax, (%ebx)\n"
428     /* indicate to the BIOS that the SMM code was executed */
429     "  mov $0x00, %al\n"
430     "  movw $0xb3, %dx\n"
431     "  outb %al, %dx\n"
432     "  rsm\n"
433     "smm_relocation_end:\n"
434
435     /* minimal SMM code to enable or disable ACPI */
436     "smm_code_start:\n"
437     "  movw $0xb2, %dx\n"
438     "  inb %dx, %al\n"
439     "  cmp $0xf0, %al\n"
440     "  jne 1f\n"
441
442     /* ACPI disable */
443     "  mov $" __stringify(PM_IO_BASE) " + 0x04, %dx\n" /* PMCNTRL */
444     "  inw %dx, %ax\n"
445     "  andw $~1, %ax\n"
446     "  outw %ax, %dx\n"
447
448     "  jmp 2f\n"
449
450     "1:\n"
451     "  cmp $0xf1, %al\n"
452     "  jne 2f\n"
453
454     /* ACPI enable */
455     "  mov $" __stringify(PM_IO_BASE) " + 0x04, %dx\n" /* PMCNTRL */
456     "  inw %dx, %ax\n"
457     "  orw $1, %ax\n"
458     "  outw %ax, %dx\n"
459
460     "2:\n"
461     "  rsm\n"
462     "smm_code_end:\n"
463     "  .code32\n"
464     );
465
466 extern uint8_t smm_relocation_start, smm_relocation_end;
467 extern uint8_t smm_code_start, smm_code_end;
468
469 #ifdef BX_USE_SMM
470 static void smm_init(PCIDevice *d)
471 {
472     uint32_t value;
473
474     /* check if SMM init is already done */
475     value = pci_config_readl(d, 0x58);
476     if ((value & (1 << 25)) == 0) {
477
478         /* copy the SMM relocation code */
479         memcpy((void *)0x38000, &smm_relocation_start,
480                &smm_relocation_end - &smm_relocation_start);
481
482         /* enable SMI generation when writing to the APMC register */
483         pci_config_writel(d, 0x58, value | (1 << 25));
484
485         /* init APM status port */
486         outb(0x01, 0xb3);
487
488         /* raise an SMI interrupt */
489         outb(0x00, 0xb2);
490
491         /* wait until SMM code executed */
492         while (inb(0xb3) != 0x00);
493
494         /* enable the SMM memory window */
495         pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x48);
496
497         /* copy the SMM code */
498         memcpy((void *)0xa8000, &smm_code_start,
499                &smm_code_end - &smm_code_start);
500         wbinvd();
501
502         /* close the SMM memory window and enable normal SMM */
503         pci_config_writeb(&i440_pcidev, 0x72, 0x02 | 0x08);
504     }
505 }
506 #endif
507
508 static void pci_bios_init_device(PCIDevice *d)
509 {
510     int class;
511     uint32_t *paddr;
512     int i, pin, pic_irq, vendor_id, device_id;
513
514     class = pci_config_readw(d, PCI_CLASS_DEVICE);
515     vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
516     device_id = pci_config_readw(d, PCI_DEVICE_ID);
517     BX_INFO("PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n",
518             d->bus, d->devfn, vendor_id, device_id);
519     switch(class) {
520     case 0x0101:
521         if (vendor_id == 0x8086 && device_id == 0x7010) {
522             /* PIIX3 IDE */
523             pci_config_writew(d, 0x40, 0x8000); // enable IDE0
524             pci_config_writew(d, 0x42, 0x8000); // enable IDE1
525             goto default_map;
526         } else {
527             /* IDE: we map it as in ISA mode */
528             pci_set_io_region_addr(d, 0, 0x1f0);
529             pci_set_io_region_addr(d, 1, 0x3f4);
530             pci_set_io_region_addr(d, 2, 0x170);
531             pci_set_io_region_addr(d, 3, 0x374);
532         }
533         break;
534     case 0x0300:
535         if (vendor_id != 0x1234)
536             goto default_map;
537         /* VGA: map frame buffer to default Bochs VBE address */
538         pci_set_io_region_addr(d, 0, 0xE0000000);
539         break;
540     case 0x0800:
541         /* PIC */
542         if (vendor_id == 0x1014) {
543             /* IBM */
544             if (device_id == 0x0046 || device_id == 0xFFFF) {
545                 /* MPIC & MPIC2 */
546                 pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
547             }
548         }
549         break;
550     case 0xff00:
551         if (vendor_id == 0x0106b &&
552             (device_id == 0x0017 || device_id == 0x0022)) {
553             /* macio bridge */
554             pci_set_io_region_addr(d, 0, 0x80800000);
555         }
556         break;
557     default:
558     default_map:
559         /* default memory mappings */
560         for(i = 0; i < PCI_NUM_REGIONS; i++) {
561             int ofs;
562             uint32_t val, size ;
563
564             if (i == PCI_ROM_SLOT)
565                 ofs = 0x30;
566             else
567                 ofs = 0x10 + i * 4;
568             pci_config_writel(d, ofs, 0xffffffff);
569             val = pci_config_readl(d, ofs);
570             if (val != 0) {
571                 size = (~(val & ~0xf)) + 1;
572                 if (val & PCI_ADDRESS_SPACE_IO)
573                     paddr = &pci_bios_io_addr;
574                 else if (size >= 0x04000000)
575                     paddr = &pci_bios_bigmem_addr;
576                 else
577                     paddr = &pci_bios_mem_addr;
578                 *paddr = (*paddr + size - 1) & ~(size - 1);
579                 pci_set_io_region_addr(d, i, *paddr);
580                 *paddr += size;
581             }
582         }
583         break;
584     }
585
586     /* map the interrupt */
587     pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
588     if (pin != 0) {
589         pin = pci_slot_get_pirq(d, pin - 1);
590         pic_irq = pci_irqs[pin];
591         pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
592     }
593
594     if (vendor_id == 0x8086 && device_id == 0x7113) {
595         /* PIIX4 Power Management device (for ACPI) */
596         pm_io_base = PM_IO_BASE;
597         pci_config_writel(d, 0x40, pm_io_base | 1);
598         pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
599         smb_io_base = SMB_IO_BASE;
600         pci_config_writel(d, 0x90, smb_io_base | 1);
601         pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
602         pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
603 #ifdef BX_USE_SMM
604         smm_init(d);
605 #endif
606         acpi_enabled = 1;
607     }
608 }
609
610 void pci_for_each_device(void (*init_func)(PCIDevice *d))
611 {
612     PCIDevice d1, *d = &d1;
613     int bus, devfn;
614     uint16_t vendor_id, device_id;
615
616     for(bus = 0; bus < 1; bus++) {
617         for(devfn = 0; devfn < 256; devfn++) {
618             d->bus = bus;
619             d->devfn = devfn;
620             vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
621             device_id = pci_config_readw(d, PCI_DEVICE_ID);
622             if (vendor_id != 0xffff || device_id != 0xffff) {
623                 init_func(d);
624             }
625         }
626     }
627 }
628
629 void pci_bios_init(void)
630 {
631     pci_bios_io_addr = 0xc000;
632     pci_bios_mem_addr = 0xf0000000;
633     pci_bios_bigmem_addr = ram_size;
634     if (pci_bios_bigmem_addr < 0x90000000)
635         pci_bios_bigmem_addr = 0x90000000;
636
637     pci_for_each_device(pci_bios_init_bridges);
638
639     pci_for_each_device(pci_bios_init_device);
640 }
641
642 /****************************************************/
643 /* Multi Processor table init */
644
645 static void putb(uint8_t **pp, int val)
646 {
647     uint8_t *q;
648     q = *pp;
649     *q++ = val;
650     *pp = q;
651 }
652
653 static void putstr(uint8_t **pp, const char *str)
654 {
655     uint8_t *q;
656     q = *pp;
657     while (*str)
658         *q++ = *str++;
659     *pp = q;
660 }
661
662 static void putle16(uint8_t **pp, int val)
663 {
664     uint8_t *q;
665     q = *pp;
666     *q++ = val;
667     *q++ = val >> 8;
668     *pp = q;
669 }
670
671 static void putle32(uint8_t **pp, int val)
672 {
673     uint8_t *q;
674     q = *pp;
675     *q++ = val;
676     *q++ = val >> 8;
677     *q++ = val >> 16;
678     *q++ = val >> 24;
679     *pp = q;
680 }
681
682 static int mpf_checksum(const uint8_t *data, int len)
683 {
684     int sum, i;
685     sum = 0;
686     for(i = 0; i < len; i++)
687         sum += data[i];
688     return sum & 0xff;
689 }
690
691 static unsigned long align(unsigned long addr, unsigned long v)
692 {
693     return (addr + v - 1) & ~(v - 1);
694 }
695
696 static void mptable_init(void)
697 {
698     uint8_t *mp_config_table, *q, *float_pointer_struct;
699     int ioapic_id, i, len;
700     int mp_config_table_size;
701
702 #ifdef BX_QEMU
703     if (smp_cpus <= 1)
704         return;
705 #endif
706
707 #ifdef BX_USE_EBDA_TABLES
708     mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
709 #else
710     bios_table_cur_addr = align(bios_table_cur_addr, 16);
711     mp_config_table = (uint8_t *)bios_table_cur_addr;
712 #endif
713     q = mp_config_table;
714     putstr(&q, "PCMP"); /* "PCMP signature */
715     putle16(&q, 0); /* table length (patched later) */
716     putb(&q, 4); /* spec rev */
717     putb(&q, 0); /* checksum (patched later) */
718 #ifdef BX_QEMU
719     putstr(&q, "QEMUCPU "); /* OEM id */
720 #else
721     putstr(&q, "BOCHSCPU");
722 #endif
723     putstr(&q, "0.1         "); /* vendor id */
724     putle32(&q, 0); /* OEM table ptr */
725     putle16(&q, 0); /* OEM table size */
726     putle16(&q, smp_cpus + 18); /* entry count */
727     putle32(&q, 0xfee00000); /* local APIC addr */
728     putle16(&q, 0); /* ext table length */
729     putb(&q, 0); /* ext table checksum */
730     putb(&q, 0); /* reserved */
731
732     for(i = 0; i < smp_cpus; i++) {
733         putb(&q, 0); /* entry type = processor */
734         putb(&q, i); /* APIC id */
735         putb(&q, 0x11); /* local APIC version number */
736         if (i == 0)
737             putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
738         else
739             putb(&q, 1); /* cpu flags: enabled */
740         putb(&q, 0); /* cpu signature */
741         putb(&q, 6);
742         putb(&q, 0);
743         putb(&q, 0);
744         putle16(&q, 0x201); /* feature flags */
745         putle16(&q, 0);
746
747         putle16(&q, 0); /* reserved */
748         putle16(&q, 0);
749         putle16(&q, 0);
750         putle16(&q, 0);
751     }
752
753     /* isa bus */
754     putb(&q, 1); /* entry type = bus */
755     putb(&q, 0); /* bus ID */
756     putstr(&q, "ISA   ");
757
758     /* ioapic */
759     ioapic_id = smp_cpus;
760     putb(&q, 2); /* entry type = I/O APIC */
761     putb(&q, ioapic_id); /* apic ID */
762     putb(&q, 0x11); /* I/O APIC version number */
763     putb(&q, 1); /* enable */
764     putle32(&q, 0xfec00000); /* I/O APIC addr */
765
766     /* irqs */
767     for(i = 0; i < 16; i++) {
768         putb(&q, 3); /* entry type = I/O interrupt */
769         putb(&q, 0); /* interrupt type = vectored interrupt */
770         putb(&q, 0); /* flags: po=0, el=0 */
771         putb(&q, 0);
772         putb(&q, 0); /* source bus ID = ISA */
773         putb(&q, i); /* source bus IRQ */
774         putb(&q, ioapic_id); /* dest I/O APIC ID */
775         putb(&q, i); /* dest I/O APIC interrupt in */
776     }
777     /* patch length */
778     len = q - mp_config_table;
779     mp_config_table[4] = len;
780     mp_config_table[5] = len >> 8;
781
782     mp_config_table[7] = -mpf_checksum(mp_config_table, q - mp_config_table);
783
784     mp_config_table_size = q - mp_config_table;
785
786 #ifndef BX_USE_EBDA_TABLES
787     bios_table_cur_addr += mp_config_table_size;
788 #endif
789
790     /* floating pointer structure */
791 #ifdef BX_USE_EBDA_TABLES
792     ebda_cur_addr = align(ebda_cur_addr, 16);
793     float_pointer_struct = (uint8_t *)ebda_cur_addr;
794 #else
795     bios_table_cur_addr = align(bios_table_cur_addr, 16);
796     float_pointer_struct = (uint8_t *)bios_table_cur_addr;
797 #endif
798     q = float_pointer_struct;
799     putstr(&q, "_MP_");
800     /* pointer to MP config table */
801     putle32(&q, (unsigned long)mp_config_table);
802
803     putb(&q, 1); /* length in 16 byte units */
804     putb(&q, 4); /* MP spec revision */
805     putb(&q, 0); /* checksum (patched later) */
806     putb(&q, 0); /* MP feature byte 1 */
807
808     putb(&q, 0);
809     putb(&q, 0);
810     putb(&q, 0);
811     putb(&q, 0);
812     float_pointer_struct[10] =
813         -mpf_checksum(float_pointer_struct, q - float_pointer_struct);
814 #ifdef BX_USE_EBDA_TABLES
815     ebda_cur_addr += (q - float_pointer_struct);
816 #else
817     bios_table_cur_addr += (q - float_pointer_struct);
818 #endif
819     BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
820             (unsigned long)float_pointer_struct,
821             (unsigned long)mp_config_table,
822             mp_config_table_size);
823 }
824
825 /****************************************************/
826 /* ACPI tables init */
827
828 /* Table structure from Linux kernel (the ACPI tables are under the
829    BSD license) */
830
831 #define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
832         uint8_t                            signature [4];          /* ACPI signature (4 ASCII characters) */\
833         uint32_t                             length;                 /* Length of table, in bytes, including header */\
834         uint8_t                              revision;               /* ACPI Specification minor version # */\
835         uint8_t                              checksum;               /* To make sum of entire table == 0 */\
836         uint8_t                            oem_id [6];             /* OEM identification */\
837         uint8_t                            oem_table_id [8];       /* OEM table identification */\
838         uint32_t                             oem_revision;           /* OEM revision number */\
839         uint8_t                            asl_compiler_id [4];    /* ASL compiler vendor ID */\
840         uint32_t                             asl_compiler_revision;  /* ASL compiler revision number */
841
842
843 struct acpi_table_header         /* ACPI common table header */
844 {
845         ACPI_TABLE_HEADER_DEF
846 };
847
848 struct rsdp_descriptor         /* Root System Descriptor Pointer */
849 {
850         uint8_t                            signature [8];          /* ACPI signature, contains "RSD PTR " */
851         uint8_t                              checksum;               /* To make sum of struct == 0 */
852         uint8_t                            oem_id [6];             /* OEM identification */
853         uint8_t                              revision;               /* Must be 0 for 1.0, 2 for 2.0 */
854         uint32_t                             rsdt_physical_address;  /* 32-bit physical address of RSDT */
855         uint32_t                             length;                 /* XSDT Length in bytes including hdr */
856         uint64_t                             xsdt_physical_address;  /* 64-bit physical address of XSDT */
857         uint8_t                              extended_checksum;      /* Checksum of entire table */
858         uint8_t                            reserved [3];           /* Reserved field must be 0 */
859 };
860
861 /*
862  * ACPI 1.0 Root System Description Table (RSDT)
863  */
864 struct rsdt_descriptor_rev1
865 {
866         ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
867         uint32_t                             table_offset_entry [3]; /* Array of pointers to other */
868                          /* ACPI tables */
869 };
870
871 /*
872  * ACPI 1.0 Firmware ACPI Control Structure (FACS)
873  */
874 struct facs_descriptor_rev1
875 {
876         uint8_t                            signature[4];           /* ACPI Signature */
877         uint32_t                             length;                 /* Length of structure, in bytes */
878         uint32_t                             hardware_signature;     /* Hardware configuration signature */
879         uint32_t                             firmware_waking_vector; /* ACPI OS waking vector */
880         uint32_t                             global_lock;            /* Global Lock */
881         uint32_t                             S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
882         uint32_t                             reserved1       : 31;   /* Must be 0 */
883         uint8_t                              resverved3 [40];        /* Reserved - must be zero */
884 };
885
886
887 /*
888  * ACPI 1.0 Fixed ACPI Description Table (FADT)
889  */
890 struct fadt_descriptor_rev1
891 {
892         ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
893         uint32_t                             firmware_ctrl;          /* Physical address of FACS */
894         uint32_t                             dsdt;                   /* Physical address of DSDT */
895         uint8_t                              model;                  /* System Interrupt Model */
896         uint8_t                              reserved1;              /* Reserved */
897         uint16_t                             sci_int;                /* System vector of SCI interrupt */
898         uint32_t                             smi_cmd;                /* Port address of SMI command port */
899         uint8_t                              acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
900         uint8_t                              acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
901         uint8_t                              S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
902         uint8_t                              reserved2;              /* Reserved - must be zero */
903         uint32_t                             pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
904         uint32_t                             pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
905         uint32_t                             pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
906         uint32_t                             pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
907         uint32_t                             pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
908         uint32_t                             pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
909         uint32_t                             gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
910         uint32_t                             gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
911         uint8_t                              pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
912         uint8_t                              pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
913         uint8_t                              pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
914         uint8_t                              pm_tmr_len;              /* Byte Length of ports at pm_tm_blk */
915         uint8_t                              gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
916         uint8_t                              gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
917         uint8_t                              gpe1_base;              /* Offset in gpe model where gpe1 events start */
918         uint8_t                              reserved3;              /* Reserved */
919         uint16_t                             plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
920         uint16_t                             plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
921         uint16_t                             flush_size;             /* Size of area read to flush caches */
922         uint16_t                             flush_stride;           /* Stride used in flushing caches */
923         uint8_t                              duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
924         uint8_t                              duty_width;             /* Bit width of duty cycle field in p_cnt reg */
925         uint8_t                              day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
926         uint8_t                              mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
927         uint8_t                              century;                /* Index to century in RTC CMOS RAM */
928         uint8_t                              reserved4;              /* Reserved */
929         uint8_t                              reserved4a;             /* Reserved */
930         uint8_t                              reserved4b;             /* Reserved */
931 #if 0
932         uint32_t                             wb_invd         : 1;    /* The wbinvd instruction works properly */
933         uint32_t                             wb_invd_flush   : 1;    /* The wbinvd flushes but does not invalidate */
934         uint32_t                             proc_c1         : 1;    /* All processors support C1 state */
935         uint32_t                             plvl2_up        : 1;    /* C2 state works on MP system */
936         uint32_t                             pwr_button      : 1;    /* Power button is handled as a generic feature */
937         uint32_t                             sleep_button    : 1;    /* Sleep button is handled as a generic feature, or not present */
938         uint32_t                             fixed_rTC       : 1;    /* RTC wakeup stat not in fixed register space */
939         uint32_t                             rtcs4           : 1;    /* RTC wakeup stat not possible from S4 */
940         uint32_t                             tmr_val_ext     : 1;    /* The tmr_val width is 32 bits (0 = 24 bits) */
941         uint32_t                             reserved5       : 23;   /* Reserved - must be zero */
942 #else
943         uint32_t flags;
944 #endif
945 };
946
947 /*
948  * MADT values and structures
949  */
950
951 /* Values for MADT PCATCompat */
952
953 #define DUAL_PIC                0
954 #define MULTIPLE_APIC           1
955
956
957 /* Master MADT */
958
959 struct multiple_apic_table
960 {
961         ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
962         uint32_t                             local_apic_address;     /* Physical address of local APIC */
963 #if 0
964         uint32_t                             PCATcompat      : 1;    /* A one indicates system also has dual 8259s */
965         uint32_t                             reserved1       : 31;
966 #else
967         uint32_t                             flags;
968 #endif
969 };
970
971
972 /* Values for Type in APIC_HEADER_DEF */
973
974 #define APIC_PROCESSOR          0
975 #define APIC_IO                 1
976 #define APIC_XRUPT_OVERRIDE     2
977 #define APIC_NMI                3
978 #define APIC_LOCAL_NMI          4
979 #define APIC_ADDRESS_OVERRIDE   5
980 #define APIC_IO_SAPIC           6
981 #define APIC_LOCAL_SAPIC        7
982 #define APIC_XRUPT_SOURCE       8
983 #define APIC_RESERVED           9           /* 9 and greater are reserved */
984
985 /*
986  * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
987  */
988 #define APIC_HEADER_DEF                     /* Common APIC sub-structure header */\
989         uint8_t                              type; \
990         uint8_t                              length;
991
992 /* Sub-structures for MADT */
993
994 struct madt_processor_apic
995 {
996         APIC_HEADER_DEF
997         uint8_t                              processor_id;           /* ACPI processor id */
998         uint8_t                              local_apic_id;          /* Processor's local APIC id */
999 #if 0
1000         uint32_t                             processor_enabled: 1;   /* Processor is usable if set */
1001         uint32_t                             reserved2       : 31;   /* Reserved, must be zero */
1002 #else
1003         uint32_t flags;
1004 #endif
1005 };
1006
1007 struct madt_io_apic
1008 {
1009         APIC_HEADER_DEF
1010         uint8_t                              io_apic_id;             /* I/O APIC ID */
1011         uint8_t                              reserved;               /* Reserved - must be zero */
1012         uint32_t                             address;                /* APIC physical address */
1013         uint32_t                             interrupt;              /* Global system interrupt where INTI
1014                           * lines start */
1015 };
1016
1017 #include "acpi-dsdt.hex"
1018
1019 static inline uint16_t cpu_to_le16(uint16_t x)
1020 {
1021     return x;
1022 }
1023
1024 static inline uint32_t cpu_to_le32(uint32_t x)
1025 {
1026     return x;
1027 }
1028
1029 static int acpi_checksum(const uint8_t *data, int len)
1030 {
1031     int sum, i;
1032     sum = 0;
1033     for(i = 0; i < len; i++)
1034         sum += data[i];
1035     return (-sum) & 0xff;
1036 }
1037
1038 static void acpi_build_table_header(struct acpi_table_header *h,
1039                                     char *sig, int len, uint8_t rev)
1040 {
1041     memcpy(h->signature, sig, 4);
1042     h->length = cpu_to_le32(len);
1043     h->revision = rev;
1044 #ifdef BX_QEMU
1045     memcpy(h->oem_id, "QEMU  ", 6);
1046     memcpy(h->oem_table_id, "QEMU", 4);
1047 #else
1048     memcpy(h->oem_id, "BOCHS ", 6);
1049     memcpy(h->oem_table_id, "BXPC", 4);
1050 #endif
1051     memcpy(h->oem_table_id + 4, sig, 4);
1052     h->oem_revision = cpu_to_le32(1);
1053 #ifdef BX_QEMU
1054     memcpy(h->asl_compiler_id, "QEMU", 4);
1055 #else
1056     memcpy(h->asl_compiler_id, "BXPC", 4);
1057 #endif
1058     h->asl_compiler_revision = cpu_to_le32(1);
1059     h->checksum = acpi_checksum((void *)h, len);
1060 }
1061
1062 int acpi_build_processor_ssdt(uint8_t *ssdt)
1063 {
1064     uint8_t *ssdt_ptr = ssdt;
1065     int i, length;
1066     int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
1067
1068     ssdt_ptr[9] = 0; // checksum;
1069     ssdt_ptr += sizeof(struct acpi_table_header);
1070
1071     // caluculate the length of processor block and scope block excluding PkgLength
1072     length = 0x0d * acpi_cpus + 4;
1073
1074     // build processor scope header
1075     *(ssdt_ptr++) = 0x10; // ScopeOp
1076     if (length <= 0x3e) {
1077         *(ssdt_ptr++) = length + 1;
1078     } else {
1079         *(ssdt_ptr++) = 0x7F;
1080         *(ssdt_ptr++) = (length + 2) >> 6;
1081     }
1082     *(ssdt_ptr++) = '_'; // Name
1083     *(ssdt_ptr++) = 'P';
1084     *(ssdt_ptr++) = 'R';
1085     *(ssdt_ptr++) = '_';
1086
1087     // build object for each processor
1088     for(i=0;i<acpi_cpus;i++) {
1089         *(ssdt_ptr++) = 0x5B; // ProcessorOp
1090         *(ssdt_ptr++) = 0x83;
1091         *(ssdt_ptr++) = 0x0B; // Length
1092         *(ssdt_ptr++) = 'C';  // Name (CPUxx)
1093         *(ssdt_ptr++) = 'P';
1094         if ((i & 0xf0) != 0)
1095             *(ssdt_ptr++) = (i >> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa;
1096         else
1097             *(ssdt_ptr++) = 'U';
1098         *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa;
1099         *(ssdt_ptr++) = i;
1100         *(ssdt_ptr++) = 0x10; // Processor block address
1101         *(ssdt_ptr++) = 0xb0;
1102         *(ssdt_ptr++) = 0;
1103         *(ssdt_ptr++) = 0;
1104         *(ssdt_ptr++) = 6;    // Processor block length
1105     }
1106
1107     acpi_build_table_header((struct acpi_table_header *)ssdt,
1108                             "SSDT", ssdt_ptr - ssdt, 1);
1109
1110     return ssdt_ptr - ssdt;
1111 }
1112
1113 /* base_addr must be a multiple of 4KB */
1114 void acpi_bios_init(void)
1115 {
1116     struct rsdp_descriptor *rsdp;
1117     struct rsdt_descriptor_rev1 *rsdt;
1118     struct fadt_descriptor_rev1 *fadt;
1119     struct facs_descriptor_rev1 *facs;
1120     struct multiple_apic_table *madt;
1121     uint8_t *dsdt, *ssdt;
1122     uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
1123     uint32_t acpi_tables_size, madt_addr, madt_size;
1124     int i;
1125
1126     /* reserve memory space for tables */
1127 #ifdef BX_USE_EBDA_TABLES
1128     ebda_cur_addr = align(ebda_cur_addr, 16);
1129     rsdp = (void *)(ebda_cur_addr);
1130     ebda_cur_addr += sizeof(*rsdp);
1131 #else
1132     bios_table_cur_addr = align(bios_table_cur_addr, 16);
1133     rsdp = (void *)(bios_table_cur_addr);
1134     bios_table_cur_addr += sizeof(*rsdp);
1135 #endif
1136
1137     addr = base_addr = ram_size - ACPI_DATA_SIZE;
1138     rsdt_addr = addr;
1139     rsdt = (void *)(addr);
1140     addr += sizeof(*rsdt);
1141
1142     fadt_addr = addr;
1143     fadt = (void *)(addr);
1144     addr += sizeof(*fadt);
1145
1146     /* XXX: FACS should be in RAM */
1147     addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
1148     facs_addr = addr;
1149     facs = (void *)(addr);
1150     addr += sizeof(*facs);
1151
1152     dsdt_addr = addr;
1153     dsdt = (void *)(addr);
1154     addr += sizeof(AmlCode);
1155
1156     ssdt_addr = addr;
1157     ssdt = (void *)(addr);
1158     addr += acpi_build_processor_ssdt(ssdt);
1159
1160     addr = (addr + 7) & ~7;
1161     madt_addr = addr;
1162     madt_size = sizeof(*madt) +
1163         sizeof(struct madt_processor_apic) * smp_cpus +
1164         sizeof(struct madt_io_apic);
1165     madt = (void *)(addr);
1166     addr += madt_size;
1167
1168     acpi_tables_size = addr - base_addr;
1169
1170     BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
1171             (unsigned long)rsdp,
1172             (unsigned long)rsdt, acpi_tables_size);
1173
1174     /* RSDP */
1175     memset(rsdp, 0, sizeof(*rsdp));
1176     memcpy(rsdp->signature, "RSD PTR ", 8);
1177 #ifdef BX_QEMU
1178     memcpy(rsdp->oem_id, "QEMU  ", 6);
1179 #else
1180     memcpy(rsdp->oem_id, "BOCHS ", 6);
1181 #endif
1182     rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
1183     rsdp->checksum = acpi_checksum((void *)rsdp, 20);
1184
1185     /* RSDT */
1186     memset(rsdt, 0, sizeof(*rsdt));
1187     rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
1188     rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
1189     rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
1190     acpi_build_table_header((struct acpi_table_header *)rsdt,
1191                             "RSDT", sizeof(*rsdt), 1);
1192
1193     /* FADT */
1194     memset(fadt, 0, sizeof(*fadt));
1195     fadt->firmware_ctrl = cpu_to_le32(facs_addr);
1196     fadt->dsdt = cpu_to_le32(dsdt_addr);
1197     fadt->model = 1;
1198     fadt->reserved1 = 0;
1199     fadt->sci_int = cpu_to_le16(pm_sci_int);
1200     fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
1201     fadt->acpi_enable = 0xf1;
1202     fadt->acpi_disable = 0xf0;
1203     fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
1204     fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
1205     fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
1206     fadt->pm1_evt_len = 4;
1207     fadt->pm1_cnt_len = 2;
1208     fadt->pm_tmr_len = 4;
1209     fadt->plvl2_lat = cpu_to_le16(50);
1210     fadt->plvl3_lat = cpu_to_le16(50);
1211     fadt->plvl3_lat = cpu_to_le16(50);
1212     /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
1213     fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
1214     acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
1215                             sizeof(*fadt), 1);
1216
1217     /* FACS */
1218     memset(facs, 0, sizeof(*facs));
1219     memcpy(facs->signature, "FACS", 4);
1220     facs->length = cpu_to_le32(sizeof(*facs));
1221
1222     /* DSDT */
1223     memcpy(dsdt, AmlCode, sizeof(AmlCode));
1224
1225     /* MADT */
1226     {
1227         struct madt_processor_apic *apic;
1228         struct madt_io_apic *io_apic;
1229
1230         memset(madt, 0, madt_size);
1231         madt->local_apic_address = cpu_to_le32(0xfee00000);
1232         madt->flags = cpu_to_le32(1);
1233         apic = (void *)(madt + 1);
1234         for(i=0;i<smp_cpus;i++) {
1235             apic->type = APIC_PROCESSOR;
1236             apic->length = sizeof(*apic);
1237             apic->processor_id = i;
1238             apic->local_apic_id = i;
1239             apic->flags = cpu_to_le32(1);
1240             apic++;
1241         }
1242         io_apic = (void *)apic;
1243         io_apic->type = APIC_IO;
1244         io_apic->length = sizeof(*io_apic);
1245         io_apic->io_apic_id = smp_cpus;
1246         io_apic->address = cpu_to_le32(0xfec00000);
1247         io_apic->interrupt = cpu_to_le32(0);
1248
1249         acpi_build_table_header((struct acpi_table_header *)madt,
1250                                 "APIC", madt_size, 1);
1251     }
1252 }
1253
1254 /* SMBIOS entry point -- must be written to a 16-bit aligned address
1255    between 0xf0000 and 0xfffff.
1256  */
1257 struct smbios_entry_point {
1258         char anchor_string[4];
1259         uint8_t checksum;
1260         uint8_t length;
1261         uint8_t smbios_major_version;
1262         uint8_t smbios_minor_version;
1263         uint16_t max_structure_size;
1264         uint8_t entry_point_revision;
1265         uint8_t formatted_area[5];
1266         char intermediate_anchor_string[5];
1267         uint8_t intermediate_checksum;
1268         uint16_t structure_table_length;
1269         uint32_t structure_table_address;
1270         uint16_t number_of_structures;
1271         uint8_t smbios_bcd_revision;
1272 } __attribute__((__packed__));
1273
1274 /* This goes at the beginning of every SMBIOS structure. */
1275 struct smbios_structure_header {
1276         uint8_t type;
1277         uint8_t length;
1278         uint16_t handle;
1279 } __attribute__((__packed__));
1280
1281 /* SMBIOS type 0 - BIOS Information */
1282 struct smbios_type_0 {
1283         struct smbios_structure_header header;
1284         uint8_t vendor_str;
1285         uint8_t bios_version_str;
1286         uint16_t bios_starting_address_segment;
1287         uint8_t bios_release_date_str;
1288         uint8_t bios_rom_size;
1289         uint8_t bios_characteristics[8];
1290         uint8_t bios_characteristics_extension_bytes[2];
1291         uint8_t system_bios_major_release;
1292         uint8_t system_bios_minor_release;
1293         uint8_t embedded_controller_major_release;
1294         uint8_t embedded_controller_minor_release;
1295 } __attribute__((__packed__));
1296
1297 /* SMBIOS type 1 - System Information */
1298 struct smbios_type_1 {
1299         struct smbios_structure_header header;
1300         uint8_t manufacturer_str;
1301         uint8_t product_name_str;
1302         uint8_t version_str;
1303         uint8_t serial_number_str;
1304         uint8_t uuid[16];
1305         uint8_t wake_up_type;
1306         uint8_t sku_number_str;
1307         uint8_t family_str;
1308 } __attribute__((__packed__));
1309
1310 /* SMBIOS type 3 - System Enclosure (v2.3) */
1311 struct smbios_type_3 {
1312         struct smbios_structure_header header;
1313         uint8_t manufacturer_str;
1314         uint8_t type;
1315         uint8_t version_str;
1316         uint8_t serial_number_str;
1317         uint8_t asset_tag_number_str;
1318         uint8_t boot_up_state;
1319         uint8_t power_supply_state;
1320         uint8_t thermal_state;
1321         uint8_t security_status;
1322     uint32_t oem_defined;
1323     uint8_t height;
1324     uint8_t number_of_power_cords;
1325     uint8_t contained_element_count;
1326     // contained elements follow
1327 } __attribute__((__packed__));
1328
1329 /* SMBIOS type 4 - Processor Information (v2.0) */
1330 struct smbios_type_4 {
1331         struct smbios_structure_header header;
1332         uint8_t socket_designation_str;
1333         uint8_t processor_type;
1334         uint8_t processor_family;
1335         uint8_t processor_manufacturer_str;
1336         uint32_t processor_id[2];
1337         uint8_t processor_version_str;
1338         uint8_t voltage;
1339         uint16_t external_clock;
1340         uint16_t max_speed;
1341         uint16_t current_speed;
1342         uint8_t status;
1343         uint8_t processor_upgrade;
1344 } __attribute__((__packed__));
1345
1346 /* SMBIOS type 16 - Physical Memory Array
1347  *   Associated with one type 17 (Memory Device).
1348  */
1349 struct smbios_type_16 {
1350         struct smbios_structure_header header;
1351         uint8_t location;
1352         uint8_t use;
1353         uint8_t error_correction;
1354         uint32_t maximum_capacity;
1355         uint16_t memory_error_information_handle;
1356         uint16_t number_of_memory_devices;
1357 } __attribute__((__packed__));
1358
1359 /* SMBIOS type 17 - Memory Device
1360  *   Associated with one type 19
1361  */
1362 struct smbios_type_17 {
1363         struct smbios_structure_header header;
1364         uint16_t physical_memory_array_handle;
1365         uint16_t memory_error_information_handle;
1366         uint16_t total_width;
1367         uint16_t data_width;
1368         uint16_t size;
1369         uint8_t form_factor;
1370         uint8_t device_set;
1371         uint8_t device_locator_str;
1372         uint8_t bank_locator_str;
1373         uint8_t memory_type;
1374         uint16_t type_detail;
1375 } __attribute__((__packed__));
1376
1377 /* SMBIOS type 19 - Memory Array Mapped Address */
1378 struct smbios_type_19 {
1379         struct smbios_structure_header header;
1380         uint32_t starting_address;
1381         uint32_t ending_address;
1382         uint16_t memory_array_handle;
1383         uint8_t partition_width;
1384 } __attribute__((__packed__));
1385
1386 /* SMBIOS type 20 - Memory Device Mapped Address */
1387 struct smbios_type_20 {
1388         struct smbios_structure_header header;
1389         uint32_t starting_address;
1390         uint32_t ending_address;
1391         uint16_t memory_device_handle;
1392         uint16_t memory_array_mapped_address_handle;
1393         uint8_t partition_row_position;
1394         uint8_t interleave_position;
1395         uint8_t interleaved_data_depth;
1396 } __attribute__((__packed__));
1397
1398 /* SMBIOS type 32 - System Boot Information */
1399 struct smbios_type_32 {
1400         struct smbios_structure_header header;
1401         uint8_t reserved[6];
1402         uint8_t boot_status;
1403 } __attribute__((__packed__));
1404
1405 /* SMBIOS type 127 -- End-of-table */
1406 struct smbios_type_127 {
1407         struct smbios_structure_header header;
1408 } __attribute__((__packed__));
1409
1410 static void
1411 smbios_entry_point_init(void *start,
1412                         uint16_t max_structure_size,
1413                         uint16_t structure_table_length,
1414                         uint32_t structure_table_address,
1415                         uint16_t number_of_structures)
1416 {
1417     uint8_t sum;
1418     int i;
1419     struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
1420
1421     memcpy(ep->anchor_string, "_SM_", 4);
1422     ep->length = 0x1f;
1423     ep->smbios_major_version = 2;
1424     ep->smbios_minor_version = 4;
1425     ep->max_structure_size = max_structure_size;
1426     ep->entry_point_revision = 0;
1427     memset(ep->formatted_area, 0, 5);
1428     memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
1429
1430     ep->structure_table_length = structure_table_length;
1431     ep->structure_table_address = structure_table_address;
1432     ep->number_of_structures = number_of_structures;
1433     ep->smbios_bcd_revision = 0x24;
1434
1435     ep->checksum = 0;
1436     ep->intermediate_checksum = 0;
1437
1438     sum = 0;
1439     for (i = 0; i < 0x10; i++)
1440         sum += ((int8_t *)start)[i];
1441     ep->checksum = -sum;
1442
1443     sum = 0;
1444     for (i = 0x10; i < ep->length; i++)
1445         sum += ((int8_t *)start)[i];
1446     ep->intermediate_checksum = -sum;
1447     }
1448
1449 /* Type 0 -- BIOS Information */
1450 #define RELEASE_DATE_STR "01/01/2007"
1451 static void *
1452 smbios_type_0_init(void *start)
1453 {
1454     struct smbios_type_0 *p = (struct smbios_type_0 *)start;
1455
1456     p->header.type = 0;
1457     p->header.length = sizeof(struct smbios_type_0);
1458     p->header.handle = 0;
1459
1460     p->vendor_str = 1;
1461     p->bios_version_str = 1;
1462     p->bios_starting_address_segment = 0xe800;
1463     p->bios_release_date_str = 2;
1464     p->bios_rom_size = 0; /* FIXME */
1465
1466     memset(p->bios_characteristics, 0, 7);
1467     p->bios_characteristics[7] = 0x08; /* BIOS characteristics not supported */
1468     p->bios_characteristics_extension_bytes[0] = 0;
1469     p->bios_characteristics_extension_bytes[1] = 0;
1470
1471     p->system_bios_major_release = 1;
1472     p->system_bios_minor_release = 0;
1473     p->embedded_controller_major_release = 0xff;
1474     p->embedded_controller_minor_release = 0xff;
1475
1476     start += sizeof(struct smbios_type_0);
1477     memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
1478     start += sizeof(BX_APPNAME);
1479     memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
1480     start += sizeof(RELEASE_DATE_STR);
1481     *((uint8_t *)start) = 0;
1482
1483     return start+1;
1484 }
1485
1486 /* Type 1 -- System Information */
1487 static void *
1488 smbios_type_1_init(void *start)
1489 {
1490     struct smbios_type_1 *p = (struct smbios_type_1 *)start;
1491     p->header.type = 1;
1492     p->header.length = sizeof(struct smbios_type_1);
1493     p->header.handle = 0x100;
1494
1495     p->manufacturer_str = 0;
1496     p->product_name_str = 0;
1497     p->version_str = 0;
1498     p->serial_number_str = 0;
1499
1500     memcpy(p->uuid, bios_uuid, 16);
1501
1502     p->wake_up_type = 0x06; /* power switch */
1503     p->sku_number_str = 0;
1504     p->family_str = 0;
1505
1506     start += sizeof(struct smbios_type_1);
1507     *((uint16_t *)start) = 0;
1508
1509     return start+2;
1510 }
1511
1512 /* Type 3 -- System Enclosure */
1513 static void *
1514 smbios_type_3_init(void *start)
1515 {
1516     struct smbios_type_3 *p = (struct smbios_type_3 *)start;
1517
1518     p->header.type = 3;
1519     p->header.length = sizeof(struct smbios_type_3);
1520     p->header.handle = 0x300;
1521
1522     p->manufacturer_str = 0;
1523     p->type = 0x01; /* other */
1524     p->version_str = 0;
1525     p->serial_number_str = 0;
1526     p->asset_tag_number_str = 0;
1527     p->boot_up_state = 0x03; /* safe */
1528     p->power_supply_state = 0x03; /* safe */
1529     p->thermal_state = 0x03; /* safe */
1530     p->security_status = 0x02; /* unknown */
1531     p->oem_defined = 0;
1532     p->height = 0;
1533     p->number_of_power_cords = 0;
1534     p->contained_element_count = 0;
1535
1536     start += sizeof(struct smbios_type_3);
1537     *((uint16_t *)start) = 0;
1538
1539     return start+2;
1540 }
1541
1542 /* Type 4 -- Processor Information */
1543 static void *
1544 smbios_type_4_init(void *start, unsigned int cpu_number)
1545 {
1546     struct smbios_type_4 *p = (struct smbios_type_4 *)start;
1547
1548     p->header.type = 4;
1549     p->header.length = sizeof(struct smbios_type_4);
1550     p->header.handle = 0x400 + cpu_number;
1551
1552     p->socket_designation_str = 1;
1553     p->processor_type = 0x03; /* CPU */
1554     p->processor_family = 0x01; /* other */
1555     p->processor_manufacturer_str = 0;
1556
1557     p->processor_id[0] = cpuid_signature;
1558     p->processor_id[1] = cpuid_features;
1559
1560     p->processor_version_str = 0;
1561     p->voltage = 0;
1562     p->external_clock = 0;
1563
1564     p->max_speed = 0; /* unknown */
1565     p->current_speed = 0; /* unknown */
1566
1567     p->status = 0x41; /* socket populated, CPU enabled */
1568     p->processor_upgrade = 0x01; /* other */
1569
1570     start += sizeof(struct smbios_type_4);
1571
1572     memcpy((char *)start, "CPU  " "\0" "" "\0" "", 7);
1573         ((char *)start)[4] = cpu_number + '0';
1574
1575     return start+7;
1576 }
1577
1578 /* Type 16 -- Physical Memory Array */
1579 static void *
1580 smbios_type_16_init(void *start, uint32_t memsize)
1581 {
1582     struct smbios_type_16 *p = (struct smbios_type_16*)start;
1583
1584     p->header.type = 16;
1585     p->header.length = sizeof(struct smbios_type_16);
1586     p->header.handle = 0x1000;
1587
1588     p->location = 0x01; /* other */
1589     p->use = 0x03; /* system memory */
1590     p->error_correction = 0x01; /* other */
1591     p->maximum_capacity = memsize * 1024;
1592     p->memory_error_information_handle = 0xfffe; /* none provided */
1593     p->number_of_memory_devices = 1;
1594
1595     start += sizeof(struct smbios_type_16);
1596     *((uint16_t *)start) = 0;
1597
1598     return start + 2;
1599 }
1600
1601 /* Type 17 -- Memory Device */
1602 static void *
1603 smbios_type_17_init(void *start, uint32_t memory_size_mb)
1604 {
1605     struct smbios_type_17 *p = (struct smbios_type_17 *)start;
1606
1607     p->header.type = 17;
1608     p->header.length = sizeof(struct smbios_type_17);
1609     p->header.handle = 0x1100;
1610
1611     p->physical_memory_array_handle = 0x1000;
1612     p->total_width = 64;
1613     p->data_width = 64;
1614     /* truncate memory_size_mb to 16 bits and clear most significant
1615        bit [indicates size in MB] */
1616     p->size = (uint16_t) memory_size_mb & 0x7fff;
1617     p->form_factor = 0x09; /* DIMM */
1618     p->device_set = 0;
1619     p->device_locator_str = 1;
1620     p->bank_locator_str = 0;
1621     p->memory_type = 0x07; /* RAM */
1622     p->type_detail = 0;
1623
1624     start += sizeof(struct smbios_type_17);
1625     memcpy((char *)start, "DIMM 1", 7);
1626     start += 7;
1627     *((uint8_t *)start) = 0;
1628
1629     return start+1;
1630 }
1631
1632 /* Type 19 -- Memory Array Mapped Address */
1633 static void *
1634 smbios_type_19_init(void *start, uint32_t memory_size_mb)
1635 {
1636     struct smbios_type_19 *p = (struct smbios_type_19 *)start;
1637
1638     p->header.type = 19;
1639     p->header.length = sizeof(struct smbios_type_19);
1640     p->header.handle = 0x1300;
1641
1642     p->starting_address = 0;
1643     p->ending_address = (memory_size_mb-1) * 1024;
1644     p->memory_array_handle = 0x1000;
1645     p->partition_width = 1;
1646
1647     start += sizeof(struct smbios_type_19);
1648     *((uint16_t *)start) = 0;
1649
1650     return start + 2;
1651 }
1652
1653 /* Type 20 -- Memory Device Mapped Address */
1654 static void *
1655 smbios_type_20_init(void *start, uint32_t memory_size_mb)
1656 {
1657     struct smbios_type_20 *p = (struct smbios_type_20 *)start;
1658
1659     p->header.type = 20;
1660     p->header.length = sizeof(struct smbios_type_20);
1661     p->header.handle = 0x1400;
1662
1663     p->starting_address = 0;
1664     p->ending_address = (memory_size_mb-1)*1024;
1665     p->memory_device_handle = 0x1100;
1666     p->memory_array_mapped_address_handle = 0x1300;
1667     p->partition_row_position = 1;
1668     p->interleave_position = 0;
1669     p->interleaved_data_depth = 0;
1670
1671     start += sizeof(struct smbios_type_20);
1672
1673     *((uint16_t *)start) = 0;
1674     return start+2;
1675 }
1676
1677 /* Type 32 -- System Boot Information */
1678 static void *
1679 smbios_type_32_init(void *start)
1680 {
1681     struct smbios_type_32 *p = (struct smbios_type_32 *)start;
1682
1683     p->header.type = 32;
1684     p->header.length = sizeof(struct smbios_type_32);
1685     p->header.handle = 0x2000;
1686     memset(p->reserved, 0, 6);
1687     p->boot_status = 0; /* no errors detected */
1688
1689     start += sizeof(struct smbios_type_32);
1690     *((uint16_t *)start) = 0;
1691
1692     return start+2;
1693 }
1694
1695 /* Type 127 -- End of Table */
1696 static void *
1697 smbios_type_127_init(void *start)
1698 {
1699     struct smbios_type_127 *p = (struct smbios_type_127 *)start;
1700
1701     p->header.type = 127;
1702     p->header.length = sizeof(struct smbios_type_127);
1703     p->header.handle = 0x7f00;
1704
1705     start += sizeof(struct smbios_type_127);
1706     *((uint16_t *)start) = 0;
1707
1708     return start + 2;
1709 }
1710
1711 void smbios_init(void)
1712 {
1713     unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
1714     char *start, *p, *q;
1715     int memsize = ram_size / (1024 * 1024);
1716
1717 #ifdef BX_USE_EBDA_TABLES
1718     ebda_cur_addr = align(ebda_cur_addr, 16);
1719     start = (void *)(ebda_cur_addr);
1720 #else
1721     bios_table_cur_addr = align(bios_table_cur_addr, 16);
1722     start = (void *)(bios_table_cur_addr);
1723 #endif
1724
1725         p = (char *)start + sizeof(struct smbios_entry_point);
1726
1727 #define add_struct(fn) { \
1728     q = (fn); \
1729     nr_structs++; \
1730     if ((q - p) > max_struct_size) \
1731         max_struct_size = q - p; \
1732     p = q; \
1733 }
1734
1735     add_struct(smbios_type_0_init(p));
1736     add_struct(smbios_type_1_init(p));
1737     add_struct(smbios_type_3_init(p));
1738     for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
1739         add_struct(smbios_type_4_init(p, cpu_num));
1740     add_struct(smbios_type_16_init(p, memsize));
1741     add_struct(smbios_type_17_init(p, memsize));
1742     add_struct(smbios_type_19_init(p, memsize));
1743     add_struct(smbios_type_20_init(p, memsize));
1744     add_struct(smbios_type_32_init(p));
1745     add_struct(smbios_type_127_init(p));
1746
1747 #undef add_struct
1748
1749     smbios_entry_point_init(
1750         start, max_struct_size,
1751         (p - (char *)start) - sizeof(struct smbios_entry_point),
1752         (uint32_t)(start + sizeof(struct smbios_entry_point)),
1753         nr_structs);
1754
1755 #ifdef BX_USE_EBDA_TABLES
1756     ebda_cur_addr += (p - (char *)start);
1757 #else
1758     bios_table_cur_addr += (p - (char *)start);
1759 #endif
1760
1761     BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
1762 }
1763
1764 void rombios32_init(void)
1765 {
1766     BX_INFO("Starting rombios32\n");
1767
1768     ram_probe();
1769
1770     cpu_probe();
1771
1772     smp_probe();
1773
1774     uuid_probe();
1775
1776     pci_bios_init();
1777
1778     if (bios_table_cur_addr != 0) {
1779
1780         mptable_init();
1781
1782         smbios_init();
1783
1784         if (acpi_enabled)
1785             acpi_bios_init();
1786
1787         bios_lock_shadow_ram();
1788
1789         BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
1790         if (bios_table_cur_addr > bios_table_end_addr)
1791             BX_PANIC("bios_table_end_addr overflow!\n");
1792     }
1793 }