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