hw: provide ACPI infos via platform_info ROM
in uefi/mbi2 boot case Issue #2242
This commit is contained in:
parent
972031cbbc
commit
6792456e4e
|
@ -181,8 +181,9 @@ Platform::Platform()
|
||||||
Hw::PAGE_FLAGS_KERN_TEXT));
|
Hw::PAGE_FLAGS_KERN_TEXT));
|
||||||
Boot_info & bootinfo =
|
Boot_info & bootinfo =
|
||||||
*construct_at<Boot_info>(bi_base, (addr_t)&core_pd->table,
|
*construct_at<Boot_info>(bi_base, (addr_t)&core_pd->table,
|
||||||
(addr_t)&core_pd->array,
|
(addr_t)&core_pd->array,
|
||||||
core_pd->mappings, board.core_mmio);
|
core_pd->mappings, board.core_mmio,
|
||||||
|
board.acpi_rsdp);
|
||||||
|
|
||||||
/* add all left RAM to bootinfo */
|
/* add all left RAM to bootinfo */
|
||||||
ram_alloc.for_each_free_region([&] (Memory_region const & r) {
|
ram_alloc.for_each_free_region([&] (Memory_region const & r) {
|
||||||
|
|
|
@ -45,6 +45,7 @@ class Bootstrap::Platform
|
||||||
Memory_region_array early_ram_regions;
|
Memory_region_array early_ram_regions;
|
||||||
Memory_region_array late_ram_regions;
|
Memory_region_array late_ram_regions;
|
||||||
Mmio_space const core_mmio;
|
Mmio_space const core_mmio;
|
||||||
|
Hw::Acpi_rsdp acpi_rsdp;
|
||||||
|
|
||||||
Board();
|
Board();
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,10 @@ class Genode::Multiboot2_info : Mmio
|
||||||
struct Tag : Genode::Mmio {
|
struct Tag : Genode::Mmio {
|
||||||
enum { LOG2_SIZE = 3 };
|
enum { LOG2_SIZE = 3 };
|
||||||
|
|
||||||
struct Type : Register <0x00, 32> { enum { END = 0, MEMORY = 6 }; };
|
struct Type : Register <0x00, 32>
|
||||||
|
{
|
||||||
|
enum { END = 0, MEMORY = 6, ACPI_RSDP = 15 };
|
||||||
|
};
|
||||||
struct Size : Register <0x04, 32> { };
|
struct Size : Register <0x04, 32> { };
|
||||||
|
|
||||||
Tag(addr_t addr) : Mmio(addr) { }
|
Tag(addr_t addr) : Mmio(addr) { }
|
||||||
|
@ -50,8 +53,8 @@ class Genode::Multiboot2_info : Mmio
|
||||||
|
|
||||||
Multiboot2_info(addr_t mbi) : Mmio(mbi) { }
|
Multiboot2_info(addr_t mbi) : Mmio(mbi) { }
|
||||||
|
|
||||||
template <typename FUNC>
|
template <typename FUNC_MEM, typename FUNC_ACPI>
|
||||||
void for_each_mem(FUNC functor)
|
void for_each_tag(FUNC_MEM mem_fn, FUNC_ACPI acpi_fn)
|
||||||
{
|
{
|
||||||
addr_t const size = read<Multiboot2_info::Size>();
|
addr_t const size = read<Multiboot2_info::Size>();
|
||||||
|
|
||||||
|
@ -69,10 +72,20 @@ class Genode::Multiboot2_info : Mmio
|
||||||
|
|
||||||
for (; mem_start < mem_end; mem_start += Memory::SIZE) {
|
for (; mem_start < mem_end; mem_start += Memory::SIZE) {
|
||||||
Memory mem(mem_start);
|
Memory mem(mem_start);
|
||||||
functor(mem);
|
mem_fn(mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tag.read<Tag::Type>() == Tag::Type::ACPI_RSDP) {
|
||||||
|
size_t const sizeof_tag = 1UL << Tag::LOG2_SIZE;
|
||||||
|
addr_t const rsdp_addr = tag_addr + sizeof_tag;
|
||||||
|
|
||||||
|
Hw::Acpi_rsdp * rsdp = reinterpret_cast<Hw::Acpi_rsdp *>(rsdp_addr);
|
||||||
|
if (rsdp->valid() &&
|
||||||
|
sizeof(*rsdp) >= tag.read<Tag::Size>() - sizeof_tag)
|
||||||
|
acpi_fn(*rsdp);
|
||||||
|
}
|
||||||
|
|
||||||
tag_addr += align_addr(tag.read<Tag::Size>(), Tag::LOG2_SIZE);
|
tag_addr += align_addr(tag.read<Tag::Size>(), Tag::LOG2_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ Bootstrap::Platform::Board::Board()
|
||||||
if (__initial_ax == Multiboot2_info::MAGIC) {
|
if (__initial_ax == Multiboot2_info::MAGIC) {
|
||||||
Multiboot2_info mbi2(__initial_bx);
|
Multiboot2_info mbi2(__initial_bx);
|
||||||
|
|
||||||
mbi2.for_each_mem([&] (Multiboot2_info::Memory const & m) {
|
mbi2.for_each_tag([&] (Multiboot2_info::Memory const & m) {
|
||||||
uint32_t const type = m.read<Multiboot2_info::Memory::Type>();
|
uint32_t const type = m.read<Multiboot2_info::Memory::Type>();
|
||||||
|
|
||||||
if (type != Multiboot2_info::Memory::Type::MEMORY)
|
if (type != Multiboot2_info::Memory::Type::MEMORY)
|
||||||
|
@ -75,7 +75,8 @@ Bootstrap::Platform::Board::Board()
|
||||||
uint64_t const size = m.read<Multiboot2_info::Memory::Size>();
|
uint64_t const size = m.read<Multiboot2_info::Memory::Size>();
|
||||||
|
|
||||||
lambda(base, size);
|
lambda(base, size);
|
||||||
});
|
},
|
||||||
|
[&] (Hw::Acpi_rsdp const &rsdp) { acpi_rsdp = rsdp; });
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,73 @@
|
||||||
#include <bios_data_area.h>
|
#include <bios_data_area.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <kernel/kernel.h>
|
#include <kernel/kernel.h>
|
||||||
|
#include <map_local.h>
|
||||||
|
|
||||||
|
#include <util/xml_generator.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
void Platform::_init_additional() { };
|
void Platform::_init_additional()
|
||||||
|
{
|
||||||
|
/* export x86 platform specific infos */
|
||||||
|
|
||||||
|
unsigned const pages = 1;
|
||||||
|
size_t const rom_size = pages << get_page_size_log2();
|
||||||
|
void *phys_ptr = nullptr;
|
||||||
|
void *virt_ptr = nullptr;
|
||||||
|
const char *rom_name = "platform_info";
|
||||||
|
|
||||||
|
if (!ram_alloc()->alloc(get_page_size(), &phys_ptr)) {
|
||||||
|
error("could not setup platform_info ROM - ram allocation error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!region_alloc()->alloc(rom_size, &virt_ptr)) {
|
||||||
|
error("could not setup platform_info ROM - region allocation error");
|
||||||
|
ram_alloc()->free(phys_ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_t const phys_addr = reinterpret_cast<addr_t>(phys_ptr);
|
||||||
|
addr_t const virt_addr = reinterpret_cast<addr_t>(virt_ptr);
|
||||||
|
|
||||||
|
if (!map_local(phys_addr, virt_addr, pages, Hw::PAGE_FLAGS_KERN_DATA)) {
|
||||||
|
error("could not setup platform_info ROM - map error");
|
||||||
|
region_alloc()->free(virt_ptr);
|
||||||
|
ram_alloc()->free(phys_ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::Xml_generator xml(reinterpret_cast<char *>(virt_addr),
|
||||||
|
rom_size, rom_name, [&] ()
|
||||||
|
{
|
||||||
|
xml.node("acpi", [&] () {
|
||||||
|
uint32_t const revision = _boot_info().acpi_rsdp.revision;
|
||||||
|
uint32_t const rsdt = _boot_info().acpi_rsdp.rsdt;
|
||||||
|
uint64_t const xsdt = _boot_info().acpi_rsdp.xsdt;
|
||||||
|
|
||||||
|
if (revision && (rsdt || xsdt)) {
|
||||||
|
xml.attribute("revision", revision);
|
||||||
|
if (rsdt)
|
||||||
|
xml.attribute("rsdt", String<32>(Hex(rsdt)));
|
||||||
|
|
||||||
|
if (xsdt)
|
||||||
|
xml.attribute("xsdt", String<32>(Hex(xsdt)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!unmap_local(virt_addr, pages)) {
|
||||||
|
error("could not setup platform_info ROM - unmap error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
region_alloc()->free(virt_ptr);
|
||||||
|
|
||||||
|
_rom_fs.insert(
|
||||||
|
new (core_mem_alloc()) Rom_module(phys_addr, rom_size, rom_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Platform::setup_irq_mode(unsigned irq_number, unsigned trigger,
|
void Platform::setup_irq_mode(unsigned irq_number, unsigned trigger,
|
||||||
|
|
40
repos/base-hw/src/lib/hw/acpi_rsdp.h
Normal file
40
repos/base-hw/src/lib/hw/acpi_rsdp.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* \brief ACPI RSDP structure
|
||||||
|
* \author Alexander Boettcher
|
||||||
|
* \date 2017-08-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SRC__LIB__HW__ACPI_RSDP_H
|
||||||
|
#define _SRC__LIB__HW__ACPI_RSDP_H
|
||||||
|
|
||||||
|
#include <base/fixed_stdint.h>
|
||||||
|
|
||||||
|
namespace Hw {
|
||||||
|
struct Acpi_rsdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Hw::Acpi_rsdp
|
||||||
|
{
|
||||||
|
Genode::uint64_t signature;
|
||||||
|
Genode::uint8_t checksum;
|
||||||
|
char oem[6];
|
||||||
|
Genode::uint8_t revision;
|
||||||
|
Genode::uint32_t rsdt;
|
||||||
|
Genode::uint32_t length;
|
||||||
|
Genode::uint64_t xsdt;
|
||||||
|
Genode::uint32_t reserved;
|
||||||
|
|
||||||
|
bool valid() {
|
||||||
|
const char sign[] = "RSD PTR ";
|
||||||
|
return signature == *(Genode::uint64_t *)sign;
|
||||||
|
}
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#endif /* _SRC__LIB__HW__ACPI_RSDP_H */
|
|
@ -15,6 +15,7 @@
|
||||||
#define _SRC__LIB__HW__BOOT_INFO_H_
|
#define _SRC__LIB__HW__BOOT_INFO_H_
|
||||||
|
|
||||||
#include <hw/mmio_space.h>
|
#include <hw/mmio_space.h>
|
||||||
|
#include <hw/acpi_rsdp.h>
|
||||||
|
|
||||||
namespace Hw { struct Boot_info; }
|
namespace Hw { struct Boot_info; }
|
||||||
|
|
||||||
|
@ -27,13 +28,16 @@ struct Hw::Boot_info
|
||||||
Mapping_pool const elf_mappings;
|
Mapping_pool const elf_mappings;
|
||||||
Mmio_space const mmio_space;
|
Mmio_space const mmio_space;
|
||||||
Memory_region_array ram_regions;
|
Memory_region_array ram_regions;
|
||||||
|
Acpi_rsdp const acpi_rsdp;
|
||||||
|
|
||||||
Boot_info(addr_t const table,
|
Boot_info(addr_t const table,
|
||||||
addr_t const table_alloc,
|
addr_t const table_alloc,
|
||||||
Mapping_pool const elf_mappings,
|
Mapping_pool const elf_mappings,
|
||||||
Mmio_space const mmio_space)
|
Mmio_space const mmio_space,
|
||||||
|
Acpi_rsdp const &acpi_rsdp)
|
||||||
: table(table), table_allocator(table_alloc),
|
: table(table), table_allocator(table_alloc),
|
||||||
elf_mappings(elf_mappings), mmio_space(mmio_space) {}
|
elf_mappings(elf_mappings), mmio_space(mmio_space),
|
||||||
|
acpi_rsdp(acpi_rsdp) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _SRC__LIB__HW__BOOT_INFO_H_ */
|
#endif /* _SRC__LIB__HW__BOOT_INFO_H_ */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user