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