diff --git a/repos/base-hw/src/bootstrap/platform.cc b/repos/base-hw/src/bootstrap/platform.cc index d3401eaff..ecca3f2b0 100644 --- a/repos/base-hw/src/bootstrap/platform.cc +++ b/repos/base-hw/src/bootstrap/platform.cc @@ -197,7 +197,8 @@ Platform::Platform() *construct_at(bi_base, (addr_t)&core_pd->table, (addr_t)&core_pd->array, core_pd->mappings, boot_modules, - board.core_mmio, board.acpi_rsdp); + board.core_mmio, board.acpi_rsdp, + board.framebuffer); /* add all left RAM to bootinfo */ ram_alloc.for_each_free_region([&] (Memory_region const & r) { diff --git a/repos/base-hw/src/bootstrap/platform.h b/repos/base-hw/src/bootstrap/platform.h index fcbcc2b6d..379cc8f08 100644 --- a/repos/base-hw/src/bootstrap/platform.h +++ b/repos/base-hw/src/bootstrap/platform.h @@ -46,6 +46,7 @@ class Bootstrap::Platform Memory_region_array late_ram_regions; Mmio_space const core_mmio; Hw::Acpi_rsdp acpi_rsdp; + Hw::Framebuffer framebuffer; Board(); }; diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/multiboot2.h b/repos/base-hw/src/bootstrap/spec/x86_64/multiboot2.h index ff23b0a24..329e14e37 100644 --- a/repos/base-hw/src/bootstrap/spec/x86_64/multiboot2.h +++ b/repos/base-hw/src/bootstrap/spec/x86_64/multiboot2.h @@ -30,8 +30,10 @@ class Genode::Multiboot2_info : Mmio struct Type : Register <0x00, 32> { - enum { END = 0, MEMORY = 6, ACPI_RSDP_V1 = 14, - ACPI_RSDP_V2 = 15 }; + enum { + END = 0, MEMORY = 6, FRAMEBUFFER = 8, + ACPI_RSDP_V1 = 14, ACPI_RSDP_V2 = 15 + }; }; struct Size : Register <0x04, 32> { }; @@ -54,8 +56,8 @@ class Genode::Multiboot2_info : Mmio Multiboot2_info(addr_t mbi) : Mmio(mbi) { } - template - void for_each_tag(FUNC_MEM mem_fn, FUNC_ACPI acpi_fn) + template + void for_each_tag(FUNC_MEM mem_fn, FUNC_ACPI acpi_fn, FUNC_FB fb_fn) { addr_t const size = read(); @@ -95,6 +97,15 @@ class Genode::Multiboot2_info : Mmio acpi_fn(*rsdp); } + if (tag.read() == Tag::Type::FRAMEBUFFER) { + size_t const sizeof_tag = 1UL << Tag::LOG2_SIZE; + addr_t const fb_addr = tag_addr + sizeof_tag; + + Hw::Framebuffer const * fb = reinterpret_cast(fb_addr); + if (sizeof(*fb) <= tag.read() - sizeof_tag) + fb_fn(*fb); + } + tag_addr += align_addr(tag.read(), Tag::LOG2_SIZE); } } diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc b/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc index f753a4e8b..8e4161c2e 100644 --- a/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc +++ b/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc @@ -80,6 +80,9 @@ Bootstrap::Platform::Board::Board() /* prefer higher acpi revisions */ if (!acpi_rsdp.valid() || acpi_rsdp.revision < rsdp.revision) acpi_rsdp = rsdp; + }, + [&] (Hw::Framebuffer const &fb) { + framebuffer = fb; }); return; diff --git a/repos/base-hw/src/core/spec/x86_64/platform_support.cc b/repos/base-hw/src/core/spec/x86_64/platform_support.cc index e9ff36f6e..c25ab460b 100644 --- a/repos/base-hw/src/core/spec/x86_64/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/platform_support.cc @@ -69,6 +69,17 @@ void Platform::_init_additional() xml.attribute("xsdt", String<32>(Hex(xsdt))); } }); + xml.node("boot", [&] () { + xml.node("framebuffer", [&] () { + Hw::Framebuffer const &boot_fb = _boot_info().framebuffer; + xml.attribute("phys", String<32>(Hex(boot_fb.addr))); + xml.attribute("width", boot_fb.width); + xml.attribute("height", boot_fb.height); + xml.attribute("bpp", boot_fb.bpp); + xml.attribute("type", boot_fb.type); + xml.attribute("pitch", boot_fb.pitch); + }); + }); }); if (!unmap_local(virt_addr, pages)) { diff --git a/repos/base-hw/src/lib/hw/boot_info.h b/repos/base-hw/src/lib/hw/boot_info.h index cf2bb4381..c4a33ca0a 100644 --- a/repos/base-hw/src/lib/hw/boot_info.h +++ b/repos/base-hw/src/lib/hw/boot_info.h @@ -16,6 +16,7 @@ #include #include +#include namespace Hw { struct Boot_info; } @@ -30,16 +31,18 @@ struct Hw::Boot_info Mmio_space const mmio_space; Memory_region_array ram_regions; Acpi_rsdp const acpi_rsdp; + Framebuffer const framebuffer; Boot_info(addr_t const table, addr_t const table_alloc, Mapping_pool const elf_mappings, Mapping const boot_modules, Mmio_space const mmio_space, - Acpi_rsdp const &acpi_rsdp) + Acpi_rsdp const &acpi_rsdp, + Framebuffer const &fb) : table(table), table_allocator(table_alloc), elf_mappings(elf_mappings), boot_modules(boot_modules), - mmio_space(mmio_space), acpi_rsdp(acpi_rsdp) {} + mmio_space(mmio_space), acpi_rsdp(acpi_rsdp), framebuffer(fb) {} }; #endif /* _SRC__LIB__HW__BOOT_INFO_H_ */ diff --git a/repos/base-hw/src/lib/hw/framebuffer.h b/repos/base-hw/src/lib/hw/framebuffer.h new file mode 100644 index 000000000..22e65a48b --- /dev/null +++ b/repos/base-hw/src/lib/hw/framebuffer.h @@ -0,0 +1,33 @@ +/* + * \brief Framebuffer structure as provided by bootloader + * \author Alexander Boettcher + * \date 2017-11-20 + */ + +/* + * 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__FRAMEBUFFER_H +#define _SRC__LIB__HW__FRAMEBUFFER_H + +#include + +namespace Hw { + struct Framebuffer; +} + +struct Hw::Framebuffer +{ + Genode::uint64_t addr; + Genode::uint32_t pitch; + Genode::uint32_t width; + Genode::uint32_t height; + Genode::uint8_t bpp; + Genode::uint8_t type; +} __attribute__((packed)); + +#endif /* _SRC__LIB__HW__FRAMEBUFFER_H */ diff --git a/tool/run/boot_dir/hw b/tool/run/boot_dir/hw index 0d191494b..f386950fa 100644 --- a/tool/run/boot_dir/hw +++ b/tool/run/boot_dir/hw @@ -129,6 +129,8 @@ proc run_boot_dir {binaries} { # set fh [open "[run_dir]/boot/grub/grub.cfg" "WRONLY CREAT TRUNC"] puts $fh "set timeout=0" + # tell grub2 to prefer 32bit framebuffer resolution + puts $fh "set gfxpayload=\"0x0x32\"" puts $fh "menuentry 'Genode on base-hw' {" puts $fh " insmod multiboot2" puts $fh " multiboot2 /boot/bender $serial_bender_opt"