-
-
-/****************************************************************
- * BIOS table copying
- ****************************************************************/
-
-static void
-copy_pir(void *pos)
-{
- struct pir_header *p = pos;
- if (p->signature != PIR_SIGNATURE)
- return;
- if (PirOffset)
- return;
- if (p->size < sizeof(*p))
- return;
- if (checksum(pos, p->size) != 0)
- return;
- bios_table_cur_addr = ALIGN(bios_table_cur_addr, 16);
- if (bios_table_cur_addr + p->size > bios_table_end_addr) {
- dprintf(1, "No room to copy PIR table!\n");
- return;
- }
- dprintf(1, "Copying PIR from %p to %x\n", pos, bios_table_cur_addr);
- memcpy((void*)bios_table_cur_addr, pos, p->size);
- PirOffset = bios_table_cur_addr - BUILD_BIOS_ADDR;
- bios_table_cur_addr += p->size;
-}
-
-static void
-copy_mptable(void *pos)
-{
- struct mptable_floating_s *p = pos;
- if (p->signature != MPTABLE_SIGNATURE)
- return;
- if (!p->physaddr)
- return;
- if (checksum(pos, sizeof(*p)) != 0)
- return;
- u32 length = p->length * 16;
- bios_table_cur_addr = ALIGN(bios_table_cur_addr, 16);
- u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
- if (bios_table_cur_addr + length + mpclength > bios_table_end_addr) {
- dprintf(1, "No room to copy MPTABLE!\n");
- return;
- }
- dprintf(1, "Copying MPTABLE from %p/%x to %x\n"
- , pos, p->physaddr, bios_table_cur_addr);
- memcpy((void*)bios_table_cur_addr, pos, length);
- struct mptable_floating_s *newp = (void*)bios_table_cur_addr;
- newp->physaddr = bios_table_cur_addr + length;
- newp->checksum = 0;
- newp->checksum = -checksum(newp, sizeof(*newp));
- memcpy((void*)bios_table_cur_addr + length, (void*)p->physaddr, mpclength);
- bios_table_cur_addr += length + mpclength;
-}
-
-static void
-copy_acpi_rsdp(void *pos)
-{
- if (RsdpAddr)
- return;
- struct rsdp_descriptor *p = pos;
- if (p->signature != RSDP_SIGNATURE)
- return;
- u32 length = 20;
- if (checksum(pos, length) != 0)
- return;
- if (p->revision > 1) {
- length = p->length;
- if (checksum(pos, length) != 0)
- return;
- }
- bios_table_cur_addr = ALIGN(bios_table_cur_addr, 16);
- if (bios_table_cur_addr + length > bios_table_end_addr) {
- dprintf(1, "No room to copy ACPI RSDP table!\n");
- return;
- }
- dprintf(1, "Copying ACPI RSDP from %p to %x\n", pos, bios_table_cur_addr);
- RsdpAddr = (void*)bios_table_cur_addr;
- memcpy(RsdpAddr, pos, length);
- bios_table_cur_addr += length;
-}
-
-// Attempt to find (and relocate) any standard bios tables found in a
-// given address range.
-static void
-scan_tables(u32 start, u32 size)
-{
- void *p = (void*)ALIGN(start, 16);
- void *end = (void*)start + size;
- for (; p<end; p += 16) {
- copy_pir(p);
- copy_mptable(p);
- copy_acpi_rsdp(p);
- }
-}