grml...
[seabios.git] / src / biostables.c
1 // Coreboot interface support.
2 //
3 // Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
6
7 #include "config.h" // CONFIG_*
8 #include "util.h" // dprintf
9 #include "pci.h" // struct pir_header
10 #include "acpi.h" // struct rsdp_descriptor
11 #include "mptable.h" // MPTABLE_SIGNATURE
12 #include "smbios.h" // struct smbios_entry_point
13
14 void
15 copy_pir(void *pos)
16 {
17     struct pir_header *p = pos;
18     if (p->signature != PIR_SIGNATURE)
19         return;
20     if (PirOffset)
21         return;
22     if (p->size < sizeof(*p))
23         return;
24     if (checksum(pos, p->size) != 0)
25         return;
26     void *newpos = malloc_fseg(p->size);
27     if (!newpos) {
28         warn_noalloc();
29         return;
30     }
31     dprintf(1, "Copying PIR from %p to %p\n", pos, newpos);
32     memcpy(newpos, pos, p->size);
33     PirOffset = (u32)newpos - BUILD_BIOS_ADDR;
34 }
35
36 void
37 copy_mptable(void *pos)
38 {
39     struct mptable_floating_s *p = pos;
40     if (p->signature != MPTABLE_SIGNATURE)
41         return;
42     if (!p->physaddr)
43         return;
44     if (checksum(pos, sizeof(*p)) != 0)
45         return;
46     u32 length = p->length * 16;
47     u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
48     struct mptable_floating_s *newpos = malloc_fseg(length + mpclength);
49     if (!newpos) {
50         warn_noalloc();
51         return;
52     }
53     dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos);
54     memcpy(newpos, pos, length);
55     newpos->physaddr = (u32)newpos + length;
56     newpos->checksum -= checksum(newpos, sizeof(*newpos));
57     memcpy((void*)newpos + length, (void*)p->physaddr, mpclength);
58 }
59
60 void
61 copy_acpi_rsdp(void *pos)
62 {
63     if (RsdpAddr)
64         return;
65     struct rsdp_descriptor *p = pos;
66     if (p->signature != RSDP_SIGNATURE)
67         return;
68     u32 length = 20;
69     if (checksum(pos, length) != 0)
70         return;
71     if (p->revision > 1) {
72         length = p->length;
73         if (checksum(pos, length) != 0)
74             return;
75     }
76     void *newpos = malloc_fseg(length);
77     if (!newpos) {
78         warn_noalloc();
79         return;
80     }
81     dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos);
82     memcpy(newpos, pos, length);
83     RsdpAddr = newpos;
84 }
85
86 void
87 copy_smbios(void *pos)
88 {
89     if (SMBiosAddr)
90         return;
91     struct smbios_entry_point *p = pos;
92     if (memcmp(p->anchor_string, "_SM_", 4))
93         return;
94     if (checksum(pos, 0x10) != 0)
95         return;
96     if (memcmp(p->intermediate_anchor_string, "_DMI_", 5))
97         return;
98     if (checksum(pos+0x10, p->length-0x10) != 0)
99         return;
100     struct smbios_entry_point *newpos = malloc_fseg(p->length);
101     if (!newpos) {
102         warn_noalloc();
103         return;
104     }
105     dprintf(1, "Copying SMBIOS entry point from %p to %p\n", pos, newpos);
106     memcpy(newpos, pos, p->length);
107     SMBiosAddr = newpos;
108 }