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