|
|
1.1 root 1: // Coreboot interface support.
2: //
3: // Copyright (C) 2008,2009 Kevin O'Connor <[email protected]>
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: {
1.1.1.2 ! root 89: if (SMBiosAddr)
! 90: return;
1.1 root 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);
1.1.1.2 ! root 107: SMBiosAddr = newpos;
1.1 root 108: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.