Move support for copying out BIOS tables into its own file.
[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
13 void
14 copy_pir(void *pos)
15 {
16     struct pir_header *p = pos;
17     if (p->signature != PIR_SIGNATURE)
18         return;
19     if (PirOffset)
20         return;
21     if (p->size < sizeof(*p))
22         return;
23     if (checksum(pos, p->size) != 0)
24         return;
25     void *newpos = malloc_fseg(p->size);
26     if (!newpos) {
27         warn_noalloc();
28         return;
29     }
30     dprintf(1, "Copying PIR from %p to %p\n", pos, newpos);
31     memcpy(newpos, pos, p->size);
32     PirOffset = (u32)newpos - BUILD_BIOS_ADDR;
33 }
34
35 void
36 copy_mptable(void *pos)
37 {
38     struct mptable_floating_s *p = pos;
39     if (p->signature != MPTABLE_SIGNATURE)
40         return;
41     if (!p->physaddr)
42         return;
43     if (checksum(pos, sizeof(*p)) != 0)
44         return;
45     u32 length = p->length * 16;
46     u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
47     struct mptable_floating_s *newpos = malloc_fseg(length + mpclength);
48     if (!newpos) {
49         warn_noalloc();
50         return;
51     }
52     dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos);
53     memcpy(newpos, pos, length);
54     newpos->physaddr = (u32)newpos + length;
55     newpos->checksum -= checksum(newpos, sizeof(*newpos));
56     memcpy((void*)newpos + length, (void*)p->physaddr, mpclength);
57 }
58
59 void
60 copy_acpi_rsdp(void *pos)
61 {
62     if (RsdpAddr)
63         return;
64     struct rsdp_descriptor *p = pos;
65     if (p->signature != RSDP_SIGNATURE)
66         return;
67     u32 length = 20;
68     if (checksum(pos, length) != 0)
69         return;
70     if (p->revision > 1) {
71         length = p->length;
72         if (checksum(pos, length) != 0)
73             return;
74     }
75     void *newpos = malloc_fseg(length);
76     if (!newpos) {
77         warn_noalloc();
78         return;
79     }
80     dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos);
81     memcpy(newpos, pos, length);
82     RsdpAddr = newpos;
83 }