Unify checksum functions.
[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 unsigned long align(unsigned long addr, unsigned long v)
638 {
639     return (addr + v - 1) & ~(v - 1);
640 }
641
642 static void mptable_init(void)
643 {
644     u8 *mp_config_table, *q, *float_pointer_struct;
645     int ioapic_id, i, len;
646     int mp_config_table_size;
647
648 #ifdef BX_QEMU
649     if (smp_cpus <= 1)
650         return;
651 #endif
652
653 #ifdef BX_USE_EBDA_TABLES
654     mp_config_table = (u8 *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
655 #else
656     bios_table_cur_addr = align(bios_table_cur_addr, 16);
657     mp_config_table = (u8 *)bios_table_cur_addr;
658 #endif
659     q = mp_config_table;
660     putstr(&q, "PCMP"); /* "PCMP signature */
661     putle16(&q, 0); /* table length (patched later) */
662     putb(&q, 4); /* spec rev */
663     putb(&q, 0); /* checksum (patched later) */
664 #ifdef BX_QEMU
665     putstr(&q, "QEMUCPU "); /* OEM id */
666 #else
667     putstr(&q, "BOCHSCPU");
668 #endif
669     putstr(&q, "0.1         "); /* vendor id */
670     putle32(&q, 0); /* OEM table ptr */
671     putle16(&q, 0); /* OEM table size */
672     putle16(&q, smp_cpus + 18); /* entry count */
673     putle32(&q, 0xfee00000); /* local APIC addr */
674     putle16(&q, 0); /* ext table length */
675     putb(&q, 0); /* ext table checksum */
676     putb(&q, 0); /* reserved */
677
678     for(i = 0; i < smp_cpus; i++) {
679         putb(&q, 0); /* entry type = processor */
680         putb(&q, i); /* APIC id */
681         putb(&q, 0x11); /* local APIC version number */
682         if (i == 0)
683             putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
684         else
685             putb(&q, 1); /* cpu flags: enabled */
686         putb(&q, 0); /* cpu signature */
687         putb(&q, 6);
688         putb(&q, 0);
689         putb(&q, 0);
690         putle16(&q, 0x201); /* feature flags */
691         putle16(&q, 0);
692
693         putle16(&q, 0); /* reserved */
694         putle16(&q, 0);
695         putle16(&q, 0);
696         putle16(&q, 0);
697     }
698
699     /* isa bus */
700     putb(&q, 1); /* entry type = bus */
701     putb(&q, 0); /* bus ID */
702     putstr(&q, "ISA   ");
703
704     /* ioapic */
705     ioapic_id = smp_cpus;
706     putb(&q, 2); /* entry type = I/O APIC */
707     putb(&q, ioapic_id); /* apic ID */
708     putb(&q, 0x11); /* I/O APIC version number */
709     putb(&q, 1); /* enable */
710     putle32(&q, 0xfec00000); /* I/O APIC addr */
711
712     /* irqs */
713     for(i = 0; i < 16; i++) {
714         putb(&q, 3); /* entry type = I/O interrupt */
715         putb(&q, 0); /* interrupt type = vectored interrupt */
716         putb(&q, 0); /* flags: po=0, el=0 */
717         putb(&q, 0);
718         putb(&q, 0); /* source bus ID = ISA */
719         putb(&q, i); /* source bus IRQ */
720         putb(&q, ioapic_id); /* dest I/O APIC ID */
721         putb(&q, i); /* dest I/O APIC interrupt in */
722     }
723     /* patch length */
724     len = q - mp_config_table;
725     mp_config_table[4] = len;
726     mp_config_table[5] = len >> 8;
727
728     mp_config_table[7] = -checksum(mp_config_table, q - mp_config_table);
729
730     mp_config_table_size = q - mp_config_table;
731
732 #ifndef BX_USE_EBDA_TABLES
733     bios_table_cur_addr += mp_config_table_size;
734 #endif
735
736     /* floating pointer structure */
737 #ifdef BX_USE_EBDA_TABLES
738     ebda_cur_addr = align(ebda_cur_addr, 16);
739     float_pointer_struct = (u8 *)ebda_cur_addr;
740 #else
741     bios_table_cur_addr = align(bios_table_cur_addr, 16);
742     float_pointer_struct = (u8 *)bios_table_cur_addr;
743 #endif
744     q = float_pointer_struct;
745     putstr(&q, "_MP_");
746     /* pointer to MP config table */
747     putle32(&q, (unsigned long)mp_config_table);
748
749     putb(&q, 1); /* length in 16 byte units */
750     putb(&q, 4); /* MP spec revision */
751     putb(&q, 0); /* checksum (patched later) */
752     putb(&q, 0); /* MP feature byte 1 */
753
754     putb(&q, 0);
755     putb(&q, 0);
756     putb(&q, 0);
757     putb(&q, 0);
758     float_pointer_struct[10] = -checksum(float_pointer_struct
759                                          , q - float_pointer_struct);
760 #ifdef BX_USE_EBDA_TABLES
761     ebda_cur_addr += (q - float_pointer_struct);
762 #else
763     bios_table_cur_addr += (q - float_pointer_struct);
764 #endif
765     BX_INFO("MP table addr=0x%08lx MPC table addr=0x%08lx size=0x%x\n",
766             (unsigned long)float_pointer_struct,
767             (unsigned long)mp_config_table,
768             mp_config_table_size);
769 }
770
771 /****************************************************/
772 /* ACPI tables init */
773
774 /* Table structure from Linux kernel (the ACPI tables are under the
775    BSD license) */
776
777 #define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
778         u8                            signature [4];          /* ACPI signature (4 ASCII characters) */\
779         u32                             length;                 /* Length of table, in bytes, including header */\
780         u8                              revision;               /* ACPI Specification minor version # */\
781         u8                              checksum;               /* To make sum of entire table == 0 */\
782         u8                            oem_id [6];             /* OEM identification */\
783         u8                            oem_table_id [8];       /* OEM table identification */\
784         u32                             oem_revision;           /* OEM revision number */\
785         u8                            asl_compiler_id [4];    /* ASL compiler vendor ID */\
786         u32                             asl_compiler_revision;  /* ASL compiler revision number */
787
788
789 struct acpi_table_header         /* ACPI common table header */
790 {
791         ACPI_TABLE_HEADER_DEF
792 };
793
794 struct rsdp_descriptor         /* Root System Descriptor Pointer */
795 {
796         u8                            signature [8];          /* ACPI signature, contains "RSD PTR " */
797         u8                              checksum;               /* To make sum of struct == 0 */
798         u8                            oem_id [6];             /* OEM identification */
799         u8                              revision;               /* Must be 0 for 1.0, 2 for 2.0 */
800         u32                             rsdt_physical_address;  /* 32-bit physical address of RSDT */
801         u32                             length;                 /* XSDT Length in bytes including hdr */
802         u64                             xsdt_physical_address;  /* 64-bit physical address of XSDT */
803         u8                              extended_checksum;      /* Checksum of entire table */
804         u8                            reserved [3];           /* Reserved field must be 0 */
805 };
806
807 /*
808  * ACPI 1.0 Root System Description Table (RSDT)
809  */
810 struct rsdt_descriptor_rev1
811 {
812         ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
813         u32                             table_offset_entry [3]; /* Array of pointers to other */
814                          /* ACPI tables */
815 };
816
817 /*
818  * ACPI 1.0 Firmware ACPI Control Structure (FACS)
819  */
820 struct facs_descriptor_rev1
821 {
822         u8                            signature[4];           /* ACPI Signature */
823         u32                             length;                 /* Length of structure, in bytes */
824         u32                             hardware_signature;     /* Hardware configuration signature */
825         u32                             firmware_waking_vector; /* ACPI OS waking vector */
826         u32                             global_lock;            /* Global Lock */
827         u32                             S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
828         u32                             reserved1       : 31;   /* Must be 0 */
829         u8                              resverved3 [40];        /* Reserved - must be zero */
830 };
831
832
833 /*
834  * ACPI 1.0 Fixed ACPI Description Table (FADT)
835  */
836 struct fadt_descriptor_rev1
837 {
838         ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
839         u32                             firmware_ctrl;          /* Physical address of FACS */
840         u32                             dsdt;                   /* Physical address of DSDT */
841         u8                              model;                  /* System Interrupt Model */
842         u8                              reserved1;              /* Reserved */
843         u16                             sci_int;                /* System vector of SCI interrupt */
844         u32                             smi_cmd;                /* Port address of SMI command port */
845         u8                              acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
846         u8                              acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
847         u8                              S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
848         u8                              reserved2;              /* Reserved - must be zero */
849         u32                             pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
850         u32                             pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
851         u32                             pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
852         u32                             pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
853         u32                             pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
854         u32                             pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
855         u32                             gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
856         u32                             gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
857         u8                              pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
858         u8                              pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
859         u8                              pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
860         u8                              pm_tmr_len;              /* Byte Length of ports at pm_tm_blk */
861         u8                              gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
862         u8                              gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
863         u8                              gpe1_base;              /* Offset in gpe model where gpe1 events start */
864         u8                              reserved3;              /* Reserved */
865         u16                             plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
866         u16                             plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
867         u16                             flush_size;             /* Size of area read to flush caches */
868         u16                             flush_stride;           /* Stride used in flushing caches */
869         u8                              duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
870         u8                              duty_width;             /* Bit width of duty cycle field in p_cnt reg */
871         u8                              day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
872         u8                              mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
873         u8                              century;                /* Index to century in RTC CMOS RAM */
874         u8                              reserved4;              /* Reserved */
875         u8                              reserved4a;             /* Reserved */
876         u8                              reserved4b;             /* Reserved */
877 #if 0
878         u32                             wb_invd         : 1;    /* The wbinvd instruction works properly */
879         u32                             wb_invd_flush   : 1;    /* The wbinvd flushes but does not invalidate */
880         u32                             proc_c1         : 1;    /* All processors support C1 state */
881         u32                             plvl2_up        : 1;    /* C2 state works on MP system */
882         u32                             pwr_button      : 1;    /* Power button is handled as a generic feature */
883         u32                             sleep_button    : 1;    /* Sleep button is handled as a generic feature, or not present */
884         u32                             fixed_rTC       : 1;    /* RTC wakeup stat not in fixed register space */
885         u32                             rtcs4           : 1;    /* RTC wakeup stat not possible from S4 */
886         u32                             tmr_val_ext     : 1;    /* The tmr_val width is 32 bits (0 = 24 bits) */
887         u32                             reserved5       : 23;   /* Reserved - must be zero */
888 #else
889         u32 flags;
890 #endif
891 };
892
893 /*
894  * MADT values and structures
895  */
896
897 /* Values for MADT PCATCompat */
898
899 #define DUAL_PIC                0
900 #define MULTIPLE_APIC           1
901
902
903 /* Master MADT */
904
905 struct multiple_apic_table
906 {
907         ACPI_TABLE_HEADER_DEF                           /* ACPI common table header */
908         u32                             local_apic_address;     /* Physical address of local APIC */
909 #if 0
910         u32                             PCATcompat      : 1;    /* A one indicates system also has dual 8259s */
911         u32                             reserved1       : 31;
912 #else
913         u32                             flags;
914 #endif
915 };
916
917
918 /* Values for Type in APIC_HEADER_DEF */
919
920 #define APIC_PROCESSOR          0
921 #define APIC_IO                 1
922 #define APIC_XRUPT_OVERRIDE     2
923 #define APIC_NMI                3
924 #define APIC_LOCAL_NMI          4
925 #define APIC_ADDRESS_OVERRIDE   5
926 #define APIC_IO_SAPIC           6
927 #define APIC_LOCAL_SAPIC        7
928 #define APIC_XRUPT_SOURCE       8
929 #define APIC_RESERVED           9           /* 9 and greater are reserved */
930
931 /*
932  * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
933  */
934 #define APIC_HEADER_DEF                     /* Common APIC sub-structure header */\
935         u8                              type; \
936         u8                              length;
937
938 /* Sub-structures for MADT */
939
940 struct madt_processor_apic
941 {
942         APIC_HEADER_DEF
943         u8                              processor_id;           /* ACPI processor id */
944         u8                              local_apic_id;          /* Processor's local APIC id */
945 #if 0
946         u32                             processor_enabled: 1;   /* Processor is usable if set */
947         u32                             reserved2       : 31;   /* Reserved, must be zero */
948 #else
949         u32 flags;
950 #endif
951 };
952
953 struct madt_io_apic
954 {
955         APIC_HEADER_DEF
956         u8                              io_apic_id;             /* I/O APIC ID */
957         u8                              reserved;               /* Reserved - must be zero */
958         u32                             address;                /* APIC physical address */
959         u32                             interrupt;              /* Global system interrupt where INTI
960                           * lines start */
961 };
962
963 #include "acpi-dsdt.hex"
964
965 static inline u16 cpu_to_le16(u16 x)
966 {
967     return x;
968 }
969
970 static inline u32 cpu_to_le32(u32 x)
971 {
972     return x;
973 }
974
975 static void acpi_build_table_header(struct acpi_table_header *h,
976                                     char *sig, int len, u8 rev)
977 {
978     memcpy(h->signature, sig, 4);
979     h->length = cpu_to_le32(len);
980     h->revision = rev;
981 #ifdef BX_QEMU
982     memcpy(h->oem_id, "QEMU  ", 6);
983     memcpy(h->oem_table_id, "QEMU", 4);
984 #else
985     memcpy(h->oem_id, "BOCHS ", 6);
986     memcpy(h->oem_table_id, "BXPC", 4);
987 #endif
988     memcpy(h->oem_table_id + 4, sig, 4);
989     h->oem_revision = cpu_to_le32(1);
990 #ifdef BX_QEMU
991     memcpy(h->asl_compiler_id, "QEMU", 4);
992 #else
993     memcpy(h->asl_compiler_id, "BXPC", 4);
994 #endif
995     h->asl_compiler_revision = cpu_to_le32(1);
996     h->checksum = -checksum((void *)h, len);
997 }
998
999 int acpi_build_processor_ssdt(u8 *ssdt)
1000 {
1001     u8 *ssdt_ptr = ssdt;
1002     int i, length;
1003     int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
1004
1005     ssdt_ptr[9] = 0; // checksum;
1006     ssdt_ptr += sizeof(struct acpi_table_header);
1007
1008     // caluculate the length of processor block and scope block excluding PkgLength
1009     length = 0x0d * acpi_cpus + 4;
1010
1011     // build processor scope header
1012     *(ssdt_ptr++) = 0x10; // ScopeOp
1013     if (length <= 0x3e) {
1014         *(ssdt_ptr++) = length + 1;
1015     } else {
1016         *(ssdt_ptr++) = 0x7F;
1017         *(ssdt_ptr++) = (length + 2) >> 6;
1018     }
1019     *(ssdt_ptr++) = '_'; // Name
1020     *(ssdt_ptr++) = 'P';
1021     *(ssdt_ptr++) = 'R';
1022     *(ssdt_ptr++) = '_';
1023
1024     // build object for each processor
1025     for(i=0;i<acpi_cpus;i++) {
1026         *(ssdt_ptr++) = 0x5B; // ProcessorOp
1027         *(ssdt_ptr++) = 0x83;
1028         *(ssdt_ptr++) = 0x0B; // Length
1029         *(ssdt_ptr++) = 'C';  // Name (CPUxx)
1030         *(ssdt_ptr++) = 'P';
1031         if ((i & 0xf0) != 0)
1032             *(ssdt_ptr++) = (i >> 4) < 0xa ? (i >> 4) + '0' : (i >> 4) + 'A' - 0xa;
1033         else
1034             *(ssdt_ptr++) = 'U';
1035         *(ssdt_ptr++) = (i & 0xf) < 0xa ? (i & 0xf) + '0' : (i & 0xf) + 'A' - 0xa;
1036         *(ssdt_ptr++) = i;
1037         *(ssdt_ptr++) = 0x10; // Processor block address
1038         *(ssdt_ptr++) = 0xb0;
1039         *(ssdt_ptr++) = 0;
1040         *(ssdt_ptr++) = 0;
1041         *(ssdt_ptr++) = 6;    // Processor block length
1042     }
1043
1044     acpi_build_table_header((struct acpi_table_header *)ssdt,
1045                             "SSDT", ssdt_ptr - ssdt, 1);
1046
1047     return ssdt_ptr - ssdt;
1048 }
1049
1050 /* base_addr must be a multiple of 4KB */
1051 void acpi_bios_init(void)
1052 {
1053     struct rsdp_descriptor *rsdp;
1054     struct rsdt_descriptor_rev1 *rsdt;
1055     struct fadt_descriptor_rev1 *fadt;
1056     struct facs_descriptor_rev1 *facs;
1057     struct multiple_apic_table *madt;
1058     u8 *dsdt, *ssdt;
1059     u32 base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
1060     u32 acpi_tables_size, madt_addr, madt_size;
1061     int i;
1062
1063     /* reserve memory space for tables */
1064 #ifdef BX_USE_EBDA_TABLES
1065     ebda_cur_addr = align(ebda_cur_addr, 16);
1066     rsdp = (void *)(ebda_cur_addr);
1067     ebda_cur_addr += sizeof(*rsdp);
1068 #else
1069     bios_table_cur_addr = align(bios_table_cur_addr, 16);
1070     rsdp = (void *)(bios_table_cur_addr);
1071     bios_table_cur_addr += sizeof(*rsdp);
1072 #endif
1073
1074     addr = base_addr = ram_size - ACPI_DATA_SIZE;
1075     rsdt_addr = addr;
1076     rsdt = (void *)(addr);
1077     addr += sizeof(*rsdt);
1078
1079     fadt_addr = addr;
1080     fadt = (void *)(addr);
1081     addr += sizeof(*fadt);
1082
1083     /* XXX: FACS should be in RAM */
1084     addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */
1085     facs_addr = addr;
1086     facs = (void *)(addr);
1087     addr += sizeof(*facs);
1088
1089     dsdt_addr = addr;
1090     dsdt = (void *)(addr);
1091     addr += sizeof(AmlCode);
1092
1093     ssdt_addr = addr;
1094     ssdt = (void *)(addr);
1095     addr += acpi_build_processor_ssdt(ssdt);
1096
1097     addr = (addr + 7) & ~7;
1098     madt_addr = addr;
1099     madt_size = sizeof(*madt) +
1100         sizeof(struct madt_processor_apic) * smp_cpus +
1101         sizeof(struct madt_io_apic);
1102     madt = (void *)(addr);
1103     addr += madt_size;
1104
1105     acpi_tables_size = addr - base_addr;
1106
1107     BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
1108             (unsigned long)rsdp,
1109             (unsigned long)rsdt, acpi_tables_size);
1110
1111     /* RSDP */
1112     memset(rsdp, 0, sizeof(*rsdp));
1113     memcpy(rsdp->signature, "RSD PTR ", 8);
1114 #ifdef BX_QEMU
1115     memcpy(rsdp->oem_id, "QEMU  ", 6);
1116 #else
1117     memcpy(rsdp->oem_id, "BOCHS ", 6);
1118 #endif
1119     rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
1120     rsdp->checksum = -checksum((void *)rsdp, 20);
1121
1122     /* RSDT */
1123     memset(rsdt, 0, sizeof(*rsdt));
1124     rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
1125     rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
1126     rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
1127     acpi_build_table_header((struct acpi_table_header *)rsdt,
1128                             "RSDT", sizeof(*rsdt), 1);
1129
1130     /* FADT */
1131     memset(fadt, 0, sizeof(*fadt));
1132     fadt->firmware_ctrl = cpu_to_le32(facs_addr);
1133     fadt->dsdt = cpu_to_le32(dsdt_addr);
1134     fadt->model = 1;
1135     fadt->reserved1 = 0;
1136     fadt->sci_int = cpu_to_le16(pm_sci_int);
1137     fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);
1138     fadt->acpi_enable = 0xf1;
1139     fadt->acpi_disable = 0xf0;
1140     fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);
1141     fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);
1142     fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);
1143     fadt->pm1_evt_len = 4;
1144     fadt->pm1_cnt_len = 2;
1145     fadt->pm_tmr_len = 4;
1146     fadt->plvl2_lat = cpu_to_le16(50);
1147     fadt->plvl3_lat = cpu_to_le16(50);
1148     fadt->plvl3_lat = cpu_to_le16(50);
1149     /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
1150     fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
1151     acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
1152                             sizeof(*fadt), 1);
1153
1154     /* FACS */
1155     memset(facs, 0, sizeof(*facs));
1156     memcpy(facs->signature, "FACS", 4);
1157     facs->length = cpu_to_le32(sizeof(*facs));
1158
1159     /* DSDT */
1160     memcpy(dsdt, AmlCode, sizeof(AmlCode));
1161
1162     /* MADT */
1163     {
1164         struct madt_processor_apic *apic;
1165         struct madt_io_apic *io_apic;
1166
1167         memset(madt, 0, madt_size);
1168         madt->local_apic_address = cpu_to_le32(0xfee00000);
1169         madt->flags = cpu_to_le32(1);
1170         apic = (void *)(madt + 1);
1171         for(i=0;i<smp_cpus;i++) {
1172             apic->type = APIC_PROCESSOR;
1173             apic->length = sizeof(*apic);
1174             apic->processor_id = i;
1175             apic->local_apic_id = i;
1176             apic->flags = cpu_to_le32(1);
1177             apic++;
1178         }
1179         io_apic = (void *)apic;
1180         io_apic->type = APIC_IO;
1181         io_apic->length = sizeof(*io_apic);
1182         io_apic->io_apic_id = smp_cpus;
1183         io_apic->address = cpu_to_le32(0xfec00000);
1184         io_apic->interrupt = cpu_to_le32(0);
1185
1186         acpi_build_table_header((struct acpi_table_header *)madt,
1187                                 "APIC", madt_size, 1);
1188     }
1189 }
1190
1191 /* SMBIOS entry point -- must be written to a 16-bit aligned address
1192    between 0xf0000 and 0xfffff.
1193  */
1194 struct smbios_entry_point {
1195         char anchor_string[4];
1196         u8 checksum;
1197         u8 length;
1198         u8 smbios_major_version;
1199         u8 smbios_minor_version;
1200         u16 max_structure_size;
1201         u8 entry_point_revision;
1202         u8 formatted_area[5];
1203         char intermediate_anchor_string[5];
1204         u8 intermediate_checksum;
1205         u16 structure_table_length;
1206         u32 structure_table_address;
1207         u16 number_of_structures;
1208         u8 smbios_bcd_revision;
1209 } __attribute__((__packed__));
1210
1211 /* This goes at the beginning of every SMBIOS structure. */
1212 struct smbios_structure_header {
1213         u8 type;
1214         u8 length;
1215         u16 handle;
1216 } __attribute__((__packed__));
1217
1218 /* SMBIOS type 0 - BIOS Information */
1219 struct smbios_type_0 {
1220         struct smbios_structure_header header;
1221         u8 vendor_str;
1222         u8 bios_version_str;
1223         u16 bios_starting_address_segment;
1224         u8 bios_release_date_str;
1225         u8 bios_rom_size;
1226         u8 bios_characteristics[8];
1227         u8 bios_characteristics_extension_bytes[2];
1228         u8 system_bios_major_release;
1229         u8 system_bios_minor_release;
1230         u8 embedded_controller_major_release;
1231         u8 embedded_controller_minor_release;
1232 } __attribute__((__packed__));
1233
1234 /* SMBIOS type 1 - System Information */
1235 struct smbios_type_1 {
1236         struct smbios_structure_header header;
1237         u8 manufacturer_str;
1238         u8 product_name_str;
1239         u8 version_str;
1240         u8 serial_number_str;
1241         u8 uuid[16];
1242         u8 wake_up_type;
1243         u8 sku_number_str;
1244         u8 family_str;
1245 } __attribute__((__packed__));
1246
1247 /* SMBIOS type 3 - System Enclosure (v2.3) */
1248 struct smbios_type_3 {
1249         struct smbios_structure_header header;
1250         u8 manufacturer_str;
1251         u8 type;
1252         u8 version_str;
1253         u8 serial_number_str;
1254         u8 asset_tag_number_str;
1255         u8 boot_up_state;
1256         u8 power_supply_state;
1257         u8 thermal_state;
1258         u8 security_status;
1259     u32 oem_defined;
1260     u8 height;
1261     u8 number_of_power_cords;
1262     u8 contained_element_count;
1263     // contained elements follow
1264 } __attribute__((__packed__));
1265
1266 /* SMBIOS type 4 - Processor Information (v2.0) */
1267 struct smbios_type_4 {
1268         struct smbios_structure_header header;
1269         u8 socket_designation_str;
1270         u8 processor_type;
1271         u8 processor_family;
1272         u8 processor_manufacturer_str;
1273         u32 processor_id[2];
1274         u8 processor_version_str;
1275         u8 voltage;
1276         u16 external_clock;
1277         u16 max_speed;
1278         u16 current_speed;
1279         u8 status;
1280         u8 processor_upgrade;
1281 } __attribute__((__packed__));
1282
1283 /* SMBIOS type 16 - Physical Memory Array
1284  *   Associated with one type 17 (Memory Device).
1285  */
1286 struct smbios_type_16 {
1287         struct smbios_structure_header header;
1288         u8 location;
1289         u8 use;
1290         u8 error_correction;
1291         u32 maximum_capacity;
1292         u16 memory_error_information_handle;
1293         u16 number_of_memory_devices;
1294 } __attribute__((__packed__));
1295
1296 /* SMBIOS type 17 - Memory Device
1297  *   Associated with one type 19
1298  */
1299 struct smbios_type_17 {
1300         struct smbios_structure_header header;
1301         u16 physical_memory_array_handle;
1302         u16 memory_error_information_handle;
1303         u16 total_width;
1304         u16 data_width;
1305         u16 size;
1306         u8 form_factor;
1307         u8 device_set;
1308         u8 device_locator_str;
1309         u8 bank_locator_str;
1310         u8 memory_type;
1311         u16 type_detail;
1312 } __attribute__((__packed__));
1313
1314 /* SMBIOS type 19 - Memory Array Mapped Address */
1315 struct smbios_type_19 {
1316         struct smbios_structure_header header;
1317         u32 starting_address;
1318         u32 ending_address;
1319         u16 memory_array_handle;
1320         u8 partition_width;
1321 } __attribute__((__packed__));
1322
1323 /* SMBIOS type 20 - Memory Device Mapped Address */
1324 struct smbios_type_20 {
1325         struct smbios_structure_header header;
1326         u32 starting_address;
1327         u32 ending_address;
1328         u16 memory_device_handle;
1329         u16 memory_array_mapped_address_handle;
1330         u8 partition_row_position;
1331         u8 interleave_position;
1332         u8 interleaved_data_depth;
1333 } __attribute__((__packed__));
1334
1335 /* SMBIOS type 32 - System Boot Information */
1336 struct smbios_type_32 {
1337         struct smbios_structure_header header;
1338         u8 reserved[6];
1339         u8 boot_status;
1340 } __attribute__((__packed__));
1341
1342 /* SMBIOS type 127 -- End-of-table */
1343 struct smbios_type_127 {
1344         struct smbios_structure_header header;
1345 } __attribute__((__packed__));
1346
1347 static void
1348 smbios_entry_point_init(void *start,
1349                         u16 max_structure_size,
1350                         u16 structure_table_length,
1351                         u32 structure_table_address,
1352                         u16 number_of_structures)
1353 {
1354     struct smbios_entry_point *ep = (struct smbios_entry_point *)start;
1355
1356     memcpy(ep->anchor_string, "_SM_", 4);
1357     ep->length = 0x1f;
1358     ep->smbios_major_version = 2;
1359     ep->smbios_minor_version = 4;
1360     ep->max_structure_size = max_structure_size;
1361     ep->entry_point_revision = 0;
1362     memset(ep->formatted_area, 0, 5);
1363     memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
1364
1365     ep->structure_table_length = structure_table_length;
1366     ep->structure_table_address = structure_table_address;
1367     ep->number_of_structures = number_of_structures;
1368     ep->smbios_bcd_revision = 0x24;
1369
1370     ep->checksum = 0;
1371     ep->intermediate_checksum = 0;
1372
1373     ep->checksum = -checksum(start, 0x10);
1374
1375     ep->intermediate_checksum = -checksum(start + 0x10, ep->length - 0x10);
1376 }
1377
1378 /* Type 0 -- BIOS Information */
1379 #define RELEASE_DATE_STR "01/01/2007"
1380 static void *
1381 smbios_type_0_init(void *start)
1382 {
1383     struct smbios_type_0 *p = (struct smbios_type_0 *)start;
1384
1385     p->header.type = 0;
1386     p->header.length = sizeof(struct smbios_type_0);
1387     p->header.handle = 0;
1388
1389     p->vendor_str = 1;
1390     p->bios_version_str = 1;
1391     p->bios_starting_address_segment = 0xe800;
1392     p->bios_release_date_str = 2;
1393     p->bios_rom_size = 0; /* FIXME */
1394
1395     memset(p->bios_characteristics, 0, 7);
1396     p->bios_characteristics[7] = 0x08; /* BIOS characteristics not supported */
1397     p->bios_characteristics_extension_bytes[0] = 0;
1398     p->bios_characteristics_extension_bytes[1] = 0;
1399
1400     p->system_bios_major_release = 1;
1401     p->system_bios_minor_release = 0;
1402     p->embedded_controller_major_release = 0xff;
1403     p->embedded_controller_minor_release = 0xff;
1404
1405     start += sizeof(struct smbios_type_0);
1406     memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
1407     start += sizeof(BX_APPNAME);
1408     memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
1409     start += sizeof(RELEASE_DATE_STR);
1410     *((u8 *)start) = 0;
1411
1412     return start+1;
1413 }
1414
1415 /* Type 1 -- System Information */
1416 static void *
1417 smbios_type_1_init(void *start)
1418 {
1419     struct smbios_type_1 *p = (struct smbios_type_1 *)start;
1420     p->header.type = 1;
1421     p->header.length = sizeof(struct smbios_type_1);
1422     p->header.handle = 0x100;
1423
1424     p->manufacturer_str = 0;
1425     p->product_name_str = 0;
1426     p->version_str = 0;
1427     p->serial_number_str = 0;
1428
1429     memcpy(p->uuid, bios_uuid, 16);
1430
1431     p->wake_up_type = 0x06; /* power switch */
1432     p->sku_number_str = 0;
1433     p->family_str = 0;
1434
1435     start += sizeof(struct smbios_type_1);
1436     *((u16 *)start) = 0;
1437
1438     return start+2;
1439 }
1440
1441 /* Type 3 -- System Enclosure */
1442 static void *
1443 smbios_type_3_init(void *start)
1444 {
1445     struct smbios_type_3 *p = (struct smbios_type_3 *)start;
1446
1447     p->header.type = 3;
1448     p->header.length = sizeof(struct smbios_type_3);
1449     p->header.handle = 0x300;
1450
1451     p->manufacturer_str = 0;
1452     p->type = 0x01; /* other */
1453     p->version_str = 0;
1454     p->serial_number_str = 0;
1455     p->asset_tag_number_str = 0;
1456     p->boot_up_state = 0x03; /* safe */
1457     p->power_supply_state = 0x03; /* safe */
1458     p->thermal_state = 0x03; /* safe */
1459     p->security_status = 0x02; /* unknown */
1460     p->oem_defined = 0;
1461     p->height = 0;
1462     p->number_of_power_cords = 0;
1463     p->contained_element_count = 0;
1464
1465     start += sizeof(struct smbios_type_3);
1466     *((u16 *)start) = 0;
1467
1468     return start+2;
1469 }
1470
1471 /* Type 4 -- Processor Information */
1472 static void *
1473 smbios_type_4_init(void *start, unsigned int cpu_number)
1474 {
1475     struct smbios_type_4 *p = (struct smbios_type_4 *)start;
1476
1477     p->header.type = 4;
1478     p->header.length = sizeof(struct smbios_type_4);
1479     p->header.handle = 0x400 + cpu_number;
1480
1481     p->socket_designation_str = 1;
1482     p->processor_type = 0x03; /* CPU */
1483     p->processor_family = 0x01; /* other */
1484     p->processor_manufacturer_str = 0;
1485
1486     p->processor_id[0] = cpuid_signature;
1487     p->processor_id[1] = cpuid_features;
1488
1489     p->processor_version_str = 0;
1490     p->voltage = 0;
1491     p->external_clock = 0;
1492
1493     p->max_speed = 0; /* unknown */
1494     p->current_speed = 0; /* unknown */
1495
1496     p->status = 0x41; /* socket populated, CPU enabled */
1497     p->processor_upgrade = 0x01; /* other */
1498
1499     start += sizeof(struct smbios_type_4);
1500
1501     memcpy((char *)start, "CPU  " "\0" "" "\0" "", 7);
1502         ((char *)start)[4] = cpu_number + '0';
1503
1504     return start+7;
1505 }
1506
1507 /* Type 16 -- Physical Memory Array */
1508 static void *
1509 smbios_type_16_init(void *start, u32 memsize)
1510 {
1511     struct smbios_type_16 *p = (struct smbios_type_16*)start;
1512
1513     p->header.type = 16;
1514     p->header.length = sizeof(struct smbios_type_16);
1515     p->header.handle = 0x1000;
1516
1517     p->location = 0x01; /* other */
1518     p->use = 0x03; /* system memory */
1519     p->error_correction = 0x01; /* other */
1520     p->maximum_capacity = memsize * 1024;
1521     p->memory_error_information_handle = 0xfffe; /* none provided */
1522     p->number_of_memory_devices = 1;
1523
1524     start += sizeof(struct smbios_type_16);
1525     *((u16 *)start) = 0;
1526
1527     return start + 2;
1528 }
1529
1530 /* Type 17 -- Memory Device */
1531 static void *
1532 smbios_type_17_init(void *start, u32 memory_size_mb)
1533 {
1534     struct smbios_type_17 *p = (struct smbios_type_17 *)start;
1535
1536     p->header.type = 17;
1537     p->header.length = sizeof(struct smbios_type_17);
1538     p->header.handle = 0x1100;
1539
1540     p->physical_memory_array_handle = 0x1000;
1541     p->total_width = 64;
1542     p->data_width = 64;
1543     /* truncate memory_size_mb to 16 bits and clear most significant
1544        bit [indicates size in MB] */
1545     p->size = (u16) memory_size_mb & 0x7fff;
1546     p->form_factor = 0x09; /* DIMM */
1547     p->device_set = 0;
1548     p->device_locator_str = 1;
1549     p->bank_locator_str = 0;
1550     p->memory_type = 0x07; /* RAM */
1551     p->type_detail = 0;
1552
1553     start += sizeof(struct smbios_type_17);
1554     memcpy((char *)start, "DIMM 1", 7);
1555     start += 7;
1556     *((u8 *)start) = 0;
1557
1558     return start+1;
1559 }
1560
1561 /* Type 19 -- Memory Array Mapped Address */
1562 static void *
1563 smbios_type_19_init(void *start, u32 memory_size_mb)
1564 {
1565     struct smbios_type_19 *p = (struct smbios_type_19 *)start;
1566
1567     p->header.type = 19;
1568     p->header.length = sizeof(struct smbios_type_19);
1569     p->header.handle = 0x1300;
1570
1571     p->starting_address = 0;
1572     p->ending_address = (memory_size_mb-1) * 1024;
1573     p->memory_array_handle = 0x1000;
1574     p->partition_width = 1;
1575
1576     start += sizeof(struct smbios_type_19);
1577     *((u16 *)start) = 0;
1578
1579     return start + 2;
1580 }
1581
1582 /* Type 20 -- Memory Device Mapped Address */
1583 static void *
1584 smbios_type_20_init(void *start, u32 memory_size_mb)
1585 {
1586     struct smbios_type_20 *p = (struct smbios_type_20 *)start;
1587
1588     p->header.type = 20;
1589     p->header.length = sizeof(struct smbios_type_20);
1590     p->header.handle = 0x1400;
1591
1592     p->starting_address = 0;
1593     p->ending_address = (memory_size_mb-1)*1024;
1594     p->memory_device_handle = 0x1100;
1595     p->memory_array_mapped_address_handle = 0x1300;
1596     p->partition_row_position = 1;
1597     p->interleave_position = 0;
1598     p->interleaved_data_depth = 0;
1599
1600     start += sizeof(struct smbios_type_20);
1601
1602     *((u16 *)start) = 0;
1603     return start+2;
1604 }
1605
1606 /* Type 32 -- System Boot Information */
1607 static void *
1608 smbios_type_32_init(void *start)
1609 {
1610     struct smbios_type_32 *p = (struct smbios_type_32 *)start;
1611
1612     p->header.type = 32;
1613     p->header.length = sizeof(struct smbios_type_32);
1614     p->header.handle = 0x2000;
1615     memset(p->reserved, 0, 6);
1616     p->boot_status = 0; /* no errors detected */
1617
1618     start += sizeof(struct smbios_type_32);
1619     *((u16 *)start) = 0;
1620
1621     return start+2;
1622 }
1623
1624 /* Type 127 -- End of Table */
1625 static void *
1626 smbios_type_127_init(void *start)
1627 {
1628     struct smbios_type_127 *p = (struct smbios_type_127 *)start;
1629
1630     p->header.type = 127;
1631     p->header.length = sizeof(struct smbios_type_127);
1632     p->header.handle = 0x7f00;
1633
1634     start += sizeof(struct smbios_type_127);
1635     *((u16 *)start) = 0;
1636
1637     return start + 2;
1638 }
1639
1640 void smbios_init(void)
1641 {
1642     unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
1643     char *start, *p, *q;
1644     int memsize = ram_size / (1024 * 1024);
1645
1646 #ifdef BX_USE_EBDA_TABLES
1647     ebda_cur_addr = align(ebda_cur_addr, 16);
1648     start = (void *)(ebda_cur_addr);
1649 #else
1650     bios_table_cur_addr = align(bios_table_cur_addr, 16);
1651     start = (void *)(bios_table_cur_addr);
1652 #endif
1653
1654         p = (char *)start + sizeof(struct smbios_entry_point);
1655
1656 #define add_struct(fn) { \
1657     q = (fn); \
1658     nr_structs++; \
1659     if ((q - p) > max_struct_size) \
1660         max_struct_size = q - p; \
1661     p = q; \
1662 }
1663
1664     add_struct(smbios_type_0_init(p));
1665     add_struct(smbios_type_1_init(p));
1666     add_struct(smbios_type_3_init(p));
1667     for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
1668         add_struct(smbios_type_4_init(p, cpu_num));
1669     add_struct(smbios_type_16_init(p, memsize));
1670     add_struct(smbios_type_17_init(p, memsize));
1671     add_struct(smbios_type_19_init(p, memsize));
1672     add_struct(smbios_type_20_init(p, memsize));
1673     add_struct(smbios_type_32_init(p));
1674     add_struct(smbios_type_127_init(p));
1675
1676 #undef add_struct
1677
1678     smbios_entry_point_init(
1679         start, max_struct_size,
1680         (p - (char *)start) - sizeof(struct smbios_entry_point),
1681         (u32)(start + sizeof(struct smbios_entry_point)),
1682         nr_structs);
1683
1684 #ifdef BX_USE_EBDA_TABLES
1685     ebda_cur_addr += (p - (char *)start);
1686 #else
1687     bios_table_cur_addr += (p - (char *)start);
1688 #endif
1689
1690     BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start);
1691 }
1692
1693 void rombios32_init(void)
1694 {
1695     BX_INFO("Starting rombios32\n");
1696
1697     ram_probe();
1698
1699     cpu_probe();
1700
1701     smp_probe();
1702
1703     uuid_probe();
1704
1705     pci_bios_init();
1706
1707     if (bios_table_cur_addr != 0) {
1708
1709         mptable_init();
1710
1711         smbios_init();
1712
1713         if (acpi_enabled)
1714             acpi_bios_init();
1715
1716         bios_lock_shadow_ram();
1717
1718         BX_INFO("bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
1719         if (bios_table_cur_addr > bios_table_end_addr)
1720             BX_PANIC("bios_table_end_addr overflow!\n");
1721     }
1722 }