mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-06 19:07:51 +00:00
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));
|
||||
Boot_info & bootinfo =
|
||||
*construct_at<Boot_info>(bi_base, (addr_t)&core_pd->table,
|
||||
(addr_t)&core_pd->array,
|
||||
core_pd->mappings, board.core_mmio);
|
||||
(addr_t)&core_pd->array,
|
||||
core_pd->mappings, board.core_mmio,
|
||||
board.acpi_rsdp);
|
||||
|
||||
/* add all left RAM to bootinfo */
|
||||
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 late_ram_regions;
|
||||
Mmio_space const core_mmio;
|
||||
Hw::Acpi_rsdp acpi_rsdp;
|
||||
|
||||
Board();
|
||||
};
|
||||
|
@ -28,7 +28,10 @@ class Genode::Multiboot2_info : Mmio
|
||||
struct Tag : Genode::Mmio {
|
||||
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> { };
|
||||
|
||||
Tag(addr_t addr) : Mmio(addr) { }
|
||||
@ -50,8 +53,8 @@ class Genode::Multiboot2_info : Mmio
|
||||
|
||||
Multiboot2_info(addr_t mbi) : Mmio(mbi) { }
|
||||
|
||||
template <typename FUNC>
|
||||
void for_each_mem(FUNC functor)
|
||||
template <typename FUNC_MEM, typename FUNC_ACPI>
|
||||
void for_each_tag(FUNC_MEM mem_fn, FUNC_ACPI acpi_fn)
|
||||
{
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ Bootstrap::Platform::Board::Board()
|
||||
if (__initial_ax == Multiboot2_info::MAGIC) {
|
||||
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>();
|
||||
|
||||
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>();
|
||||
|
||||
lambda(base, size);
|
||||
});
|
||||
},
|
||||
[&] (Hw::Acpi_rsdp const &rsdp) { acpi_rsdp = rsdp; });
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -14,11 +14,73 @@
|
||||
#include <bios_data_area.h>
|
||||
#include <platform.h>
|
||||
#include <kernel/kernel.h>
|
||||
#include <map_local.h>
|
||||
|
||||
#include <util/xml_generator.h>
|
||||
|
||||
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,
|
||||
|
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_
|
||||
|
||||
#include <hw/mmio_space.h>
|
||||
#include <hw/acpi_rsdp.h>
|
||||
|
||||
namespace Hw { struct Boot_info; }
|
||||
|
||||
@ -27,13 +28,16 @@ struct Hw::Boot_info
|
||||
Mapping_pool const elf_mappings;
|
||||
Mmio_space const mmio_space;
|
||||
Memory_region_array ram_regions;
|
||||
Acpi_rsdp const acpi_rsdp;
|
||||
|
||||
Boot_info(addr_t const table,
|
||||
addr_t const table_alloc,
|
||||
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),
|
||||
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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user