diff --git a/repos/base-hw/src/bootstrap/board/imx7d_sabre/platform.cc b/repos/base-hw/src/bootstrap/board/imx7d_sabre/platform.cc index 17e4a1ad5f..043f73a15f 100644 --- a/repos/base-hw/src/bootstrap/board/imx7d_sabre/platform.cc +++ b/repos/base-hw/src/bootstrap/board/imx7d_sabre/platform.cc @@ -218,7 +218,7 @@ unsigned Bootstrap::Platform::enable_mmu() void Board::Cpu::wake_up_all_cpus(void * const ip) { - struct Src : Genode::Mmio + struct Src : Genode::Mmio<0x84> { struct A7_cr0 : Register<0x4, 32> { @@ -232,7 +232,7 @@ void Board::Cpu::wake_up_all_cpus(void * const ip) struct Gpr3 : Register<0x7c, 32> {}; /* ep core 1 */ struct Gpr4 : Register<0x80, 32> {}; /* ep core 1 */ - Src(void * const entry) : Genode::Mmio(SRC_MMIO_BASE) + Src(void * const entry) : Mmio({(char *)SRC_MMIO_BASE, Mmio::SIZE}) { write((Gpr3::access_t)entry); write((Gpr4::access_t)entry); diff --git a/repos/base-hw/src/bootstrap/board/pbxa9/platform.cc b/repos/base-hw/src/bootstrap/board/pbxa9/platform.cc index 8746729b57..6c71be40d1 100644 --- a/repos/base-hw/src/bootstrap/board/pbxa9/platform.cc +++ b/repos/base-hw/src/bootstrap/board/pbxa9/platform.cc @@ -40,12 +40,12 @@ void Board::Cpu::wake_up_all_cpus(void * const ip) * read out this register and jump to it after the cpu received * an interrupt */ - struct System_control : Genode::Mmio + struct System_control : Genode::Mmio<0x38> { struct Flagsset : Register<0x30, 32> { }; struct Flagsclr : Register<0x34, 32> { }; - System_control(void * const ip) : Mmio(SYSTEM_CONTROL_MMIO_BASE) + System_control(void * const ip) : Mmio({(char *)SYSTEM_CONTROL_MMIO_BASE, Mmio::SIZE}) { write(~0UL); write(reinterpret_cast(ip)); diff --git a/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc b/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc index fae3912c4c..b1e62c1233 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc +++ b/repos/base-hw/src/bootstrap/spec/arm/cortex_a9_mmu.cc @@ -52,7 +52,7 @@ class Cpu_counter }; -struct Scu : Genode::Mmio +struct Scu : Genode::Mmio<0x34> { struct Cr : Register<0x0, 32> { @@ -72,7 +72,7 @@ struct Scu : Genode::Mmio struct Cpu3_way : Bitfield<12, 4> { }; }; - Scu() : Genode::Mmio(Board::Cpu_mmio::SCU_MMIO_BASE) { } + Scu() : Mmio({(char *)Board::Cpu_mmio::SCU_MMIO_BASE, Mmio::SIZE}) { } void invalidate() { diff --git a/repos/base-hw/src/bootstrap/spec/arm/gicv3.cc b/repos/base-hw/src/bootstrap/spec/arm/gicv3.cc index 36d5c55a38..8b9015f371 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/gicv3.cc +++ b/repos/base-hw/src/bootstrap/spec/arm/gicv3.cc @@ -15,10 +15,14 @@ Hw::Pic::Pic() : - _distr(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE), - _redistr(Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE), - _redistr_sgi(Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE + - Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE / 2), + _distr({(char *)Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE, + Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_SIZE}), + _redistr({(char *)Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE, + Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE}), + _redistr_sgi({(char *)Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE + + Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE / 2, + Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE - + Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE / 2}), _max_irq(_distr.max_irq()) { /* disable device */ diff --git a/repos/base-hw/src/bootstrap/spec/arm/imx_aipstz.h b/repos/base-hw/src/bootstrap/spec/arm/imx_aipstz.h index 5d6906561c..67b62618cf 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/imx_aipstz.h +++ b/repos/base-hw/src/bootstrap/spec/arm/imx_aipstz.h @@ -29,7 +29,7 @@ namespace Bootstrap { } -class Bootstrap::Aipstz : public Genode::Mmio +class Bootstrap::Aipstz : public Genode::Mmio<0x54> { private: @@ -66,7 +66,7 @@ class Bootstrap::Aipstz : public Genode::Mmio /** * Configure this module appropriately for the first kernel run */ - Aipstz(Genode::addr_t const base) : Genode::Mmio(base) + Aipstz(Genode::addr_t const base) : Mmio({(char *)base, Mmio::SIZE}) { /* avoid AIPS intervention at any memory access */ write(Mpr::ALL_UNBUFFERED_AND_FULLY_TRUSTED); diff --git a/repos/base-hw/src/bootstrap/spec/arm/imx_csu.h b/repos/base-hw/src/bootstrap/spec/arm/imx_csu.h index 51793ce9af..78554a8e10 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/imx_csu.h +++ b/repos/base-hw/src/bootstrap/spec/arm/imx_csu.h @@ -20,7 +20,7 @@ namespace Bootstrap { struct Csu; } -struct Bootstrap::Csu : Genode::Mmio +struct Bootstrap::Csu : Genode::Mmio<0x36c> { template struct Csl : public Register @@ -99,7 +99,7 @@ struct Bootstrap::Csu : Genode::Mmio bool secure_uart, bool secure_gpio, bool secure_esdhc, - bool secure_i2c) : Genode::Mmio(base) + bool secure_i2c) : Mmio({(char *)base, Mmio::SIZE}) { /* Power (CCM, SRC, DPLLIP1-4, GPC and OWIRE) */ write(Csl00::UNSECURE); diff --git a/repos/base-hw/src/bootstrap/spec/arm/imx_tzic.cc b/repos/base-hw/src/bootstrap/spec/arm/imx_tzic.cc index b9b4e78b1d..13c386b1f3 100644 --- a/repos/base-hw/src/bootstrap/spec/arm/imx_tzic.cc +++ b/repos/base-hw/src/bootstrap/spec/arm/imx_tzic.cc @@ -15,7 +15,7 @@ Hw::Pic::Pic() : - Genode::Mmio(Board::IRQ_CONTROLLER_BASE) + Mmio({(char *)Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE}) { for (unsigned i = 0; i < NR_OF_IRQ; i++) { write(!Board::secure_irq(i), i); diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/multiboot.h b/repos/base-hw/src/bootstrap/spec/x86_64/multiboot.h index 5c83d806dd..f130674baa 100644 --- a/repos/base-hw/src/bootstrap/spec/x86_64/multiboot.h +++ b/repos/base-hw/src/bootstrap/spec/x86_64/multiboot.h @@ -21,7 +21,7 @@ namespace Genode { class Multiboot_info; } -class Genode::Multiboot_info : Mmio +class Genode::Multiboot_info : Mmio<0x34> { private: @@ -39,17 +39,17 @@ class Genode::Multiboot_info : Mmio MAGIC = 0x2badb002, }; - Multiboot_info(addr_t mbi) : Mmio(mbi) { } + Multiboot_info(addr_t mbi) : Mmio({(char *)mbi, Mmio::SIZE}) { } Multiboot_info(addr_t mbi, bool strip); - struct Mmap : Genode::Mmio + struct Mmap : Genode::Mmio<0x1c> { struct Size : Register <0x00, 32> { }; struct Addr : Register <0x04, 64> { }; struct Length : Register <0x0c, 64> { }; struct Type : Register <0x14, 8> { enum { MEMORY = 1 }; }; - Mmap(addr_t mmap = 0) : Mmio(mmap) { } + Mmap(addr_t mmap = 0) : Mmio({(char *)mmap, Mmio::SIZE}) { } }; /** 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 af10f76946..0dae4949fd 100644 --- a/repos/base-hw/src/bootstrap/spec/x86_64/multiboot2.h +++ b/repos/base-hw/src/bootstrap/spec/x86_64/multiboot2.h @@ -19,13 +19,14 @@ namespace Genode { class Multiboot2_info; } -class Genode::Multiboot2_info : Mmio +class Genode::Multiboot2_info : Mmio<0x8> { private: struct Size : Register <0x0, 32> { }; - struct Tag : Genode::Mmio + template + struct Tag_tpl : Genode::Mmio { enum { LOG2_SIZE = 3 }; @@ -42,21 +43,23 @@ class Genode::Multiboot2_info : Mmio }; struct Size : Register <0x04, 32> { }; - Tag(addr_t addr) : Mmio(addr) { } + Tag_tpl(addr_t addr) : Mmio({(char *)addr, SIZE}) { } }; - struct Efi_system_table_64 : Tag + using Tag = Tag_tpl<0x8>; + + struct Efi_system_table_64 : Tag_tpl<0x10> { struct Pointer : Register <0x08, 64> { }; - Efi_system_table_64(addr_t addr) : Tag(addr) { } + Efi_system_table_64(addr_t addr) : Tag_tpl(addr) { } }; public: enum { MAGIC = 0x36d76289UL }; - struct Memory : Genode::Mmio + struct Memory : Genode::Mmio<0x14> { enum { SIZE = 3 * 8 }; @@ -64,10 +67,10 @@ class Genode::Multiboot2_info : Mmio struct Size : Register <0x08, 64> { }; struct Type : Register <0x10, 32> { enum { MEMORY = 1 }; }; - Memory(addr_t mmap = 0) : Mmio(mmap) { } + Memory(addr_t mmap = 0) : Mmio({(char *)mmap, Mmio::SIZE}) { } }; - Multiboot2_info(addr_t mbi) : Mmio(mbi) { } + Multiboot2_info(addr_t mbi) : Mmio({(char *)mbi, Mmio::SIZE}) { } template { struct Svr : Register<0x0f0, 32> { @@ -299,7 +299,7 @@ struct Lapic : Mmio struct Destination : Bitfield<24, 8> { }; }; - Lapic(addr_t const addr) : Mmio(addr) { } + Lapic(addr_t const addr) : Mmio({(char *)addr, Mmio::SIZE}) { } }; diff --git a/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.cc b/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.cc index ad18867824..62b9602991 100644 --- a/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.cc +++ b/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.cc @@ -35,7 +35,7 @@ enum { Board::Timer::Timer(unsigned cpu_id) : - Mmio(Platform::mmio_to_virt(Board::Cpu_mmio::GLOBAL_TIMER_MMIO_BASE)) + Mmio({(char *)Platform::mmio_to_virt(Board::Cpu_mmio::GLOBAL_TIMER_MMIO_BASE), Mmio::SIZE}) { enum { PRESCALER = Board::CORTEX_A9_GLOBAL_TIMER_DIV - 1 }; diff --git a/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h b/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h index 441dac8d7f..3a02b7191b 100644 --- a/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h +++ b/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h @@ -26,7 +26,7 @@ namespace Board { class Timer; } /** * Timer driver for core */ -struct Board::Timer : Genode::Mmio +struct Board::Timer : Genode::Mmio<0x18> { /** * Counter value registers diff --git a/repos/base-hw/src/core/spec/arm/gicv3.cc b/repos/base-hw/src/core/spec/arm/gicv3.cc index 54e3fe2ef1..9bd1a14803 100644 --- a/repos/base-hw/src/core/spec/arm/gicv3.cc +++ b/repos/base-hw/src/core/spec/arm/gicv3.cc @@ -27,9 +27,9 @@ static inline addr_t redistributor_addr() Hw::Pic::Pic() : - _distr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE)), - _redistr(redistributor_addr()), - _redistr_sgi(redistributor_addr() + 0x10000), + _distr({(char *)Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE), Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_SIZE}), + _redistr({(char *)redistributor_addr(), Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE}), + _redistr_sgi({(char *)redistributor_addr() + 0x10000, Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE - 0x10000}), _max_irq(_distr.max_irq()) { _redistributor_init(); diff --git a/repos/base-hw/src/core/spec/arm/imx_epit.cc b/repos/base-hw/src/core/spec/arm/imx_epit.cc index 70a3c193f8..5145c265c5 100644 --- a/repos/base-hw/src/core/spec/arm/imx_epit.cc +++ b/repos/base-hw/src/core/spec/arm/imx_epit.cc @@ -28,7 +28,7 @@ unsigned Timer::interrupt_id() const { return Board::EPIT_1_IRQ; } Board::Timer::Timer(unsigned) : - Mmio(Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE)) + Mmio({(char *)Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE), Mmio::SIZE}) { init(); } diff --git a/repos/base-hw/src/core/spec/arm/imx_epit.h b/repos/base-hw/src/core/spec/arm/imx_epit.h index 328fc692ed..e822fa71e4 100644 --- a/repos/base-hw/src/core/spec/arm/imx_epit.h +++ b/repos/base-hw/src/core/spec/arm/imx_epit.h @@ -23,7 +23,7 @@ namespace Board { class Timer; } /** * Timer driver for core */ -struct Board::Timer : Genode::Mmio +struct Board::Timer : Genode::Mmio<0x14> { enum { TICS_PER_MS = 33333 }; diff --git a/repos/base-hw/src/core/spec/arm/imx_tzic.cc b/repos/base-hw/src/core/spec/arm/imx_tzic.cc index 1eef97f6ec..7050f778a1 100644 --- a/repos/base-hw/src/core/spec/arm/imx_tzic.cc +++ b/repos/base-hw/src/core/spec/arm/imx_tzic.cc @@ -18,4 +18,4 @@ using namespace Core; -Hw::Pic::Pic() : Mmio(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE)) { } +Hw::Pic::Pic() : Mmio({(char *)Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE), Mmio::SIZE}) { } diff --git a/repos/base-hw/src/core/spec/arm/virtualization/gicv2.cc b/repos/base-hw/src/core/spec/arm/virtualization/gicv2.cc index 14db8b4f6f..1dee16a90b 100644 --- a/repos/base-hw/src/core/spec/arm/virtualization/gicv2.cc +++ b/repos/base-hw/src/core/spec/arm/virtualization/gicv2.cc @@ -23,7 +23,7 @@ using Board::Pic; Pic::Gich::Gich() : - Genode::Mmio(Core::Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_VT_CTRL_BASE)) + Mmio({(char *)Core::Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_VT_CTRL_BASE), Mmio::SIZE}) { } diff --git a/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h b/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h index cbd28ecafb..32fec30457 100644 --- a/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h +++ b/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h @@ -29,7 +29,7 @@ class Board::Pic : public Hw::Gicv2 using uint32_t = Genode::uint32_t; - struct Gich : Genode::Mmio + struct Gich : Genode::Mmio<0x104> { struct Gich_hcr : Register<0x00, 32> { }; struct Gich_vmcr : Register<0x08, 32> { }; diff --git a/repos/base-hw/src/core/spec/riscv/pic.cc b/repos/base-hw/src/core/spec/riscv/pic.cc index d915e338d3..605f38e258 100644 --- a/repos/base-hw/src/core/spec/riscv/pic.cc +++ b/repos/base-hw/src/core/spec/riscv/pic.cc @@ -17,7 +17,7 @@ Board::Pic::Pic(Global_interrupt_controller &) : - _plic(Core::Platform::mmio_to_virt(Board::PLIC_BASE)) + _plic({(char *)Core::Platform::mmio_to_virt(Board::PLIC_BASE), Board::PLIC_SIZE}) { /* enable external interrupts */ enum { SEIE = 0x200 }; diff --git a/repos/base-hw/src/core/spec/x86_64/fpu.h b/repos/base-hw/src/core/spec/x86_64/fpu.h index b3bf484f95..817a26b716 100644 --- a/repos/base-hw/src/core/spec/x86_64/fpu.h +++ b/repos/base-hw/src/core/spec/x86_64/fpu.h @@ -35,14 +35,14 @@ class Genode::Fpu_context */ char _fxsave_area[527]; - struct Context : Mmio + struct Context : Mmio<512> { struct Fcw : Register<0, 16> { }; struct Mxcsr : Register<24, 32> { }; - Context(addr_t const base) : Mmio(base) + Context(addr_t const base) : Mmio({(char *)base, Mmio::SIZE}) { - memset((void *)base, 0, 512); + memset((void *)base, 0, Mmio::SIZE); write(0x37f); /* mask exceptions SysV ABI */ write(0x1f80); } diff --git a/repos/base-hw/src/core/spec/x86_64/pic.cc b/repos/base-hw/src/core/spec/x86_64/pic.cc index 6a6c67c3cf..99cdef7574 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.cc +++ b/repos/base-hw/src/core/spec/x86_64/pic.cc @@ -15,7 +15,6 @@ /* Genode includes */ #include -#include /* core includes */ #include @@ -40,7 +39,7 @@ enum { Local_interrupt_controller:: Local_interrupt_controller(Global_interrupt_controller &global_irq_ctrl) : - Mmio { Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()) }, + Mmio { {(char *)Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()), Mmio::SIZE} }, _global_irq_ctrl { global_irq_ctrl } { init(); @@ -236,7 +235,7 @@ Global_interrupt_controller::_create_irt_entry(unsigned const irq) Global_interrupt_controller::Global_interrupt_controller() : - Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::MMIO_IOAPIC_BASE)) + Mmio({(char *)Platform::mmio_to_virt(Hw::Cpu_memory_map::MMIO_IOAPIC_BASE), Mmio::SIZE}) { write(IOAPICVER); _irte_count = read() + 1; diff --git a/repos/base-hw/src/core/spec/x86_64/pic.h b/repos/base-hw/src/core/spec/x86_64/pic.h index d8243e9aca..dc31eb99f9 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.h +++ b/repos/base-hw/src/core/spec/x86_64/pic.h @@ -17,6 +17,7 @@ /* Genode includes */ #include +#include namespace Board { @@ -47,7 +48,7 @@ struct Board::Irte : Genode::Register<64> }; -class Board::Global_interrupt_controller : public Genode::Mmio +class Board::Global_interrupt_controller : public Genode::Mmio { private: @@ -147,7 +148,7 @@ class Board::Global_interrupt_controller : public Genode::Mmio }; -class Board::Local_interrupt_controller : public Genode::Mmio +class Board::Local_interrupt_controller : public Genode::Mmio { private: diff --git a/repos/base-hw/src/core/spec/x86_64/pit.cc b/repos/base-hw/src/core/spec/x86_64/pit.cc index 3c594f47df..60bdb5662d 100644 --- a/repos/base-hw/src/core/spec/x86_64/pit.cc +++ b/repos/base-hw/src/core/spec/x86_64/pit.cc @@ -55,7 +55,7 @@ uint32_t Board::Timer::pit_calc_timer_freq(void) Board::Timer::Timer(unsigned) : - Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base())) + Mmio({(char *)Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()), Mmio::SIZE}) { init(); } diff --git a/repos/base-hw/src/core/spec/x86_64/pit.h b/repos/base-hw/src/core/spec/x86_64/pit.h index 0d6bad1785..026e293d9a 100644 --- a/repos/base-hw/src/core/spec/x86_64/pit.h +++ b/repos/base-hw/src/core/spec/x86_64/pit.h @@ -28,7 +28,7 @@ namespace Board { class Timer; } /** * LAPIC-based timer driver for core */ -struct Board::Timer: Genode::Mmio +struct Board::Timer: Genode::Mmio { enum { /* PIT constants */ diff --git a/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/svm.cc b/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/svm.cc index 6e6f43a732..6a231ace0c 100644 --- a/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/svm.cc +++ b/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/svm.cc @@ -26,7 +26,7 @@ using Board::Vmcb; Vmcb::Vmcb(Genode::uint32_t id) : - Mmio((Genode::addr_t)this) + Mmio({(char *)this, Mmio::SIZE}) { write(id); write(dummy_msrpm()); diff --git a/repos/base-hw/src/core/spec/x86_64/virtualization/svm.h b/repos/base-hw/src/core/spec/x86_64/virtualization/svm.h index 34297da6ed..7c6f970724 100644 --- a/repos/base-hw/src/core/spec/x86_64/virtualization/svm.h +++ b/repos/base-hw/src/core/spec/x86_64/virtualization/svm.h @@ -77,11 +77,10 @@ struct Board::Vmcb_control_area struct Board::Vmcb_reserved_for_host { /* 64bit used by the inherited Mmio class here */ - Genode::uint64_t _reserved[1]; Genode::addr_t root_vmcb_phys = 0U; }; static_assert(Board::Vmcb_control_area::total_size - - sizeof(Board::Vmcb_control_area) - sizeof(Genode::Mmio) - + sizeof(Board::Vmcb_control_area) - sizeof(Genode::Mmio<0>) - sizeof(Board::Vmcb_reserved_for_host) == 0); @@ -136,7 +135,7 @@ struct Board::Vmcb_state_save_area struct alignas(Genode::get_page_size()) Board::Vmcb : Board::Vmcb_control_area, - public Genode::Mmio, + public Genode::Mmio, Board::Vmcb_reserved_for_host, Board::Vmcb_state_save_area { diff --git a/repos/base-hw/src/include/hw/spec/arm/gicv2.h b/repos/base-hw/src/include/hw/spec/arm/gicv2.h index c3edfc1a13..c4d67fb2ff 100644 --- a/repos/base-hw/src/include/hw/spec/arm/gicv2.h +++ b/repos/base-hw/src/include/hw/spec/arm/gicv2.h @@ -27,7 +27,7 @@ class Hw::Gicv2 /** * Distributor of the ARM generic interrupt controller */ - struct Distributor : Genode::Mmio + struct Distributor : Genode::Mmio<0xf04> { static constexpr unsigned nr_of_irq = 1024; @@ -99,7 +99,7 @@ class Hw::Gicv2 }; }; - Distributor(Genode::addr_t const base) : Genode::Mmio(base) { } + Distributor(Genode::addr_t const base) : Mmio({(char *)base, Mmio::SIZE}) { } /** * Return minimum IRQ priority @@ -125,7 +125,7 @@ class Hw::Gicv2 /** * CPU interface of the ARM generic interrupt controller */ - struct Cpu_interface : Genode::Mmio + struct Cpu_interface : Genode::Mmio<0x14> { /** * Control register @@ -162,7 +162,7 @@ class Hw::Gicv2 struct Eoir : Register<0x10, 32, true> { struct Irq_id : Bitfield<0,10> { }; }; - Cpu_interface(Genode::addr_t const base) : Genode::Mmio(base) { } + Cpu_interface(Genode::addr_t const base) : Mmio({(char *)base, Mmio::SIZE}) { } }; diff --git a/repos/base-hw/src/include/hw/spec/arm/gicv3.h b/repos/base-hw/src/include/hw/spec/arm/gicv3.h index b367b7ca6d..2f3d0cea64 100644 --- a/repos/base-hw/src/include/hw/spec/arm/gicv3.h +++ b/repos/base-hw/src/include/hw/spec/arm/gicv3.h @@ -42,7 +42,7 @@ class Hw::Pic static constexpr unsigned min_spi = 32; static constexpr unsigned spurious_id = 1023; - struct Distributor : Genode::Mmio + struct Distributor : Genode::Mmio<0x7fe0> { static constexpr unsigned nr_of_irq = 1024; @@ -103,19 +103,17 @@ class Hw::Pic unsigned max_irq() { return 32 * (read() + 1) - 1; } - Distributor(Genode::addr_t const base) : Genode::Mmio(base) - { } + using Mmio::Mmio; }; - struct Redistributor : Genode::Mmio + struct Redistributor : Genode::Mmio<0x4> { struct Ctlr : Register<0x0, 32> { struct Uwp : Bitfield<31, 1> { }; }; - Redistributor(Genode::addr_t const base) : Genode::Mmio(base) - { } + using Mmio::Mmio; /* wait for upstream writes */ void wait_for_uwp() @@ -126,7 +124,7 @@ class Hw::Pic } }; - struct Redistributor_sgi_ppi : Genode::Mmio + struct Redistributor_sgi_ppi : Genode::Mmio<0xc08> { struct Igroupr0 : Register<0x80, 32> { }; @@ -143,8 +141,7 @@ class Hw::Pic struct Icfgr1 : Register<0xc04, 32> { }; - Redistributor_sgi_ppi(Genode::addr_t const base) : Genode::Mmio(base) - { } + using Mmio::Mmio; }; struct Cpu_interface diff --git a/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h b/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h index 77c1a3d947..243727128b 100644 --- a/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h +++ b/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h @@ -19,7 +19,7 @@ namespace Hw { class Pic; } -class Hw::Pic : public Genode::Mmio +class Hw::Pic : public Genode::Mmio<0xf04> { public: diff --git a/repos/base-hw/src/include/hw/spec/arm/pl310.h b/repos/base-hw/src/include/hw/spec/arm/pl310.h index 38b8769388..7c14367c95 100644 --- a/repos/base-hw/src/include/hw/spec/arm/pl310.h +++ b/repos/base-hw/src/include/hw/spec/arm/pl310.h @@ -22,7 +22,7 @@ namespace Hw { struct Pl310; } -class Hw::Pl310 : public Genode::Mmio +class Hw::Pl310 : public Genode::Mmio<0xf64> { protected: @@ -104,7 +104,7 @@ class Hw::Pl310 : public Genode::Mmio public: - Pl310(Genode::addr_t const base) : Mmio(base) { } + Pl310(Genode::addr_t const base) : Mmio({(char *)base, Mmio::SIZE}) { } void enable() {} void disable() {} diff --git a/repos/base-hw/src/include/hw/spec/x86_64/acpi.h b/repos/base-hw/src/include/hw/spec/x86_64/acpi.h index ee61623f5b..bda6053968 100644 --- a/repos/base-hw/src/include/hw/spec/x86_64/acpi.h +++ b/repos/base-hw/src/include/hw/spec/x86_64/acpi.h @@ -59,20 +59,20 @@ struct Hw::Apic_madt Apic_madt *next() const { return reinterpret_cast((Genode::uint8_t *)this + length); } - struct Ioapic : Genode::Mmio + struct Ioapic : Genode::Mmio<0xc> { struct Id : Register <0x02, 8> { }; struct Paddr : Register <0x04, 32> { }; struct Gsi_base : Register <0x08, 32> { }; - Ioapic(Apic_madt const * a) : Mmio(reinterpret_cast(a)) { } + Ioapic(Apic_madt const * a) : Mmio({(char *)a, Mmio::SIZE}) { } }; - struct Lapic : Genode::Mmio + struct Lapic : Genode::Mmio<0x8> { struct Flags : Register <0x04, 32> { enum { VALID = 1 }; }; - Lapic(Apic_madt const * a) : Mmio(reinterpret_cast(a)) { } + Lapic(Apic_madt const * a) : Mmio({(char *)a, Mmio::SIZE}) { } bool valid() { return read() & Flags::VALID; }; }; @@ -81,7 +81,7 @@ struct Hw::Apic_madt /* ACPI spec 5.2.9 and ACPI GAS 5.2.3.2 */ -struct Hw::Acpi_fadt : Genode::Mmio +struct Hw::Acpi_fadt : Genode::Mmio<276> { enum Addressspace { IO = 0x1 }; @@ -174,7 +174,7 @@ struct Hw::Acpi_fadt : Genode::Mmio asm volatile ("outl %0, %w1" : : "a"(val), "Nd"(port)); } - Acpi_fadt(Acpi_generic const * a) : Mmio(Genode::addr_t(a)) { } + Acpi_fadt(Acpi_generic const * a) : Mmio({(char *)a, Mmio::SIZE}) { } addr_t facs() const { @@ -346,7 +346,7 @@ struct Hw::Acpi_fadt : Genode::Mmio }; -struct Hw::Acpi_facs : Genode::Mmio +struct Hw::Acpi_facs : Genode::Mmio<64> { struct Length : Register < 0x04, 32> { }; struct Fw_wake_vector : Register < 0x0c, 32> { }; @@ -362,7 +362,7 @@ struct Hw::Acpi_facs : Genode::Mmio write(0); } - Acpi_facs(addr_t const mmio) : Mmio(mmio) { } + Acpi_facs(addr_t const mmio) : Mmio({(char *)mmio, Mmio::SIZE}) { } }; diff --git a/repos/base-hw/src/include/hw/spec/x86_64/x86_64.h b/repos/base-hw/src/include/hw/spec/x86_64/x86_64.h index 4d130a1641..b41d14d590 100644 --- a/repos/base-hw/src/include/hw/spec/x86_64/x86_64.h +++ b/repos/base-hw/src/include/hw/spec/x86_64/x86_64.h @@ -31,6 +31,7 @@ struct Hw::Cpu_memory_map enum { MMIO_IOAPIC_BASE = 0xfec00000, MMIO_IOAPIC_SIZE = 0x1000, + LAPIC_SIZE = 0xe34, }; static Genode::addr_t lapic_phys_base() diff --git a/repos/base/include/drivers/uart/imx.h b/repos/base/include/drivers/uart/imx.h index 0b88152c0b..361ed6921f 100644 --- a/repos/base/include/drivers/uart/imx.h +++ b/repos/base/include/drivers/uart/imx.h @@ -24,7 +24,7 @@ namespace Genode { class Imx_uart; } /** * Driver base for i.MX UART-module */ -class Genode::Imx_uart: Mmio +class Genode::Imx_uart: Mmio<0xa2> { /** * Control register 1 @@ -246,7 +246,7 @@ class Genode::Imx_uart: Mmio * * \param base device MMIO base */ - Imx_uart(addr_t base, uint32_t, uint32_t) : Mmio(base) + Imx_uart(addr_t base, uint32_t, uint32_t) : Mmio({(char*)base, Mmio::SIZE}) { init(); } diff --git a/repos/base/include/drivers/uart/pl011.h b/repos/base/include/drivers/uart/pl011.h index 2d25cc5a1b..22f3c2c599 100644 --- a/repos/base/include/drivers/uart/pl011.h +++ b/repos/base/include/drivers/uart/pl011.h @@ -17,13 +17,13 @@ /* Genode includes */ #include -namespace Genode { class Pl011_uart; } +namespace Genode { class Pl011_uart; } /** * Driver base for the PrimeCell UART PL011 Revision r1p3 */ -class Genode::Pl011_uart : Mmio +class Genode::Pl011_uart : Mmio<0x3a> { protected: @@ -132,7 +132,7 @@ class Genode::Pl011_uart : Mmio Genode::Pl011_uart::Pl011_uart(addr_t const base, uint32_t const clock, - uint32_t const baud_rate) : Mmio(base) + uint32_t const baud_rate) : Mmio({(char *)base, Mmio::SIZE}) { write(Uartcr::Uarten::bits(1) | Uartcr::Txe::bits(1) | diff --git a/repos/base/include/spec/x86/bios_data_area.h b/repos/base/include/spec/x86/bios_data_area.h index b4b36739c8..8d67fd72c9 100644 --- a/repos/base/include/spec/x86/bios_data_area.h +++ b/repos/base/include/spec/x86/bios_data_area.h @@ -22,21 +22,21 @@ namespace Genode { class Bios_data_area; } -class Genode::Bios_data_area : Mmio +class Genode::Bios_data_area : Mmio<0x12> { friend Unmanaged_singleton_constructor; private: - struct Serial_base_com1 : Register<0x400, 16> { }; - struct Equipment : Register<0x410, 16> + struct Serial_base_com1 : Register<0x0, 16> { }; + struct Equipment : Register<0x10, 16> { struct Serial_count : Bitfield<9, 3> { }; }; static addr_t _mmio_base_virt(); - Bios_data_area() : Mmio(_mmio_base_virt()) { } + Bios_data_area() : Mmio({(char *)(_mmio_base_virt() + 0x400), Mmio::SIZE}) { } public: diff --git a/repos/base/include/util/mmio.h b/repos/base/include/util/mmio.h index 58301b6aa9..1da6e2ddc7 100644 --- a/repos/base/include/util/mmio.h +++ b/repos/base/include/util/mmio.h @@ -15,12 +15,14 @@ #define _INCLUDE__UTIL__MMIO_H_ /* Genode includes */ +#include +#include #include namespace Genode { class Mmio_plain_access; - class Mmio; + template class Mmio; } /** @@ -32,27 +34,24 @@ class Genode::Mmio_plain_access private: - addr_t const _base; + Byte_range_ptr const _range; /** - * Write '_ACCESS_T' typed 'value' to MMIO base + 'offset' + * Write 'ACCESS_T' typed 'value' to MMIO base + 'offset' */ template inline void _write(off_t const offset, ACCESS_T const value) { - addr_t const dst = _base + offset; - *(ACCESS_T volatile *)dst = value; + *(ACCESS_T volatile *)(_range.start + offset) = value; } /** - * Read '_ACCESS_T' typed from MMIO base + 'offset' + * Read 'ACCESS_T' typed from MMIO base + 'offset' */ template inline ACCESS_T _read(off_t const &offset) const { - addr_t const dst = _base + offset; - ACCESS_T const value = *(ACCESS_T volatile *)dst; - return value; + return *(ACCESS_T volatile *)(_range.start + offset); } public: @@ -62,9 +61,16 @@ class Genode::Mmio_plain_access * * \param base base address of targeted MMIO region */ - Mmio_plain_access(addr_t const base) : _base(base) { } + Mmio_plain_access(Byte_range_ptr const &range) : _range(range.start, range.num_bytes) { } - addr_t base() const { return _base; } + Byte_range_ptr range_at(off_t offset) const + { + return {_range.start + offset, _range.num_bytes - offset}; + } + + Byte_range_ptr range() const { return range_at(0); } + + addr_t base() const { return (addr_t)range().start; } }; @@ -73,17 +79,28 @@ class Genode::Mmio_plain_access * * For further details refer to the documentation of the 'Register_set' class. */ -struct Genode::Mmio : Mmio_plain_access, Register_set +template +struct Genode::Mmio : Mmio_plain_access, Register_set { + static constexpr size_t SIZE = MMIO_SIZE; + + class Range_violation : Exception { }; + /** * Constructor * - * \param base base address of targeted MMIO region + * \param range byte range of targeted MMIO region */ - Mmio(addr_t const base) + Mmio(Byte_range_ptr const &range) : - Mmio_plain_access(base), - Register_set(*static_cast(this)) { } + Mmio_plain_access(range), + Register_set(*static_cast(this)) + { + if (range.num_bytes < SIZE) { + error("MMIO range is unexpectedly too small"); + throw Range_violation { }; + } + } }; #endif /* _INCLUDE__UTIL__MMIO_H_ */ diff --git a/repos/base/include/util/register_set.h b/repos/base/include/util/register_set.h index c6bc639323..402aee6d2e 100644 --- a/repos/base/include/util/register_set.h +++ b/repos/base/include/util/register_set.h @@ -23,7 +23,8 @@ namespace Genode { struct Register_set_plain_access; - template class Register_set; + struct Register_set_base; + template class Register_set; } @@ -68,6 +69,21 @@ struct Genode::Register_set_plain_access }; +struct Genode::Register_set_base : Noncopyable +{ + /** + * Interface for delaying the execution of a calling thread + */ + struct Delayer : Interface + { + /** + * Delay execution of the caller for 'us' microseconds + */ + virtual void usleep(uint64_t us) = 0; + }; +}; + + /** * Set of fine-grained and typesafe accessible registers with offsets * @@ -83,8 +99,8 @@ struct Genode::Register_set_plain_access * must not define members named 'Register_base', 'Bitfield_base', * 'Register_array_base' or 'Array_bitfield_base'. */ -template -class Genode::Register_set : Noncopyable +template +class Genode::Register_set : public Register_set_base { private: @@ -225,6 +241,8 @@ class Genode::Register_set : Noncopyable typedef typename Genode::Register<_ACCESS_WIDTH>::access_t access_t; + static_assert(OFFSET + sizeof(access_t) <= REGISTER_SET_SIZE); + /** * A region within a register * @@ -333,28 +351,27 @@ class Genode::Register_set : Noncopyable Compound_array; }; + + struct Dst { off_t offset; uint8_t shift; }; + /** * Calculate destination of an array-item access * - * \param offset Gets overridden with the offset of the - * access type instance, that contains the - * access destination - * \param shift Gets overridden with the shift of the - * destination within the access type instance - * targeted by 'offset'. * \param index index of the targeted array item */ - static inline void dst(off_t & offset, - unsigned long & shift, - unsigned long const index) + static constexpr Dst dst(unsigned long index) { - unsigned long const bit_off = index << ITEM_WIDTH_LOG2; - offset = (off_t) ((bit_off >> BYTE_WIDTH_LOG2) - & ~(sizeof(access_t)-1) ); - shift = bit_off - ( offset << BYTE_WIDTH_LOG2 ); + off_t bit_offset = off_t(index << ITEM_WIDTH_LOG2); + off_t byte_offset = bit_offset >> BYTE_WIDTH_LOG2; + off_t offset = byte_offset & ~(sizeof(access_t) - 1); + uint8_t shift = uint8_t(bit_offset - (offset << BYTE_WIDTH_LOG2)); offset += OFFSET; + + return { .offset = offset, .shift = shift }; } + static_assert(dst(MAX_INDEX).offset + sizeof(access_t) <= REGISTER_SET_SIZE); + /** * Calc destination of a simple array-item access without shift * @@ -485,10 +502,9 @@ class Genode::Register_set : Noncopyable /* access width and item width differ */ } else { - long unsigned shift; - Array::dst(offset, shift, index); - return (Plain_access::read(_plain_access, offset) - >> shift) & Array::ITEM_MASK; + typename Array::Dst dst { Array::dst(index) }; + return (Plain_access::read(_plain_access, dst.offset) + >> dst.shift) & Array::ITEM_MASK; } } @@ -517,8 +533,7 @@ class Genode::Register_set : Noncopyable /* access width and item width differ */ } else { - long unsigned shift; - Array::dst(offset, shift, index); + typename Array::Dst dst { Array::dst(index) }; /* insert new value into old register value */ access_t write_value; @@ -530,12 +545,12 @@ class Genode::Register_set : Noncopyable /* apply bitfield to the old register value */ write_value = Plain_access::read(_plain_access, - offset); - write_value &= ~(Array::ITEM_MASK << shift); + dst.offset); + write_value &= ~(Array::ITEM_MASK << dst.shift); } /* apply bitfield value and override register */ - write_value |= (value & Array::ITEM_MASK) << shift; - Plain_access::write(_plain_access, offset, + write_value |= (value & Array::ITEM_MASK) << dst.shift; + Plain_access::write(_plain_access, dst.offset, write_value); } } @@ -680,17 +695,6 @@ class Genode::Register_set : Noncopyable explicit Microseconds(uint64_t value) : value(value) { } }; - /** - * Interface for delaying the execution of a calling thread - */ - struct Delayer : Interface - { - /** - * Delay execution of the caller for 'us' microseconds - */ - virtual void usleep(uint64_t us) = 0; - }; - /** * Wait until a list of IO conditions is met diff --git a/repos/base/src/test/mmio/main.cc b/repos/base/src/test/mmio/main.cc index 5a006e8f73..52423e1060 100644 --- a/repos/base/src/test/mmio/main.cc +++ b/repos/base/src/test/mmio/main.cc @@ -58,9 +58,9 @@ struct Cpu_state : Register<16> /** * Exemplary MMIO region type */ -struct Test_mmio : public Mmio +struct Test_mmio : public Mmio { - Test_mmio(addr_t const base) : Mmio(base) { } + Test_mmio(addr_t const base) : Mmio({(char *)base, Mmio::SIZE}) { } struct Reg_64 : Register<0x00, 64> { @@ -129,7 +129,7 @@ struct Test_mmio : public Mmio struct Simple_array_1 : Register_array<0x0, 32, 2, 32> { }; - struct Simple_array_2 : Register_array<0x2, 16, 4, 16> { }; + struct Simple_array_2 : Register_array<0x2, 16, 3, 16> { }; struct Strict_reg : Register<0x0, 32, true> { diff --git a/repos/base/src/timer/epit/imx6/timer.cc b/repos/base/src/timer/epit/imx6/timer.cc index 33beefc6c6..ca9073062e 100644 --- a/repos/base/src/timer/epit/imx6/timer.cc +++ b/repos/base/src/timer/epit/imx6/timer.cc @@ -27,7 +27,7 @@ using namespace Genode; Timer::Time_source::Time_source(Env &env) : - Attached_mmio(env, EPIT_2_MMIO_BASE, EPIT_2_MMIO_SIZE), + Attached_mmio(env, {(char *)EPIT_2_MMIO_BASE, EPIT_2_MMIO_SIZE}), Signalled_time_source(env), _timer_irq(env, unsigned(EPIT_2_IRQ)) { diff --git a/repos/base/src/timer/epit/time_source.h b/repos/base/src/timer/epit/time_source.h index f4fd4a54ea..7f44e8fc1e 100644 --- a/repos/base/src/timer/epit/time_source.h +++ b/repos/base/src/timer/epit/time_source.h @@ -26,8 +26,7 @@ namespace Timer { class Time_source; } - -class Timer::Time_source : private Genode::Attached_mmio, +class Timer::Time_source : private Genode::Attached_mmio<0x14>, public Genode::Signalled_time_source { private: diff --git a/repos/dde_bsd/src/lib/audio/pci.cc b/repos/dde_bsd/src/lib/audio/pci.cc index 64aedad005..191f6beab9 100644 --- a/repos/dde_bsd/src/lib/audio/pci.cc +++ b/repos/dde_bsd/src/lib/audio/pci.cc @@ -51,9 +51,9 @@ class Pci_driver struct Device { - Platform::Device dev; - Platform::Device::Irq irq; - Platform::Device::Mmio mmio; + Platform::Device dev; + Platform::Device::Irq irq; + Platform::Device::Mmio<0> mmio; Device(Platform::Connection &pci, Platform::Device::Name const &name) diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc index 45216e0231..1e5a5d70f9 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc +++ b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc @@ -148,7 +148,7 @@ extern "C" void dde_mdelay(unsigned long msecs) struct Range { addr_t start; size_t size; }; -using Io_mem = Platform::Device::Mmio; +using Io_mem = Platform::Device::Mmio<0>; using Io_port = Platform::Device::Io_port_range; struct Pci_driver diff --git a/repos/dde_linux/src/include/lx_kit/device.h b/repos/dde_linux/src/include/lx_kit/device.h index 7368d95dbf..0a1c85fc18 100644 --- a/repos/dde_linux/src/include/lx_kit/device.h +++ b/repos/dde_linux/src/include/lx_kit/device.h @@ -45,14 +45,14 @@ class Lx_kit::Device : List::Element struct Io_mem : List::Element { - using Index = Platform::Device::Mmio::Index; + using Index = Platform::Device::Mmio<0>::Index; Index idx; addr_t addr; size_t size; unsigned pci_bar; - Constructible io_mem {}; + Constructible > io_mem {}; bool match(addr_t addr, size_t size); diff --git a/repos/os/include/os/attached_mmio.h b/repos/os/include/os/attached_mmio.h index 1eb930fc8c..7833634bfe 100644 --- a/repos/os/include/os/attached_mmio.h +++ b/repos/os/include/os/attached_mmio.h @@ -18,7 +18,7 @@ #include #include -namespace Genode { class Attached_mmio; } +namespace Genode { template class Attached_mmio; } /** @@ -30,8 +30,9 @@ namespace Genode { class Attached_mmio; } * and cast the received address. This helper undertakes all of this * generic work when inheriting from it. */ +template class Genode::Attached_mmio : public Attached_io_mem_dataspace, - public Mmio + public Mmio { public: @@ -49,10 +50,9 @@ class Genode::Attached_mmio : public Attached_io_mem_dataspace, * \throw Out_of_caps * \throw Region_map::Region_conflict */ - Attached_mmio(Env &env, addr_t base, size_t size, - bool write_combined = false) - : Attached_io_mem_dataspace(env, base, size, write_combined), - Mmio((addr_t)local_addr()) { } + Attached_mmio(Env &env, Byte_range_ptr const &range, bool write_combined = false) + : Attached_io_mem_dataspace(env, (addr_t)range.start, range.num_bytes, write_combined), + Mmio({local_addr(), range.num_bytes}) { } }; #endif /* _INCLUDE__OS__ATTACHED_MMIO_H_ */ diff --git a/repos/os/include/pci/config.h b/repos/os/include/pci/config.h index d7751bd24e..8e9dbe79be 100644 --- a/repos/os/include/pci/config.h +++ b/repos/os/include/pci/config.h @@ -33,7 +33,7 @@ namespace Pci { }; }; -struct Pci::Config : Genode::Mmio +struct Pci::Config : Genode::Mmio<0x45> { struct Vendor : Register<0x0, 16> { @@ -82,7 +82,7 @@ struct Pci::Config : Genode::Mmio struct Multi_function : Bitfield<7,1> {}; }; - struct Base_address : Mmio + struct Base_address : Mmio<0x8> { struct Bar_32bit : Register<0, 32> { @@ -126,7 +126,7 @@ struct Pci::Config : Genode::Mmio return _conf_value; } - Base_address(Genode::addr_t base) : Mmio(base) { } + Base_address(Genode::Byte_range_ptr const &range) : Mmio(range) { } bool valid() { return _conf() != 0; } @@ -202,7 +202,8 @@ struct Pci::Config : Genode::Mmio ** PCI Capabilities ** **********************/ - struct Pci_capability : Genode::Mmio + template + struct Pci_capability : Genode::Mmio { struct Id : Register<0,8> { @@ -223,11 +224,17 @@ struct Pci::Config : Genode::Mmio struct Pointer : Register<1,8> {}; - using Genode::Mmio::Mmio; + using Mmio::Mmio; }; - struct Power_management_capability : Pci_capability + struct Pci_capability_header : Pci_capability<0x2> + { + using Pci_capability::Pci_capability; + }; + + + struct Power_management_capability : Pci_capability<0x8> { struct Capabilities : Register<0x2, 16> {}; @@ -279,7 +286,7 @@ struct Pci::Config : Genode::Mmio }; - struct Msi_capability : Pci_capability + struct Msi_capability : Pci_capability<0xe> { struct Control : Register<0x2, 16> { @@ -315,7 +322,7 @@ struct Pci::Config : Genode::Mmio }; - struct Msi_x_capability : Pci_capability + struct Msi_x_capability : Pci_capability<0xc> { struct Control : Register<0x2, 16> { @@ -337,7 +344,7 @@ struct Pci::Config : Genode::Mmio struct Offset : Bitfield<3, 29> {}; }; - struct Table_entry : Genode::Mmio + struct Table_entry : Genode::Mmio<0x10> { enum { SIZE = 16 }; @@ -349,7 +356,7 @@ struct Pci::Config : Genode::Mmio struct Mask : Bitfield <0, 1> { }; }; - using Genode::Mmio::Mmio; + using Mmio::Mmio; }; using Pci_capability::Pci_capability; @@ -372,7 +379,7 @@ struct Pci::Config : Genode::Mmio }; - struct Pci_express_capability : Pci_capability + struct Pci_express_capability : Pci_capability<0x3c> { struct Capabilities : Register<0x2, 16> {}; @@ -484,7 +491,8 @@ struct Pci::Config : Genode::Mmio enum { PCI_E_EXTENDED_CAPS_OFFSET = 0x100U }; - struct Pci_express_extended_capability : Genode::Mmio + template + struct Pci_express_extended_capability : Genode::Mmio { struct Id : Register<0x0, 16> { @@ -504,11 +512,17 @@ struct Pci::Config : Genode::Mmio struct Offset : Bitfield<4, 12> {}; }; - using Genode::Mmio::Mmio; + using Mmio::Mmio; }; - struct Advanced_error_reporting_capability : Pci_express_extended_capability + struct Pci_express_extended_capability_header : Pci_express_extended_capability<0x4> + { + using Pci_express_extended_capability::Pci_express_extended_capability; + }; + + + struct Advanced_error_reporting_capability : Pci_express_extended_capability<0x34> { struct Uncorrectable_error_status : Register<0x4, 32> {}; struct Correctable_error_status : Register<0x10, 32> {}; @@ -547,8 +561,8 @@ struct Pci::Config : Genode::Mmio Genode::Constructible pci_e_cap {}; Genode::Constructible adv_err_cap {}; - Base_address bar0 { base() + BASE_ADDRESS_0 }; - Base_address bar1 { base() + BASE_ADDRESS_0 + 0x4 }; + Base_address bar0 { Mmio::range_at(BASE_ADDRESS_0) }; + Base_address bar1 { Mmio::range_at(BASE_ADDRESS_0 + 0x4) }; void clear_errors() { if (adv_err_cap.constructed()) adv_err_cap->clear(); } @@ -562,21 +576,22 @@ struct Pci::Config : Genode::Mmio uint16_t off = read(); while (off) { - Pci_capability cap(base() + off); - switch(cap.read()) { - case Pci_capability::Id::POWER_MANAGEMENT: - power_cap.construct(base()+off); break; - case Pci_capability::Id::MSI: - msi_cap.construct(base()+off); break; - case Pci_capability::Id::MSI_X: - msi_x_cap.construct(base()+off); break; - case Pci_capability::Id::PCI_E: - pci_e_cap.construct(base()+off); break; + using Capability_header = Pci_capability_header; + Capability_header cap(Mmio::range_at(off)); + switch(cap.read()) { + case Capability_header::Id::POWER_MANAGEMENT: + power_cap.construct(Mmio::range_at(off)); break; + case Capability_header::Id::MSI: + msi_cap.construct(Mmio::range_at(off)); break; + case Capability_header::Id::MSI_X: + msi_x_cap.construct(Mmio::range_at(off)); break; + case Capability_header::Id::PCI_E: + pci_e_cap.construct(Mmio::range_at(off)); break; default: /* ignore unhandled capability */ ; } - off = cap.read(); + off = cap.read(); } if (!pci_e_cap.constructed()) @@ -584,21 +599,22 @@ struct Pci::Config : Genode::Mmio off = PCI_E_EXTENDED_CAPS_OFFSET; while (off) { - Pci_express_extended_capability cap(base() + off); - switch (cap.read()) { - case Pci_express_extended_capability::Id::INVALID: + using Capability_header = Pci_express_extended_capability_header; + Capability_header cap(Mmio::range_at(off)); + switch (cap.read()) { + case Capability_header::Id::INVALID: return; - case Pci_express_extended_capability::Id::ADVANCED_ERROR_REPORTING: - adv_err_cap.construct(base() + off); break; + case Capability_header::Id::ADVANCED_ERROR_REPORTING: + adv_err_cap.construct(Mmio::range_at(off)); break; default: /* ignore unhandled extended capability */ ; } - off = cap.read(); + off = cap.read(); } } - using Genode::Mmio::Mmio; + using Mmio::Mmio; bool valid() { return read() != Vendor::INVALID; } @@ -612,13 +628,12 @@ struct Pci::Config : Genode::Mmio template void for_each_bar(MEM_FN const & memory, IO_FN const & io) { - Genode::addr_t const reg_addr = base() + BASE_ADDRESS_0; Genode::size_t const reg_cnt = (read()) ? BASE_ADDRESS_COUNT_TYPE_1 : BASE_ADDRESS_COUNT_TYPE_0; for (unsigned i = 0; i < reg_cnt; i++) { - Base_address reg0(reg_addr + i*0x4); + Base_address reg0 { Mmio::range_at(BASE_ADDRESS_0 + i*0x4) }; if (!reg0.valid()) continue; if (reg0.memory()) { @@ -634,7 +649,7 @@ struct Pci::Config : Genode::Mmio if (idx > 5 || (idx > 1 && bridge())) return; - Base_address bar { base() + BASE_ADDRESS_0 + idx*0x4 }; + Base_address bar { Mmio::range_at(BASE_ADDRESS_0 + idx*0x4) }; bar.set(addr); } @@ -660,10 +675,10 @@ struct Pci::Config_type0 : Pci::Config using Pci::Config::Config; - Base_address bar2 { base() + BASE_ADDRESS_0 + 0x8 }; - Base_address bar3 { base() + BASE_ADDRESS_0 + 0xc }; - Base_address bar4 { base() + BASE_ADDRESS_0 + 0x10 }; - Base_address bar5 { base() + BASE_ADDRESS_0 + 0x14 }; + Base_address bar2 { Mmio::range_at(BASE_ADDRESS_0 + 0x8 ) }; + Base_address bar3 { Mmio::range_at(BASE_ADDRESS_0 + 0xc ) }; + Base_address bar4 { Mmio::range_at(BASE_ADDRESS_0 + 0x10) }; + Base_address bar5 { Mmio::range_at(BASE_ADDRESS_0 + 0x14) }; struct Subsystem_vendor : Register<0x2c, 16> { }; struct Subsystem_device : Register<0x2e, 16> { }; diff --git a/repos/os/include/platform_session/device.h b/repos/os/include/platform_session/device.h index 4906f99956..42ae748454 100644 --- a/repos/os/include/platform_session/device.h +++ b/repos/os/include/platform_session/device.h @@ -28,7 +28,7 @@ class Platform::Device : Interface, Noncopyable { public: - struct Mmio; + template struct Mmio; struct Irq; struct Io_port_range; @@ -38,8 +38,6 @@ class Platform::Device : Interface, Noncopyable typedef Device_interface::Range Range; - friend class Mmio; - ::Platform::Connection &_platform; Capability _cap; @@ -86,7 +84,8 @@ class Platform::Device : Interface, Noncopyable }; -class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio +template +class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio { private: @@ -108,7 +107,7 @@ class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio Mmio(Device &device, Index index) : Attached_dataspace(device._rm(), _ds_cap(device, index.value)), - Genode::Mmio(_local_addr()) + Genode::Mmio({(char *)_local_addr(), size()}) { } explicit Mmio(Device &device) : Mmio(device, Index { 0 }) { } diff --git a/repos/os/include/virtio/mmio_device.h b/repos/os/include/virtio/mmio_device.h index 25c1ce78cf..18f2f63ff6 100644 --- a/repos/os/include/virtio/mmio_device.h +++ b/repos/os/include/virtio/mmio_device.h @@ -25,7 +25,7 @@ namespace Virtio { } -class Virtio::Device : Platform::Device::Mmio +class Virtio::Device : Platform::Device::Mmio<0x200> { public: @@ -102,7 +102,7 @@ class Virtio::Device : Platform::Device::Mmio Device(Platform::Device & device) : - Platform::Device::Mmio(device), _irq(device, {0}) + Platform::Device::Mmio(device), _irq(device, {0}) { if (read() != VIRTIO_MMIO_MAGIC) { throw Invalid_device(); } diff --git a/repos/os/include/virtio/pci_device.h b/repos/os/include/virtio/pci_device.h index bfa54e2273..889b2ffb3a 100644 --- a/repos/os/include/virtio/pci_device.h +++ b/repos/os/include/virtio/pci_device.h @@ -23,7 +23,7 @@ namespace Virtio { class Device; } -struct Virtio::Device_mmio : public Genode::Mmio +struct Virtio::Device_mmio : public Genode::Mmio<0x100> { struct DeviceFeatureSelect : Register<0x00, 32> { }; struct DeviceFeature : Register<0x04, 32> { }; @@ -96,13 +96,13 @@ class Virtio::Device Platform::Device _device { _plat }; Platform::Device::Irq _irq { _device, { 0 } }; - Constructible _mmio[MMIO_MAX] { }; + Constructible > _mmio[MMIO_MAX] { }; - Mmio _cfg_common { _bar_offset("common") }; - Mmio _dev_config { _bar_offset("device") }; - Mmio _notify { _bar_offset("notify") }; - Mmio _isr { _bar_offset("irq_status") }; - size_t _notify_offset_multiplier { 0 }; + Device_mmio _cfg_common { _bar_range("common") }; + Device_mmio _dev_config { _bar_range("device") }; + Device_mmio _notify { _bar_range("notify") }; + Device_mmio _isr { _bar_range("irq_status") }; + size_t _notify_offset_multiplier { 0 }; template void with_virtio_range(String<16> type, FN const & fn) @@ -123,7 +123,7 @@ class Virtio::Device }); } - addr_t _bar_offset(String<16> type) + Byte_range_ptr _bar_range(String<16> type) { unsigned idx = MMIO_MAX; addr_t off = ~0UL; @@ -137,8 +137,8 @@ class Virtio::Device if (!_mmio[idx].constructed()) _mmio[idx].construct(_device, - Platform::Device::Mmio::Index{idx}); - return _mmio[idx]->base() + off; + Platform::Device::Mmio<0>::Index{idx}); + return _mmio[idx]->range_at(off); } public: diff --git a/repos/os/src/app/pci_decode/main.cc b/repos/os/src/app/pci_decode/main.cc index a94a1846de..3ab186d3f6 100644 --- a/repos/os/src/app/pci_decode/main.cc +++ b/repos/os/src/app/pci_decode/main.cc @@ -56,7 +56,7 @@ struct Main bus_t parse_pci_function(Bdf bdf, Config & cfg, addr_t cfg_phys_base, Xml_generator & generator, unsigned & msi); - bus_t parse_pci_bus(bus_t bus, addr_t base, addr_t phys_base, + bus_t parse_pci_bus(bus_t bus, Byte_range_ptr const & range, addr_t phys_base, Xml_generator & generator, unsigned & msi); void parse_irq_override_rules(Xml_node & xml); @@ -94,7 +94,7 @@ bus_t Main::parse_pci_function(Bdf bdf, /* check for bridges */ if (cfg.read()) { for_bridge(bdf.bus, [&] (Bridge & parent) { - Config_type1 bcfg(cfg.base()); + Config_type1 bcfg(cfg.range()); new (heap) Bridge(parent.sub_bridges, bdf, bcfg.secondary_bus_number(), bcfg.subordinate_bus_number()); @@ -142,7 +142,7 @@ bus_t Main::parse_pci_function(Bdf bdf, gen.attribute("revision", string(cfg.read())); gen.attribute("bridge", cfg.bridge() ? "yes" : "no"); if (!cfg.bridge()) { - C0 cfg0(cfg.base()); + C0 cfg0(cfg.range()); gen.attribute("sub_vendor_id", string(cfg0.read())); gen.attribute("sub_device_id", @@ -286,17 +286,17 @@ bus_t Main::parse_pci_function(Bdf bdf, } -bus_t Main::parse_pci_bus(bus_t bus, - addr_t base, - addr_t phys_base, - Xml_generator & generator, - unsigned & msi_number) +bus_t Main::parse_pci_bus(bus_t bus, + Byte_range_ptr const & range, + addr_t phys_base, + Xml_generator & generator, + unsigned & msi_number) { bus_t max_subordinate_bus = bus; - auto per_function = [&] (addr_t config_base, addr_t config_phys_base, + auto per_function = [&] (Byte_range_ptr const & config_range, addr_t config_phys_base, dev_t dev, func_t fn) { - Config cfg(config_base); + Config cfg(config_range); if (!cfg.valid()) return true; @@ -312,10 +312,10 @@ bus_t Main::parse_pci_bus(bus_t bus, for (dev_t dev = 0; dev < DEVICES_PER_BUS_MAX; dev++) { for (func_t fn = 0; fn < FUNCTION_PER_DEVICE_MAX; fn++) { unsigned factor = dev * FUNCTION_PER_DEVICE_MAX + fn; - addr_t config_base = base + factor * FUNCTION_CONFIG_SPACE_SIZE; - addr_t config_phys_base = - phys_base + factor * FUNCTION_CONFIG_SPACE_SIZE; - if (!per_function(config_base, config_phys_base, dev, fn)) + off_t config_offset = factor * FUNCTION_CONFIG_SPACE_SIZE; + Byte_range_ptr config_range { range.start + config_offset, range.num_bytes - config_offset }; + addr_t config_phys_base = phys_base + config_offset; + if (!per_function(config_range, config_phys_base, dev, fn)) break; } } @@ -504,7 +504,7 @@ void Main::parse_pci_config_spaces(Xml_node & xml, Xml_generator & generator) pci_config_ds.construct(env, offset, BUS_SIZE); bus_t const subordinate_bus = parse_pci_bus((bus_t)bus + bus_off, - (addr_t)pci_config_ds->local_addr(), + {pci_config_ds->local_addr(), BUS_SIZE}, offset, generator, msi_number); max_subordinate_bus = max(max_subordinate_bus, subordinate_bus); diff --git a/repos/os/src/drivers/acpi/acpi.cc b/repos/os/src/drivers/acpi/acpi.cc index 9c64b3bb8a..d0c0283a98 100644 --- a/repos/os/src/drivers/acpi/acpi.cc +++ b/repos/os/src/drivers/acpi/acpi.cc @@ -115,13 +115,13 @@ struct Generic } __attribute__((packed)); -struct Dmar_common : Genode::Mmio +struct Dmar_common : Genode::Mmio<0x4> { struct Type : Register<0x0, 16> { enum { DRHD= 0U, RMRR = 0x1U, ATSR = 0x2U, RHSA = 0x3U }; }; struct Length : Register<0x2, 16> { }; - Dmar_common(addr_t mmio) : Genode::Mmio(mmio) { } + Dmar_common(Byte_range_ptr const &range) : Mmio(range) { } }; @@ -143,7 +143,7 @@ struct Dmar_struct_header : Generic { addr_t addr = dmar_entry_start(); while (addr < dmar_entry_end()) { - Dmar_common dmar(addr); + Dmar_common dmar({(char *)addr, dmar_entry_end() - addr}); func(dmar); @@ -163,38 +163,43 @@ struct Dmar_struct_header : Generic /* Intel VT-d IO Spec - 8.3.1. */ -struct Device_scope : Genode::Mmio +struct Device_scope : Genode::Mmio<0x6> { - enum { MAX_PATHS = 4 }; - - Device_scope(addr_t a) : Genode::Mmio(a) { } + Device_scope(Byte_range_ptr const &range) : Mmio(range) { } struct Type : Register<0x0, 8> { enum { PCI_END_POINT = 0x1 }; }; struct Length : Register<0x1, 8> { }; struct Bus : Register<0x5, 8> { }; - struct Path : Register_array<0x6, 8, MAX_PATHS, 16> { - struct Dev : Bitfield<0,8> { }; - struct Func : Bitfield<8,8> { }; + struct Path : Genode::Mmio<0x2> + { + Path(Byte_range_ptr const &range) : Mmio(range) { } + + struct Dev : Register<0, 8> { }; + struct Func : Register<1, 8> { }; + + uint8_t dev() const { return read(); } + uint8_t func() const { return read(); } }; - unsigned count() const { - unsigned const length = read(); - if (length < 6) - return 0; + void for_each_path(auto const &fn) const + { + auto const length = read(); - unsigned paths = (read() - 6) / 2; - if (paths > MAX_PATHS) { - Genode::error("Device_scope: more paths (", paths, ") than" - " supported (", (int)MAX_PATHS,")"); - return MAX_PATHS; + unsigned offset = Device_scope::SIZE; + + while (offset < length) { + Path const path(Mmio::range_at(offset)); + + fn(path); + + offset += Path::SIZE; } - return paths; } }; /* DMA Remapping Hardware Definition - Intel VT-d IO Spec - 8.3. */ -struct Dmar_drhd : Genode::Mmio +struct Dmar_drhd : Genode::Mmio<0x10> { struct Length : Register<0x2, 16> { }; struct Flags : Register<0x4, 8> { }; @@ -203,52 +208,52 @@ struct Dmar_drhd : Genode::Mmio struct Segment : Register<0x6, 16> { }; struct Phys : Register<0x8, 64> { }; - Dmar_drhd(addr_t a) : Genode::Mmio(a) { } + Dmar_drhd(Byte_range_ptr const &range) : Mmio(range) { } template void apply(FUNC const &func = [] () { } ) { - addr_t addr = base() + 16; - while (addr < base() + read()) { - Device_scope scope(addr); + off_t offset = 16; + while (offset < read()) { + Device_scope scope(Mmio::range_at(offset)); func(scope); - addr = scope.base() + scope.read(); + offset += scope.read(); } } }; /* DMA Remapping Reporting structure - Intel VT-d IO Spec - 8.3. */ -struct Dmar_rmrr : Genode::Mmio +struct Dmar_rmrr : Genode::Mmio<0x18> { struct Length : Register<0x02, 16> { }; struct Base : Register<0x08, 64> { }; struct Limit : Register<0x10, 64> { }; - Dmar_rmrr(addr_t a) : Genode::Mmio(a) { } + Dmar_rmrr(Byte_range_ptr const &range) : Mmio(range) { } template void apply(FUNC const &func = [] () { } ) { - addr_t addr = base() + 24; - while (addr < base() + read()) { - Device_scope scope(addr); + addr_t offset = 24; + while (offset < read()) { + Device_scope scope(Mmio::range_at(offset)); func(scope); - addr = scope.base() + scope.read(); + offset += scope.read(); } } }; /* I/O Virtualization Definition Blocks for AMD IO-MMU */ -struct Ivdb : Genode::Mmio +struct Ivdb : Genode::Mmio<0x4> { struct Type : Register<0x00, 8> { }; struct Length : Register<0x02, 16> { }; - Ivdb(addr_t const addr) : Genode::Mmio(addr) { } + Ivdb(Byte_range_ptr const &range) : Mmio(range) { } }; @@ -275,7 +280,7 @@ struct Ivdb_entry : public List::Element /* I/O Virtualization Reporting Structure (IVRS) for AMD IO-MMU */ -struct Ivrs : Genode::Mmio +struct Ivrs : Genode::Mmio<0x28> { struct Length : Register<0x04, 32> { }; struct Ivinfo : Register<0x24, 32> { @@ -284,37 +289,33 @@ struct Ivrs : Genode::Mmio static constexpr unsigned min_size() { return 0x30; } - Ivrs(addr_t const table) : Genode::Mmio(table) { } + Ivrs(Byte_range_ptr const &range) : Mmio(range) { } void parse(Allocator &alloc) { - addr_t addr = base() + 0x30; - while (addr < base() + read()) { + uint32_t offset = 0x30; + while (offset < read()) { bool dmar = Ivinfo::Dmar::get(read()); if (dmar) Genode::warning("Predefined regions should be added to IOMMU"); - Ivdb ivdb(addr); + Ivdb ivdb(Mmio::range_at(offset)); uint32_t const type = ivdb.read(); uint32_t const size = ivdb.read(); Ivdb_entry::list()->insert(new (&alloc) Ivdb_entry(type)); - addr += size; + offset += size; } } }; -/* Fixed ACPI description table (FADT) */ -struct Fadt : Genode::Mmio + +struct Fadt_reset : Genode::Mmio<0x88> { - size_t const size; + Fadt_reset(Byte_range_ptr const &range) : Mmio(range) { } - Fadt(addr_t mmio, size_t size) : Genode::Mmio(mmio), size(size) { } - - struct Dsdt : Register<0x28, 32> { }; - struct Sci_int : Register<0x2e, 16> { }; struct Features : Register<0x70, 32> { /* Table 5-35 Fixed ACPI Description Table Fixed Feature Flags */ struct Reset : Bitfield<10, 1> { }; @@ -328,25 +329,31 @@ struct Fadt : Genode::Mmio struct Reset_reg : Register<0x78, 64> { }; struct Reset_value : Register<0x80, 8> { }; - bool dsdt_valid() { - return size >= Dsdt::OFFSET + Dsdt::ACCESS_WIDTH / 8; } + uint16_t io_port_reset() const { return read() & 0xffffu; } + uint8_t reset_value() const { return read(); } +}; - bool sci_int_valid() { - return size >= Sci_int::OFFSET + Sci_int::ACCESS_WIDTH / 8; } - bool io_reset_supported() +/* Fixed ACPI description table (FADT) */ +struct Fadt : Genode::Mmio<0x30> +{ + Fadt(Byte_range_ptr const &range) : Mmio(range) { } + + struct Dsdt : Register<0x28, 32> { }; + struct Sci_int : Register<0x2e, 16> { }; + + void detect_io_reset(auto const &range, auto const &fn) const { - if (size < Reset_value::OFFSET + Reset_value::ACCESS_WIDTH / 8) - return false; + if (range.num_bytes < Fadt_reset::SIZE) + return; - if (!read()) - return false; + Fadt_reset const reset(range); - if (read() == Reset_type::Address_space::SYSTEM_IO) - return true; + if (!read()) + return; - warning("unsupported reset mode ", read()); - return false; + if (read() == Fadt_reset::Reset_type::Address_space::SYSTEM_IO) + fn(reset); } }; @@ -421,16 +428,16 @@ class Pci_config_space : public List::Element return &_list; } - struct Config_space : Mmio + struct Config_space : Mmio<0x100> { struct Vendor : Register<0x00, 16> { enum { INTEL = 0x8086 }; }; struct Class : Register<0x0b, 8> { enum { DISPLAY = 0x3 }; }; struct Asls : Register<0xfc, 32> { }; - Config_space(addr_t mmio) : Mmio(mmio) { } + Config_space(Byte_range_ptr const &range) : Mmio(range) { } }; - struct Opregion : Mmio + struct Opregion : Mmio<0x3c6> { struct Minor : Register<0x16, 8> { }; struct Major : Register<0x17, 8> { }; @@ -441,7 +448,7 @@ class Pci_config_space : public List::Element struct Asle_rvda : Register<0x3ba, 64> { }; struct Asle_rvds : Register<0x3c2, 32> { }; - Opregion(addr_t mmio) : Mmio(mmio) { } + Opregion(Byte_range_ptr const &range) : Mmio(range) { } }; static void intel_opregion(Env &env) @@ -459,7 +466,7 @@ class Pci_config_space : public List::Element Attached_io_mem_dataspace pci_config(env, e->_base + config_offset * config_size, config_size); - Config_space device((addr_t)pci_config.local_addr()); + Config_space device({pci_config.local_addr(), config_size}); if ((device.read() != Config_space::Vendor::INTEL) || (device.read() != Config_space::Class::DISPLAY)) @@ -477,7 +484,7 @@ class Pci_config_space : public List::Element { Attached_io_mem_dataspace map_asls(env, phys_asls, asls_size); - Opregion opregion((addr_t)map_asls.local_addr()); + Opregion opregion({map_asls.local_addr(), asls_size}); auto const rvda = opregion.read(); auto const rvds = opregion.read(); @@ -1426,27 +1433,25 @@ class Acpi_table if (table.is_ivrs() && Ivrs::min_size() <= table->size) { log("Found IVRS"); - Ivrs ivrs(reinterpret_cast(table->signature)); + Ivrs ivrs({(char *)table->signature, table->size}); ivrs.parse(_heap); } - if (table.is_facp()) { - Fadt fadt(reinterpret_cast(table->signature), table->size); + if (table.is_facp() && (Fadt::SIZE <= table->size)) { + Byte_range_ptr const range((char *)table->signature, + table->size); - if (fadt.dsdt_valid()) - dsdt = fadt.read(); + Fadt fadt(range); - if (fadt.io_reset_supported()) { - uint16_t const reset_io_port = fadt.read() & 0xffffu; - uint8_t const reset_value = fadt.read(); + dsdt = fadt.read(); - _reset_info.construct(Reset_info { .io_port = reset_io_port, - .value = reset_value }); - } - if (fadt.sci_int_valid()) { - _sci_int = fadt.read(); - _sci_int_valid = true; - } + _sci_int = fadt.read(); + _sci_int_valid = true; + + fadt.detect_io_reset(range, [&](auto const &reset) { + _reset_info.construct(Reset_info { .io_port = reset.io_port_reset(), + .value = reset.reset_value() }); + }); } if (table.is_searched()) { @@ -1651,20 +1656,16 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc, /* lambda definition for scope evaluation in rmrr */ auto func_scope = [&] (Device_scope const &scope) { - if (!scope.count()) - return; - xml.node("scope", [&] () { xml.attribute("bus_start", scope.read()); xml.attribute("type", scope.read()); - for (unsigned j = 0 ; j < scope.count(); j++) { + + scope.for_each_path([&](auto const &path) { xml.node("path", [&] () { - attribute_hex(xml, "dev", - scope.read(j)); - attribute_hex(xml, "func", - scope.read(j)); + attribute_hex(xml, "dev" , path.dev()); + attribute_hex(xml, "func", path.func()); }); - } + }); }); }; @@ -1676,7 +1677,7 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc, if (!ignore_drhd && dmar.read() == Dmar_common::Type::DRHD) { - Dmar_drhd drhd(dmar.base()); + Dmar_drhd drhd(dmar.range()); size_t size_log2 = drhd.read() + 12; @@ -1692,7 +1693,7 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc, if (dmar.read() != Dmar_common::Type::RMRR) return; - Dmar_rmrr rmrr(dmar.base()); + Dmar_rmrr rmrr(dmar.range()); xml.node("rmrr", [&] () { attribute_hex(xml, "start", rmrr.read()); diff --git a/repos/os/src/drivers/ahci/ahci.h b/repos/os/src/drivers/ahci/ahci.h index 58772d1571..83cf4d5155 100644 --- a/repos/os/src/drivers/ahci/ahci.h +++ b/repos/os/src/drivers/ahci/ahci.h @@ -31,7 +31,8 @@ namespace Ahci { struct Protocol; struct Port; - struct Port_base; + template struct Port_base_tpl; + using Port_base = Port_base_tpl<0x28>; struct Hba; using Response = Block::Request_stream::Response; @@ -42,10 +43,10 @@ namespace Ahci { /** * HBA definitions */ -struct Ahci::Hba : private Platform::Device::Mmio +struct Ahci::Hba : private Platform::Device::Mmio<0x28> { - using Platform::Device::Mmio::base; - using Index = Platform::Device::Mmio::Index; + using Platform::Device::Mmio::base; + using Index = Platform::Device::Mmio::Index; Platform::Device::Irq _irq; @@ -85,7 +86,7 @@ struct Ahci::Hba : private Platform::Device::Mmio Signal_context_capability cap, Platform::Connection & platform) : - Platform::Device::Mmio(dev, _mmio_index(platform)), + Platform::Device::Mmio(dev, _mmio_index(platform)), _irq(dev) { log("version: " @@ -144,6 +145,8 @@ struct Ahci::Hba : private Platform::Device::Mmio /** * Ports implemented + * + * Each bit set here corresponds to a port that can be accessed by software */ struct Pi : Register<0xc, 32> { }; @@ -176,6 +179,8 @@ struct Ahci::Hba : private Platform::Device::Mmio /* clear status register */ ack_irq(); } + + Byte_range_ptr range_at(off_t offset) const { return Platform::Device::Mmio::range_at(offset); } }; @@ -185,7 +190,7 @@ struct Ahci::Hba : private Platform::Device::Mmio namespace Ahci { - struct Device_fis : Mmio + struct Device_fis : Mmio<0x4> { struct Status : Register<0x2, 8> { @@ -194,12 +199,12 @@ namespace Ahci { }; struct Error : Register<0x3, 8> { }; - Device_fis(addr_t recv_base) - : Mmio(recv_base + 0x40) { } + Device_fis(Byte_range_ptr const &recv_range) + : Mmio({recv_range.start + 0x40, recv_range.num_bytes - 0x40}) { } }; - struct Command_fis : Mmio + struct Command_fis : Mmio<0xe> { struct Type : Register<0x0, 8> { }; /* FIS type */ struct Bits : Register<0x1, 8, 1> @@ -236,8 +241,8 @@ namespace Ahci { struct Sector8_15 : Register<0xd, 8> { }; struct Sector : Bitset_2 { }; /* sector count */ - Command_fis(addr_t base) - : Mmio(base) + Command_fis(Byte_range_ptr const &range) + : Mmio(range) { clear(); @@ -310,7 +315,7 @@ namespace Ahci { /** * AHCI command list structure header */ - struct Command_header : Mmio + struct Command_header : Mmio<0x10> { struct Bits : Register<0x0, 16> { @@ -326,7 +331,7 @@ namespace Ahci { struct Ctba0 : Register<0x8, 32> { }; /* command table base addr (low) */ struct Ctba0_u0 : Register<0xc, 32> { }; /* command table base addr (upper) */ - Command_header(addr_t base) : Mmio(base) { } + using Mmio::Mmio; void cmd_table_base(addr_t base_phys) { @@ -354,7 +359,7 @@ namespace Ahci { /** * ATAPI packet 12 or 16 bytes */ - struct Atapi_command : Mmio + struct Atapi_command : Mmio<0xa> { struct Command : Register<0, 8> { }; @@ -372,9 +377,9 @@ namespace Ahci { struct Sector : Bitset_2 { }; - Atapi_command(addr_t base) : Mmio(base) + Atapi_command(Byte_range_ptr const &range) : Mmio(range) { - memset((void *)base, 0, 16); + memset((void *)base(), 0, 16); } void read_capacity() @@ -410,7 +415,7 @@ namespace Ahci { /** * Physical region descritpor table */ - struct Prdt : Mmio + struct Prdt : Mmio<0x10> { struct Dba : Register<0x0, 32> { }; /* data base address */ struct Dbau : Register<0x4, 32> { }; /* data base address upper 32 bits */ @@ -421,8 +426,8 @@ namespace Ahci { struct Irq : Bitfield<31,1> { }; /* interrupt completion */ }; - Prdt(addr_t base, addr_t phys, size_t bytes) - : Mmio(base) + Prdt(Byte_range_ptr const &range, addr_t phys, size_t bytes) + : Mmio(range) { uint64_t addr = phys; write((uint32_t)addr); @@ -442,11 +447,14 @@ namespace Ahci { /* in Genode we only need one PRD (for one packet) */ Prdt prdt; - Command_table(addr_t base, + enum { ATAPI_CMD_OFF = 0x40 }; + enum { PRDT_OFF = 0x80 }; + + Command_table(Byte_range_ptr const &range, addr_t phys, size_t bytes = 0) - : fis(base), atapi_cmd(base + 0x40), - prdt(base + 0x80, phys, bytes) + : fis(range), atapi_cmd({range.start + ATAPI_CMD_OFF, range.num_bytes - ATAPI_CMD_OFF}), + prdt({range.start + PRDT_OFF, range.num_bytes - PRDT_OFF}, phys, bytes) { } static constexpr size_t size() { return 0x100; } @@ -456,8 +464,11 @@ namespace Ahci { /** * Minimalistic AHCI port structure to merely detect device signature */ -struct Ahci::Port_base : Mmio +template +struct Ahci::Port_base_tpl : Mmio { + using Base = Mmio; + /* device signature */ enum Signature { ATA_SIG = 0x101, @@ -468,31 +479,26 @@ struct Ahci::Port_base : Mmio unsigned index { }; Platform::Connection &plat; Hba &hba; - Mmio::Delayer &delayer; + Base::Delayer &delayer; /** * Port signature */ - struct Sig : Register<0x24, 32> { }; + struct Sig : Base::template Register<0x24, 32> { }; static constexpr addr_t offset() { return 0x100; } static constexpr size_t size() { return 0x80; } - Port_base(unsigned index, Platform::Connection &plat, Hba &hba, - Mmio::Delayer &delayer) - : Mmio(hba.base() + offset() + (index * size())), + Port_base_tpl(unsigned index, Platform::Connection &plat, Hba &hba, + Base::Delayer &delayer) + : Base(hba.range_at(offset() + (index * size()))), index(index), plat(plat), hba(hba), delayer(delayer) { } - bool implemented() const - { - return hba.port_implemented(index); - } - - bool ata() const { return read() == ATA_SIG; } + bool ata() const { return Base::template read() == ATA_SIG; } bool atapi() const { - unsigned sig = read(); + unsigned sig = Base::template read(); return sig == ATAPI_SIG || sig == ATAPI_SIG_QEMU; } }; @@ -513,17 +519,17 @@ struct Ahci::Protocol : Interface /** * AHCI port */ -struct Ahci::Port : private Port_base +struct Ahci::Port : private Port_base_tpl<0x3c> { - using Port_base::write; - using Port_base::read; - using Port_base::wait_for_any; - using Port_base::wait_for; - using Port_base::Register_set::Polling_timeout; - using Port_base::index; - using Port_base::hba; - using Port_base::delayer; - using Port_base::plat; + using Port_base_tpl::write; + using Port_base_tpl::read; + using Port_base_tpl::wait_for_any; + using Port_base_tpl::wait_for; + using Port_base_tpl::Register_set::Polling_timeout; + using Port_base_tpl::index; + using Port_base_tpl::hba; + using Port_base_tpl::delayer; + using Port_base_tpl::plat; struct Not_ready : Exception { }; @@ -538,10 +544,10 @@ struct Ahci::Port : private Port_base addr_t device_info_dma_addr = 0; - addr_t cmd_list = 0; - addr_t fis_base = 0; - addr_t cmd_table = 0; - addr_t device_info = 0; + Constructible cmd_list { }; + Constructible fis { }; + Constructible cmd_table { }; + Constructible device_info { }; Constructible dma_buffer { }; addr_t dma_base = 0; /* physical address of DMA memory */ @@ -549,7 +555,7 @@ struct Ahci::Port : private Port_base Port(Protocol &protocol, Region_map &rm, Platform::Connection & plat, Hba &hba, Mmio::Delayer &delayer, unsigned index) : - Port_base(index, plat, hba, delayer), + Port_base_tpl(index, plat, hba, delayer), protocol(protocol), rm(rm) { reset(); @@ -871,11 +877,12 @@ struct Ahci::Port : private Port_base { /* command list 1K */ addr_t phys = device_dma.dma_addr(); - cmd_list = addr_t(device_dma.local_addr()); + cmd_list.construct(device_dma.local_addr(), device_dma.size()); command_list_base(phys); /* receive FIS base 256 byte */ - fis_base = cmd_list + 1024; + enum { FIS_OFF = 1024 }; + fis.construct(cmd_list->start + FIS_OFF, cmd_list->num_bytes - FIS_OFF); /* * Set fis receive base, clear Fre (FIS receive) before and wait for FR @@ -886,28 +893,31 @@ struct Ahci::Port : private Port_base fis_rcv_base(phys + 1024); /* command table */ - cmd_table = addr_t(cmd_dma.local_addr()); + cmd_table.construct(cmd_dma.local_addr(), cmd_dma.size()); phys = cmd_dma.dma_addr(); /* set command table addresses in command list */ for (unsigned i = 0; i < cmd_slots; i++) { - Command_header h(cmd_list + (i * Command_header::size())); + off_t off = (i * Command_header::size()); + Command_header h({cmd_list->start + off, cmd_list->num_bytes - off}); h.cmd_table_base(phys + (i * Command_table::size())); } /* dataspace for device info */ device_info_dma_addr = device_info_dma.dma_addr(); - device_info = addr_t(device_info_dma.local_addr()); + device_info.construct(device_info_dma.local_addr(), device_info_dma.size()); } - addr_t command_table_addr(unsigned slot) + Byte_range_ptr command_table_range(unsigned slot) { - return cmd_table + (slot * Command_table::size()); + off_t off = slot * Command_table::size(); + return {cmd_table->start + off, cmd_table->num_bytes - off}; }; - addr_t command_header_addr(unsigned slot) + Byte_range_ptr command_header_range(unsigned slot) { - return cmd_list + (slot * Command_header::size()); + off_t off = slot * Command_header::size(); + return {cmd_list->start + off, cmd_list->num_bytes - off}; } void execute(unsigned slot) diff --git a/repos/os/src/drivers/ahci/ata_protocol.h b/repos/os/src/drivers/ahci/ata_protocol.h index 88fb85424c..50fa501938 100644 --- a/repos/os/src/drivers/ahci/ata_protocol.h +++ b/repos/os/src/drivers/ahci/ata_protocol.h @@ -29,9 +29,9 @@ namespace Ata { /** * Return data of 'identify_device' ATA command */ -struct Ata::Identity : Mmio +struct Ata::Identity : Mmio<0x1a4> { - Identity(addr_t base) : Mmio(base) { } + using Mmio::Mmio; struct Serial_number : Register_array<0x14, 8, 20, 8> { }; struct Model_number : Register_array<0x36, 8, 40, 8> { }; @@ -222,7 +222,7 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable unsigned init(Port &port) override { /* identify device */ - Command_table table(port.command_table_addr(0), + Command_table table(port.command_table_range(0), port.device_info_dma_addr, 0x1000); table.fis.identify_device(); port.execute(0); @@ -231,7 +231,7 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable Port::Is::Pss::Equal(1), Port::Is::Dhrs::Equal(1)); - _identity.construct(port.device_info); + _identity.construct(*port.device_info); serial.construct(*_identity); model.construct(*_identity); @@ -316,7 +316,7 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable _slot_states |= 1u << slot; /* setup fis */ - Command_table table(port.command_table_addr(slot), + Command_table table(port.command_table_range(slot), port.dma_base + request.offset, /* physical address */ op.count * _block_size()); @@ -335,7 +335,7 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable } /* set or clear write flag in command header */ - Command_header header(port.command_header_addr(slot)); + Command_header header(port.command_header_range(slot)); header.write(write ? 1 : 0); header.clear_byte_count(); diff --git a/repos/os/src/drivers/ahci/atapi_protocol.h b/repos/os/src/drivers/ahci/atapi_protocol.h index e1cb346da1..3a88c32cbb 100644 --- a/repos/os/src/drivers/ahci/atapi_protocol.h +++ b/repos/os/src/drivers/ahci/atapi_protocol.h @@ -33,7 +33,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable void _atapi_command(Port &port) { - Command_header header(port.command_header_addr(0)); + Command_header header(port.command_header_range(0)); header.atapi_command(); header.clear_byte_count(); port.execute(0); @@ -41,7 +41,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable void _read_sense(Port &port) { - Command_table table(port.command_table_addr(0), + Command_table table(port.command_table_range(0), port.device_info_dma_addr, 0x1000); table.fis.atapi(); table.atapi_cmd.read_sense(); @@ -51,7 +51,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable void _test_unit_ready(Port &port) { - Command_table table(port.command_table_addr(0), 0, 0); + Command_table table(port.command_table_range(0), 0, 0); table.fis.atapi(); table.atapi_cmd.test_unit_ready(); @@ -60,7 +60,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable void _read_capacity(Port &port) { - Command_table table(port.command_table_addr(0), + Command_table table(port.command_table_range(0), port.device_info_dma_addr, 0x1000); table.fis.atapi(); table.fis.byte_count(~0); @@ -72,7 +72,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable void _start_unit(Port &port) { - Command_table table(port.command_table_addr(0), 0, 0); + Command_table table(port.command_table_range(0), 0, 0); table.fis.atapi(); table.atapi_cmd.start_unit(); @@ -110,7 +110,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable port.wait_for(port.delayer, Port::Is::Dhrs::Equal(1)); port.ack_irq(); - Device_fis f(port.fis_base); + Device_fis f(*port.fis); /* check if devic is ready */ if (!f.read() || f.read()) throw Port::Polling_timeout(); @@ -121,8 +121,8 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable Port::Is::Dhrs::Equal(1)); port.ack_irq(); - _block_count = host_to_big_endian(((unsigned *)port.device_info)[0]) + 1; - _block_size = host_to_big_endian(((unsigned *)port.device_info)[1]); + _block_count = host_to_big_endian(((unsigned *)port.device_info->start)[0]) + 1; + _block_size = host_to_big_endian(((unsigned *)port.device_info->start)[1]); }, [&] {}, 3); @@ -158,7 +158,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable _pending.success = false; /* setup fis */ - Command_table table(port.command_table_addr(0), + Command_table table(port.command_table_range(0), port.dma_base + request.offset, op.count * _block_size); table.fis.atapi(); @@ -168,7 +168,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable table.fis.byte_count(~0); /* set and clear write flag in command header */ - Command_header header(port.command_header_addr(0)); + Command_header header(port.command_header_range(0)); header.write(0); header.clear_byte_count(); diff --git a/repos/os/src/drivers/ahci/main.cc b/repos/os/src/drivers/ahci/main.cc index ce95442bdd..eb6d6f6749 100644 --- a/repos/os/src/drivers/ahci/main.cc +++ b/repos/os/src/drivers/ahci/main.cc @@ -53,7 +53,7 @@ class Ahci::Driver : Noncopyable Dispatch &_dispatch; - struct Timer_delayer : Mmio::Delayer, Timer::Connection + struct Timer_delayer : Mmio<0>::Delayer, Timer::Connection { using Timer::Connection::Connection; @@ -78,11 +78,11 @@ class Ahci::Driver : Noncopyable for (unsigned index = 0; index < MAX_PORTS; index++) { - Port_base port(index, _plat, _hba, _delayer); - - if (port.implemented() == false) + if (_hba.port_implemented(index) == false) continue; + Port_base port(index, _plat, _hba, _delayer); + bool enabled = false; if (port.ata()) { try { diff --git a/repos/os/src/drivers/framebuffer/pl11x/main.cc b/repos/os/src/drivers/framebuffer/pl11x/main.cc index 4f0b2e5a06..dd6bbfd349 100644 --- a/repos/os/src/drivers/framebuffer/pl11x/main.cc +++ b/repos/os/src/drivers/framebuffer/pl11x/main.cc @@ -86,12 +86,12 @@ struct Pl11x_driver::Main using Type = Platform::Device::Type; - Platform::Connection _platform { _env }; - Platform::Device _pl11x_dev { _platform, Type { "arm,pl111" } }; - Platform::Device _sp810_dev { _platform, Type { "arm,sp810" } }; - Platform::Device::Mmio _lcd_io_mem { _pl11x_dev }; - Platform::Device::Mmio _sys_mem { _sp810_dev }; - Platform::Dma_buffer _fb_dma { _platform, FRAMEBUFFER_SIZE, UNCACHED }; + Platform::Connection _platform { _env }; + Platform::Device _pl11x_dev { _platform, Type { "arm,pl111" } }; + Platform::Device _sp810_dev { _platform, Type { "arm,sp810" } }; + Platform::Device::Mmio<0> _lcd_io_mem { _pl11x_dev }; + Platform::Device::Mmio<0> _sys_mem { _sp810_dev }; + Platform::Dma_buffer _fb_dma { _platform, FRAMEBUFFER_SIZE, UNCACHED }; void _init_device(); diff --git a/repos/os/src/drivers/framebuffer/ram/main.cc b/repos/os/src/drivers/framebuffer/ram/main.cc index f0db5be48e..8d4d0c2425 100644 --- a/repos/os/src/drivers/framebuffer/ram/main.cc +++ b/repos/os/src/drivers/framebuffer/ram/main.cc @@ -37,16 +37,14 @@ class Main ** Qemu firmware interface ** *****************************/ - struct Fw : Mmio + struct Fw : Mmio<0x18> { template struct Data : Register<0x0, sizeof(T) * 8> { }; struct Selector : Register<0x8, 16> { }; struct Dma : Register<0x10, 64> { }; - Fw(addr_t const base) - : - Mmio(base) { } + Fw(Byte_range_ptr const &range) : Mmio(range) { } }; Env &_env; @@ -57,10 +55,10 @@ class Main using Type = Platform::Device::Type; - Platform::Connection _platform { _env }; - Platform::Device _fw_dev { _platform, Type { "qemu,fw-cfg-mmio" } }; - Platform::Device::Mmio _fw_mem { _fw_dev }; - Fw _fw { (addr_t)_fw_mem.local_addr() }; + Platform::Connection _platform { _env }; + Platform::Device _fw_dev { _platform, Type { "qemu,fw-cfg-mmio" } }; + Platform::Device::Mmio<0> _fw_mem { _fw_dev }; + Fw _fw { {_fw_mem.local_addr(), _fw_mem.size()} }; Platform::Dma_buffer _fb_dma { _platform, SCR_HEIGHT * SCR_STRIDE, UNCACHED }; Platform::Dma_buffer _config_dma { _platform, 0x1000, UNCACHED }; @@ -91,15 +89,13 @@ class Main return host_to_big_endian(_fw.read>()); } /* DMA control structure */ - struct Fw_dma_config : Genode::Mmio + struct Fw_dma_config : Genode::Mmio<0x10> { struct Control : Register<0x0, 32> { }; struct Length : Register<0x4, 32> { }; struct Address : Register<0x8, 64> { }; - Fw_dma_config(addr_t const base) - : - Mmio(base) + Fw_dma_config(Byte_range_ptr const &range) : Mmio(range) { /* set write bit */ write(host_to_big_endian(1u << 4)); @@ -116,7 +112,7 @@ class Main }; /* ramfb configuration */ - struct Ram_fb_config : Genode::Mmio + struct Ram_fb_config : Genode::Mmio<0x1c> { struct Address : Register<0x0, 64> { }; struct Drm_format : Register<0x8, 32> { }; @@ -124,17 +120,15 @@ class Main struct Height : Register<0x14, 32> { }; struct Stride : Register<0x18, 32> { }; - Ram_fb_config(addr_t const base) - : - Mmio(base) - { - enum { - DRM_FORMAT_ARGB8888 = 0x34325241, - }; - /* RGBA32 */ - write(host_to_big_endian(DRM_FORMAT_ARGB8888)); - write(host_to_big_endian(SCR_STRIDE)); - } + Ram_fb_config(Byte_range_ptr const &range) : Mmio(range) + { + enum { + DRM_FORMAT_ARGB8888 = 0x34325241, + }; + /* RGBA32 */ + write(host_to_big_endian(DRM_FORMAT_ARGB8888)); + write(host_to_big_endian(SCR_STRIDE)); + } }; Fw_config_file _find_ramfb() @@ -173,12 +167,12 @@ class Main addr_t config_phys = _config_dma.dma_addr(); addr_t fb_phys = _fb_dma.dma_addr(); - Ram_fb_config config { config_addr }; + Ram_fb_config config { {(char *)config_addr, _config_dma.size()} }; config.write(host_to_big_endian(fb_phys)); config.write(host_to_big_endian(SCR_WIDTH)); config.write(host_to_big_endian(SCR_HEIGHT)); - Fw_dma_config fw_dma { config_addr + FW_OFFSET}; + Fw_dma_config fw_dma { {(char *)config_addr + FW_OFFSET, _config_dma.size() - FW_OFFSET} }; fw_dma.write(host_to_big_endian(file.size)); fw_dma.write(host_to_big_endian(config_phys)); diff --git a/repos/os/src/drivers/gpio/rpi/gpio.h b/repos/os/src/drivers/gpio/rpi/gpio.h index 0834fb61d8..f04f3747e7 100644 --- a/repos/os/src/drivers/gpio/rpi/gpio.h +++ b/repos/os/src/drivers/gpio/rpi/gpio.h @@ -29,7 +29,7 @@ namespace Gpio { class Reg; } -class Gpio::Reg : Attached_io_mem_dataspace, Mmio +class Gpio::Reg : Attached_io_mem_dataspace, Mmio<0xa0> { private: @@ -139,7 +139,7 @@ class Gpio::Reg : Attached_io_mem_dataspace, Mmio addr_t base, off_t offset, size_t size) : Attached_io_mem_dataspace(env, base, size), - Mmio((addr_t)local_addr() + offset), + Mmio({local_addr() + offset, size - offset}), _delayer(env) { } diff --git a/repos/os/src/drivers/gpu/intel/context.h b/repos/os/src/drivers/gpu/intel/context.h index 35531bb0d8..5fd5b64397 100644 --- a/repos/os/src/drivers/gpu/intel/context.h +++ b/repos/os/src/drivers/gpu/intel/context.h @@ -25,9 +25,11 @@ namespace Igd { + using Genode::Byte_range_ptr; + struct Context_status_qword; - struct Common_context_regs; + template struct Common_context_regs; struct Generation; @@ -84,27 +86,30 @@ struct Igd::Context_status_qword : Genode::Register<64> }; -struct Igd::Common_context_regs : public Genode::Mmio +template +struct Igd::Common_context_regs : public Genode::Mmio { + using Base = Genode::Mmio; + template - struct Common_register : Register { }; + struct Common_register : Base::template Register { }; template - struct Common_register_array : Register_array { }; + struct Common_register_array : Base::template Register_array { }; template - struct Common_register_array_64 : Register_array { }; + struct Common_register_array_64 : Base::template Register_array { }; - addr_t _base; + Byte_range_ptr _range; - Common_context_regs(addr_t base) : Genode::Mmio(base), _base(base) { } + Common_context_regs(Byte_range_ptr const &range) : Genode::Mmio(range), _range(range.start, range.num_bytes) { } - addr_t base() const { return _base; } + addr_t base() const { return (addr_t)_range.start; } template void write_offset(typename T::access_t const value) { - write(value + T::OFFSET); + Base::template write(value + T::OFFSET); } }; @@ -118,7 +123,7 @@ struct Igd::Common_context_regs : public Genode::Mmio * All engines use the same layout until offset 0x118. */ template -class Igd::Execlist_context : public Igd::Common_context_regs +class Igd::Execlist_context : public Igd::Common_context_regs<0x1E * sizeof(uint32_t) + 2 * 4> { public: @@ -360,7 +365,7 @@ class Igd::Execlist_context : public Igd::Common_context_regs public: - Execlist_context(addr_t const base) : Common_context_regs(base) { } + Execlist_context(Byte_range_ptr const &range) : Common_context_regs(range) { } void setup(addr_t const ring_buffer_start, size_t const ring_buffer_length, @@ -461,7 +466,7 @@ class Igd::Execlist_context : public Igd::Common_context_regs template -class Igd::Ppgtt_context : public Igd::Common_context_regs +class Igd::Ppgtt_context : public Igd::Common_context_regs<0x47 * sizeof(uint32_t) + 9 * 4> { public: @@ -596,7 +601,7 @@ class Igd::Ppgtt_context : public Igd::Common_context_regs public: - Ppgtt_context(addr_t const base) : Common_context_regs(base) { } + Ppgtt_context(Byte_range_ptr const &range) : Common_context_regs(range) { } void setup(uint64_t const plm4_addr) { @@ -678,7 +683,7 @@ class Igd::Urb_atomic_context /* * IHD-OS-BDW-Vol 2d-11.15 p. 199 */ -class Igd::Hardware_status_page : public Igd::Common_context_regs +class Igd::Hardware_status_page : public Igd::Common_context_regs<0x32*4 + 4> { public: @@ -708,8 +713,8 @@ class Igd::Hardware_status_page : public Igd::Common_context_regs struct Context_status_dwords : Common_register_array_64<16, CONTEXT_STATUS_REGISTERS> { }; struct Last_written_status_offset : Common_register<31> { }; - Hardware_status_page(addr_t base) - : Common_context_regs(base) + Hardware_status_page(Byte_range_ptr const &range) + : Common_context_regs(range) { semaphore(0); } @@ -784,14 +789,14 @@ class Igd::Hardware_status_page : public Igd::Common_context_regs /* * IHD-OS-BDW-Vol 2d-11.15 p. 303 */ -class Igd::Pphardware_status_page : public Igd::Common_context_regs +class Igd::Pphardware_status_page : public Igd::Common_context_regs<4 * 4 + 4> { public: struct Ring_head_ptr_storage : Common_register<4> { }; - Pphardware_status_page(addr_t base) - : Common_context_regs(base) { } + Pphardware_status_page(Byte_range_ptr const &range) + : Common_context_regs(range) { } }; @@ -848,11 +853,11 @@ class Igd::Rcs_context public: - Rcs_context(addr_t const map_base) + Rcs_context(Byte_range_ptr const &map_range) : - _hw_status_page (map_base), - _execlist_context(map_base + HW_STATUS_PAGE_SIZE), - _ppgtt_context (map_base + HW_STATUS_PAGE_SIZE) + _hw_status_page (map_range), + _execlist_context({map_range.start + HW_STATUS_PAGE_SIZE, map_range.num_bytes - HW_STATUS_PAGE_SIZE}), + _ppgtt_context ({map_range.start + HW_STATUS_PAGE_SIZE, map_range.num_bytes - HW_STATUS_PAGE_SIZE}) { } void setup(addr_t const ring_buffer_start, diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 9584609542..3ca522aaf2 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -440,12 +440,12 @@ struct Igd::Device return offset; } - void with_vaddr(auto const &fn) const + void with_vrange(auto const &fn) const { addr_t const offset = (map.map.offset + skip) * PAGE_SIZE; - if (!device._resources.with_gmadr(offset, [&](auto const addr) { - fn(addr); + if (!device._resources.with_gmadr(offset, [&](Byte_range_ptr const &range) { + fn(range); })) error("Gmadr object unavailable"); } @@ -484,8 +484,8 @@ struct Igd::Device void with_context(auto const &fn) { - ctx.with_vaddr([&](auto const vaddr) { - auto context = CONTEXT(vaddr); + ctx.with_vrange([&](Byte_range_ptr const &vrange) { + auto context = CONTEXT(vrange); fn(context); }); @@ -493,8 +493,8 @@ struct Igd::Device void with_context_ring(auto const &fn) { - ctx.with_vaddr([&](auto const vaddr) { - auto context = CONTEXT(vaddr); + ctx.with_vrange([&](Byte_range_ptr const &vrange) { + auto context = CONTEXT(vrange); fn(context, _ring); }); @@ -1247,9 +1247,9 @@ struct Igd::Device if (!_hw_status_ctx.constructed()) _hw_status_ctx.construct(_md_alloc, *this, 1, 0); if (!_hw_status_page.constructed()) { - /* global hw_status_ctx becomes never invalid up to now, so using vaddr is ok */ - _hw_status_ctx->with_vaddr([&](auto const vaddr) { - _hw_status_page.construct(vaddr); + /* global hw_status_ctx becomes never invalid up to now, so using vrange is ok */ + _hw_status_ctx->with_vrange([&](Byte_range_ptr const &vrange) { + _hw_status_page.construct(vrange); }); } diff --git a/repos/os/src/drivers/gpu/intel/mmio.h b/repos/os/src/drivers/gpu/intel/mmio.h index 8f1304fc1f..b36bb20757 100644 --- a/repos/os/src/drivers/gpu/intel/mmio.h +++ b/repos/os/src/drivers/gpu/intel/mmio.h @@ -23,10 +23,15 @@ #include -namespace Igd { class Mmio; } +namespace Igd { + + static constexpr size_t MMIO_SIZE = 0x190074; + + class Mmio; +} -class Igd::Mmio : public Platform::Device::Mmio +class Igd::Mmio : public Platform::Device::Mmio { public: @@ -1137,7 +1142,7 @@ class Igd::Mmio : public Platform::Device::Mmio private: - struct Timer_delayer : Genode::Mmio::Delayer + struct Timer_delayer : Genode::Mmio::Delayer { Timer::Connection _timer; Timer_delayer(Genode::Env & env) : _timer(env) { } @@ -1666,7 +1671,7 @@ class Igd::Mmio : public Platform::Device::Mmio public: Mmio(Platform::Device & device, Genode::Env & env) - : Platform::Device::Mmio(device, {0}), _delayer(env) { } + : Platform::Device::Mmio(device, {0}), _delayer(env) { } Delayer &delayer() { return _delayer; } diff --git a/repos/os/src/drivers/gpu/intel/platform_session.h b/repos/os/src/drivers/gpu/intel/platform_session.h index 69b7ba518d..e469843973 100644 --- a/repos/os/src/drivers/gpu/intel/platform_session.h +++ b/repos/os/src/drivers/gpu/intel/platform_session.h @@ -284,15 +284,14 @@ class Platform::Resources : Noncopyable { private: - Env & _env; - Signal_context_capability const _irq_cap; - Platform::Connection _platform { _env }; - - Reconstructible _device { _platform }; - Reconstructible _irq { *_device }; - Reconstructible _mmio { *_device, _env }; - Reconstructible _gmadr { *_device, Platform::Device::Mmio::Index(1) }; - Reconstructible _gmadr_mem { _env.rm(), _gmadr->cap() }; + Env & _env; + Signal_context_capability const _irq_cap; + Platform::Connection _platform { _env }; + Reconstructible _device { _platform }; + Reconstructible _irq { *_device }; + Reconstructible _mmio { *_device, _env }; + Reconstructible > _gmadr { *_device, Platform::Device::Mmio<0>::Index(1) }; + Reconstructible _gmadr_mem { _env.rm(), _gmadr->cap() }; Region_map_client _rm_gttmm; Region_map_client _rm_gmadr; @@ -384,13 +383,10 @@ class Platform::Resources : Noncopyable __attribute__((warn_unused_result)) bool with_gmadr(auto const offset, auto const &fn) { - if (!_gmadr_mem.constructed()) + if (!_gmadr.constructed() || !_gmadr_mem.constructed()) return false; - auto const addr = reinterpret_cast(_gmadr_mem->local_addr()) - + offset; - fn(addr); - + fn({_gmadr_mem->local_addr() + offset, _gmadr->size() - offset }); return true; } diff --git a/repos/os/src/drivers/gpu/intel/ring_buffer.h b/repos/os/src/drivers/gpu/intel/ring_buffer.h index bdd59eaee5..853481c314 100644 --- a/repos/os/src/drivers/gpu/intel/ring_buffer.h +++ b/repos/os/src/drivers/gpu/intel/ring_buffer.h @@ -45,10 +45,10 @@ class Igd::Ring_buffer Index _head { }; void with_dwords(auto const &fn) const { - _memory.with_vaddr([&](auto vaddr) { fn((uint32_t *)vaddr); }); } + _memory.with_vrange([&](Byte_range_ptr const &vrange) { fn((uint32_t *)vrange.start); }); } void with_dwords(auto const &fn) { - _memory.with_vaddr([&](auto vaddr) { fn((uint32_t *)vaddr); }); } + _memory.with_vrange([&](Byte_range_ptr const &vrange) { fn((uint32_t *)vrange.start); }); } public: diff --git a/repos/os/src/drivers/i2c/imx8q_evk/mmio.h b/repos/os/src/drivers/i2c/imx8q_evk/mmio.h index b1bd254aac..a807446e51 100644 --- a/repos/os/src/drivers/i2c/imx8q_evk/mmio.h +++ b/repos/os/src/drivers/i2c/imx8q_evk/mmio.h @@ -20,7 +20,7 @@ namespace I2c { struct Mmio; } -struct I2c::Mmio: Platform::Device::Mmio +struct I2c::Mmio: Platform::Device::Mmio<0x12> { struct Address : Mmio::Register<0x0, 16> { struct Adr : Mmio::Register<0x0, 16>::Bitfield<1, 7> {}; @@ -49,7 +49,7 @@ struct I2c::Mmio: Platform::Device::Mmio struct Data : Mmio::Register<0x10, 16> {}; - Mmio(Platform::Device &device) : Platform::Device::Mmio { device } { } + Mmio(Platform::Device &device) : Platform::Device::Mmio { device } { } }; #endif /* _I2C_MMIO_H_ */ diff --git a/repos/os/src/drivers/nic/lan9118/lan9118.h b/repos/os/src/drivers/nic/lan9118/lan9118.h index f33de25a6c..2c72510ac7 100644 --- a/repos/os/src/drivers/nic/lan9118/lan9118.h +++ b/repos/os/src/drivers/nic/lan9118/lan9118.h @@ -94,7 +94,7 @@ class Lan9118_base { } }; - Platform::Device::Mmio &_mmio; + Platform::Device::Mmio<0> &_mmio; Platform::Device::Irq &_irq; volatile uint32_t *_reg_base { _mmio.local_addr() }; Timer::Connection _timer; @@ -281,10 +281,10 @@ class Lan9118_base */ class Device_not_supported { }; - Lan9118_base(Platform::Device::Mmio &mmio, - Platform::Device::Irq &irq, - Signal_context_capability irq_handler, - Env &env) + Lan9118_base(Platform::Device::Mmio<0> &mmio, + Platform::Device::Irq &irq, + Signal_context_capability irq_handler, + Env &env) : _mmio(mmio), _irq(irq), _timer(env) { @@ -441,10 +441,10 @@ class Uplink_client : public Signal_handler, public: - Uplink_client(Env &env, - Allocator &alloc, - Platform::Device::Mmio &mmio, - Platform::Device::Irq &irq) + Uplink_client(Env &env, + Allocator &alloc, + Platform::Device::Mmio<0> &mmio, + Platform::Device::Irq &irq) : Signal_handler { env.ep(), *this, &Uplink_client::_handle_irq }, Lan9118_base { mmio, irq, *this, env }, diff --git a/repos/os/src/drivers/nic/lan9118/main.cc b/repos/os/src/drivers/nic/lan9118/main.cc index aff2ed4c2d..00bb63353e 100644 --- a/repos/os/src/drivers/nic/lan9118/main.cc +++ b/repos/os/src/drivers/nic/lan9118/main.cc @@ -31,13 +31,13 @@ class Main { private: - Env &_env; - Heap _heap { _env.ram(), _env.rm() }; - Platform::Connection _platform { _env }; - Platform::Device _device { _platform }; - Platform::Device::Mmio _mmio { _device }; - Platform::Device::Irq _irq { _device }; - Uplink_client _uplink_client { _env, _heap, _mmio, _irq }; + Env &_env; + Heap _heap { _env.ram(), _env.rm() }; + Platform::Connection _platform { _env }; + Platform::Device _device { _platform }; + Platform::Device::Mmio<0> _mmio { _device }; + Platform::Device::Irq _irq { _device }; + Uplink_client _uplink_client { _env, _heap, _mmio, _irq }; public: diff --git a/repos/os/src/drivers/nvme/main.cc b/repos/os/src/drivers/nvme/main.cc index 282ff6f609..ba8d1f134b 100644 --- a/repos/os/src/drivers/nvme/main.cc +++ b/repos/os/src/drivers/nvme/main.cc @@ -59,12 +59,13 @@ namespace Nvme { struct Cqe; - struct Sqe; + template struct Sqe; + struct Sqe_header; struct Sqe_create_cq; struct Sqe_create_sq; struct Sqe_identify; struct Sqe_get_feature; - struct Sqe_set_feature; + template struct Sqe_set_feature; struct Sqe_io; struct Set_hmb; @@ -165,7 +166,7 @@ namespace Nvme { /* * Identify command data */ -struct Nvme::Identify_data : Genode::Mmio +struct Nvme::Identify_data : Genode::Mmio<0x208> { enum { SN_OFFSET = 0x04, SN_LEN = 20, @@ -202,10 +203,9 @@ struct Nvme::Identify_data : Genode::Mmio struct Nn : Register<0x204, 32> { }; /* number of namespaces */ struct Vwc : Register<0x204, 8> { }; /* volatile write cache */ - Identify_data(addr_t const base) - : Genode::Mmio(base) + Identify_data(Byte_range_ptr const &range) : Mmio(range) { - char const *p = (char const*)base; + char const *p = Mmio::range().start; sn = Sn(Util::extract_string(p, SN_OFFSET, SN_LEN+1)); mn = Mn(Util::extract_string(p, MN_OFFSET, MN_LEN+1)); @@ -217,7 +217,7 @@ struct Nvme::Identify_data : Genode::Mmio /* * Identify name space command data */ -struct Nvme::Identify_ns_data : public Genode::Mmio +struct Nvme::Identify_ns_data : public Genode::Mmio<0xc0> { struct Nsze : Register<0x00, 64> { }; /* name space size */ struct Ncap : Register<0x08, 64> { }; /* name space capacity */ @@ -242,16 +242,14 @@ struct Nvme::Identify_ns_data : public Genode::Mmio struct Rp : Bitfield<24, 2> { }; /* relative performance */ }; - Identify_ns_data(addr_t const base) - : Genode::Mmio(base) - { } + Identify_ns_data(Byte_range_ptr const &range) : Mmio(range) { } }; /* * Queue doorbell register */ -struct Nvme::Doorbell : public Genode::Mmio +struct Nvme::Doorbell : public Genode::Mmio<0x8> { struct Sqtdbl : Register<0x00, 32> { @@ -263,15 +261,14 @@ struct Nvme::Doorbell : public Genode::Mmio struct Cqh : Bitfield< 0, 16> { }; /* submission queue tail */ }; - Doorbell(addr_t const base) - : Genode::Mmio(base) { } + Doorbell(Byte_range_ptr const &range) : Mmio(range) { } }; /* * Completion queue entry */ -struct Nvme::Cqe : Genode::Mmio +struct Nvme::Cqe : Genode::Mmio<0x10> { struct Dw0 : Register<0x00, 32> { }; /* command specific */ struct Dw1 : Register<0x04, 32> { }; /* reserved */ @@ -288,7 +285,7 @@ struct Nvme::Cqe : Genode::Mmio struct Dnr : Bitfield<15, 1> { }; /* do not retry */ }; - Cqe(addr_t const base) : Genode::Mmio(base) { } + Cqe(Byte_range_ptr const &range) : Mmio(range) { } static uint32_t request_id(Nvme::Cqe const &b) { @@ -324,46 +321,53 @@ struct Nvme::Cqe : Genode::Mmio /* * Submission queue entry base */ -struct Nvme::Sqe : Genode::Mmio +template +struct Nvme::Sqe : Genode::Mmio { - struct Cdw0 : Register<0x00, 32> + using Base = Genode::Mmio; + + using Cdw0_base = Base::template Register<0x00, 32>; + struct Cdw0 : Cdw0_base { - struct Opc : Bitfield< 0, 8> { }; /* opcode */ - struct Fuse : Bitfield< 9, 2> { }; /* fused operation */ - struct Psdt : Bitfield<14, 2> { }; /* PRP or SGL for data transfer */ - struct Cid : Bitfield<16, 16> { }; /* command identifier */ + struct Opc : Cdw0_base::template Bitfield< 0, 8> { }; /* opcode */ + struct Fuse : Cdw0_base::template Bitfield< 9, 2> { }; /* fused operation */ + struct Psdt : Cdw0_base::template Bitfield<14, 2> { }; /* PRP or SGL for data transfer */ + struct Cid : Cdw0_base::template Bitfield<16, 16> { }; /* command identifier */ }; - struct Nsid : Register<0x04, 32> { }; - struct Mptr : Register<0x10, 64> { }; - struct Prp1 : Register<0x18, 64> { }; - struct Prp2 : Register<0x20, 64> { }; + struct Nsid : Base::template Register<0x04, 32> { }; + struct Mptr : Base::template Register<0x10, 64> { }; + struct Prp1 : Base::template Register<0x18, 64> { }; + struct Prp2 : Base::template Register<0x20, 64> { }; /* SGL not supported */ - Sqe(addr_t const base) : Genode::Mmio(base) { } + Sqe(Byte_range_ptr const &range) : Mmio(range) { } - bool valid() const { return base() != 0ul; } + bool valid() const { return Base::base() != 0ul; } }; +struct Nvme::Sqe_header : Nvme::Sqe<0x28> { using Sqe::Sqe; }; + + /* * Identify command */ -struct Nvme::Sqe_identify : Nvme::Sqe +struct Nvme::Sqe_identify : Nvme::Sqe<0x2c> { struct Cdw10 : Register<0x28, 32> { struct Cns : Bitfield< 0, 8> { }; /* controller or namespace structure */ }; - Sqe_identify(addr_t const base) : Sqe(base) { } + Sqe_identify(Byte_range_ptr const &range) : Sqe(range) { } }; /* * Get feature command */ -struct Nvme::Sqe_get_feature : Nvme::Sqe +struct Nvme::Sqe_get_feature : Nvme::Sqe<0x2c> { struct Cdw10 : Register<0x28, 32> { @@ -371,33 +375,37 @@ struct Nvme::Sqe_get_feature : Nvme::Sqe struct Sel : Bitfield< 8, 2> { }; /* select which value is returned */ }; - Sqe_get_feature(addr_t const base) : Sqe(base) { } + Sqe_get_feature(Byte_range_ptr const &range) : Sqe(range) { } }; /* * Set feature command */ -struct Nvme::Sqe_set_feature : Nvme::Sqe +template +struct Nvme::Sqe_set_feature : Nvme::Sqe { - struct Cdw10 : Register<0x28, 32> + using Base = Genode::Mmio; + + using Cdw10_base = Base::template Register<0x28, 32>; + struct Cdw10 : Cdw10_base { - struct Fid : Bitfield< 0, 8> { }; /* feature identifier */ - struct Sv : Bitfield<31, 1> { }; /* save */ + struct Fid : Cdw10_base::template Bitfield< 0, 8> { }; /* feature identifier */ + struct Sv : Cdw10_base::template Bitfield<31, 1> { }; /* save */ }; - Sqe_set_feature(addr_t const base) : Sqe(base) { } + Sqe_set_feature(Byte_range_ptr const &range) : Sqe(range) { } }; -struct Hmb_de : Genode::Mmio +struct Hmb_de : Genode::Mmio<0x10> { enum { SIZE = 16u }; struct Badd : Register<0x00, 64> { }; struct Bsize : Register<0x08, 64> { }; - Hmb_de(addr_t const base, addr_t const buffer, size_t units) : Genode::Mmio(base) + Hmb_de(Byte_range_ptr const &range, addr_t const buffer, size_t units) : Mmio(range) { write(buffer); write(units); @@ -405,7 +413,7 @@ struct Hmb_de : Genode::Mmio }; -struct Nvme::Set_hmb : Nvme::Sqe_set_feature +struct Nvme::Set_hmb : Nvme::Sqe_set_feature<0x40> { struct Cdw11 : Register<0x2c, 32> { @@ -434,10 +442,10 @@ struct Nvme::Set_hmb : Nvme::Sqe_set_feature struct Hmdlec : Bitfield<0, 32> { }; /* host memory descriptor list entry count */ }; - Set_hmb(addr_t const base, uint64_t const hmdl, + Set_hmb(Byte_range_ptr const &range, uint64_t const hmdl, uint32_t const units, uint32_t const entries) : - Sqe_set_feature(base) + Sqe_set_feature(range) { write(Feature_fid::HMB); write(1); @@ -452,7 +460,7 @@ struct Nvme::Set_hmb : Nvme::Sqe_set_feature /* * Create completion queue command */ -struct Nvme::Sqe_create_cq : Nvme::Sqe +struct Nvme::Sqe_create_cq : Nvme::Sqe<0x30> { struct Cdw10 : Register<0x28, 32> { @@ -467,14 +475,14 @@ struct Nvme::Sqe_create_cq : Nvme::Sqe struct Iv : Bitfield<16, 16> { }; /* interrupt vector */ }; - Sqe_create_cq(addr_t const base) : Sqe(base) { } + Sqe_create_cq(Byte_range_ptr const &range) : Sqe(range) { } }; /* * Create submission queue command */ -struct Nvme::Sqe_create_sq : Nvme::Sqe +struct Nvme::Sqe_create_sq : Nvme::Sqe<0x30> { struct Cdw10 : Register<0x28, 32> { @@ -489,14 +497,14 @@ struct Nvme::Sqe_create_sq : Nvme::Sqe struct Cqid : Bitfield<16, 16> { }; /* completion queue identifier */ }; - Sqe_create_sq(addr_t const base) : Sqe(base) { } + Sqe_create_sq(Byte_range_ptr const &range) : Sqe(range) { } }; /* * I/O command */ -struct Nvme::Sqe_io : Nvme::Sqe +struct Nvme::Sqe_io : Nvme::Sqe<0x34> { struct Slba_lower : Register<0x28, 32> { }; struct Slba_upper : Register<0x2c, 32> { }; @@ -507,7 +515,7 @@ struct Nvme::Sqe_io : Nvme::Sqe struct Nlb : Bitfield< 0, 16> { }; }; - Sqe_io(addr_t const base) : Sqe(base) { } + Sqe_io(Byte_range_ptr const &range) : Sqe(range) { } }; @@ -538,12 +546,12 @@ struct Nvme::Sq : Nvme::Queue using Queue::Queue; - addr_t next() + Byte_range_ptr next() { - addr_t a = (addr_t)local_addr() + (tail * SQE_LEN); - Genode::memset((void*)a, 0, SQE_LEN); + char *a = local_addr() + (tail * SQE_LEN); + Genode::memset(a, 0, SQE_LEN); tail = (tail + 1) % max_entries; - return a; + return {a, size()}; } }; @@ -558,7 +566,11 @@ struct Nvme::Cq : Nvme::Queue using Queue::Queue; - addr_t next() { return (addr_t)local_addr() + (head * CQE_LEN); } + Byte_range_ptr next() + { + off_t offset = head * CQE_LEN; + return {local_addr() + offset, size() - offset}; + } void advance_head() { @@ -574,10 +586,10 @@ struct Nvme::Cq : Nvme::Queue * Controller */ class Nvme::Controller : Platform::Device, - Platform::Device::Mmio, + Platform::Device::Mmio<0x1010>, Platform::Device::Irq { - using Mmio = Genode::Mmio; + using Mmio = Genode::Mmio; public: @@ -974,15 +986,15 @@ class Nvme::Controller : Platform::Device, * \return returns address of the next free entry or 0 if there is * no free entry */ - addr_t _admin_command(Opcode opc, uint32_t nsid, uint32_t cid) + Byte_range_ptr _admin_command(Opcode opc, uint32_t nsid, uint32_t cid) { - if (_queue_full(*_admin_sq, *_admin_cq)) { return 0ul; } + if (_queue_full(*_admin_sq, *_admin_cq)) { return {nullptr, 0ul}; } - Sqe b(_admin_sq->next()); - b.write(opc); - b.write(cid); - b.write(nsid); - return b.base(); + Sqe_header b(_admin_sq->next()); + b.write(opc); + b.write(cid); + b.write(nsid); + return b.range(); } /** @@ -1068,7 +1080,7 @@ class Nvme::Controller : Platform::Device, Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, NSLIST_CID)); - b.write(_nvme_nslist.dma_addr()); + b.write(_nvme_nslist.dma_addr()); b.write(Cns::NSLIST); write(_admin_sq->tail); @@ -1106,7 +1118,7 @@ class Nvme::Controller : Platform::Device, _nvme_query_ns[id].construct(_platform, IDENTIFY_LEN); Sqe_identify b(_admin_command(Opcode::IDENTIFY, ns[id], QUERYNS_CID)); - b.write(_nvme_query_ns[id]->dma_addr()); + b.write(_nvme_query_ns[id]->dma_addr()); b.write(Cns::IDENTIFY_NS); write(_admin_sq->tail); @@ -1116,7 +1128,7 @@ class Nvme::Controller : Platform::Device, throw Initialization_failed(); } - Identify_ns_data nsdata((addr_t)_nvme_query_ns[id]->local_addr()); + Identify_ns_data nsdata({_nvme_query_ns[id]->local_addr(), _nvme_query_ns[id]->size()}); uint32_t const flbas = nsdata.read(); /* use array subscription, omit first entry */ @@ -1133,7 +1145,7 @@ class Nvme::Controller : Platform::Device, void _identify() { Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, IDENTIFY_CID)); - b.write(_nvme_identify.dma_addr()); + b.write(_nvme_identify.dma_addr()); b.write(Cns::IDENTIFY); write(_admin_sq->tail); @@ -1143,7 +1155,8 @@ class Nvme::Controller : Platform::Device, throw Initialization_failed(); } - _identify_data.construct((addr_t)_nvme_identify.local_addr()); + _identify_data.construct( + Byte_range_ptr(_nvme_identify.local_addr(), _nvme_identify.size())); /* store information */ _info.version = Genode::String<8>(read(), ".", @@ -1230,17 +1243,18 @@ class Nvme::Controller : Platform::Device, _hmb_chunk_registry.construct(_hmb_alloc); - addr_t list_base = - (addr_t)_hmb_descr_list_buffer->local_addr(); + Reconstructible list + {_hmb_descr_list_buffer->local_addr(), _hmb_descr_list_buffer->size()}; + for (uint32_t i = 0; i < num_entries; i++) { try { Hmb_chunk *c = new (_hmb_alloc) Hmb_chunk(*_hmb_chunk_registry, _platform, HMB_CHUNK_SIZE); - Hmb_de e(list_base, c->dma_buffer.dma_addr(), HMB_CHUNK_UNITS); + Hmb_de e(*list, c->dma_buffer.dma_addr(), HMB_CHUNK_UNITS); + list.construct(list->start + Hmb_de::SIZE, list->num_bytes - Hmb_de::SIZE); - list_base += Hmb_de::SIZE; } catch (... /* intentional catch-all */) { warning("could not allocate HMB chunk"); @@ -1284,7 +1298,7 @@ class Nvme::Controller : Platform::Device, Nvme::Cq &cq = *_cq[id]; Sqe_create_cq b(_admin_command(Opcode::CREATE_IO_CQ, 0, CREATE_IO_CQ_CID)); - b.write(cq.dma_addr()); + b.write(cq.dma_addr()); b.write(id); b.write(_max_io_entries_mask); b.write(1); @@ -1314,7 +1328,7 @@ class Nvme::Controller : Platform::Device, Nvme::Sq &sq = *_sq[id]; Sqe_create_sq b(_admin_command(Opcode::CREATE_IO_SQ, 0, CREATE_IO_SQ_CID)); - b.write(sq.dma_addr()); + b.write(sq.dma_addr()); b.write(id); b.write(_max_io_entries_mask); b.write(1); @@ -1340,7 +1354,7 @@ class Nvme::Controller : Platform::Device, Signal_context_capability irq_sigh) : Platform::Device(platform), - Platform::Device::Mmio((Platform::Device&)*this), + Platform::Device::Mmio((Platform::Device&)*this), Platform::Device::Irq((Platform::Device&)*this), _env(env), _platform(platform), _delayer(delayer) { @@ -1419,14 +1433,14 @@ class Nvme::Controller : Platform::Device, * * \return returns virtual address of the I/O command */ - addr_t io_command(uint16_t nsid, uint16_t cid) + Byte_range_ptr io_command(uint16_t nsid, uint16_t cid) { Nvme::Sq &sq = *_sq[nsid]; - Sqe e(sq.next()); - e.write(cid); - e.write(nsid); - return e.base(); + Sqe_header e(sq.next()); + e.write(cid); + e.write(nsid); + return e.range(); } /** @@ -1755,7 +1769,7 @@ class Nvme::Driver : Genode::Noncopyable ** MMIO Controller ** *********************/ - struct Timer_delayer : Genode::Mmio::Delayer, + struct Timer_delayer : Genode::Mmio<0>::Delayer, Timer::Connection { Timer_delayer(Genode::Env &env) @@ -1985,12 +1999,12 @@ class Nvme::Driver : Genode::Noncopyable Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); Nvme::Opcode const op = write ? Nvme::Opcode::WRITE : Nvme::Opcode::READ; - b.write(op); - b.write(request_pa); + b.write(op); + b.write(request_pa); /* payload will fit into 2 mps chunks */ if (len > Nvme::MPS && !need_list) { - b.write(request_pa + Nvme::MPS); + b.write(request_pa + Nvme::MPS); } else if (need_list) { /* get page to store list of mps chunks */ @@ -2018,7 +2032,7 @@ class Nvme::Driver : Genode::Noncopyable pe[i] = npa; npa += Nvme::MPS; } - b.write(pa); + b.write(pa); } b.write(uint32_t(lba)); @@ -2035,7 +2049,7 @@ class Nvme::Driver : Genode::Noncopyable .id = id }; Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); - b.write(Nvme::Opcode::FLUSH); + b.write(Nvme::Opcode::FLUSH); } void _submit_trim(Block::Request const request) @@ -2050,7 +2064,7 @@ class Nvme::Driver : Genode::Noncopyable Block::sector_t const lba = request.operation.block_number; Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); - b.write(Nvme::Opcode::WRITE_ZEROS); + b.write(Nvme::Opcode::WRITE_ZEROS); b.write(uint32_t(lba)); b.write(uint32_t(lba >> 32u)); diff --git a/repos/os/src/drivers/platform/pci.cc b/repos/os/src/drivers/platform/pci.cc index 738b500ce9..7db4216b18 100644 --- a/repos/os/src/drivers/platform/pci.cc +++ b/repos/os/src/drivers/platform/pci.cc @@ -52,8 +52,10 @@ struct Config_helper Driver::Device const & _dev; Driver::Device::Pci_config const & _cfg; - Attached_io_mem_dataspace _io_mem { _env, _cfg.addr, 0x1000 }; - Config _config { (addr_t)_io_mem.local_addr() }; + static constexpr size_t IO_MEM_SIZE = 0x1000; + + Attached_io_mem_dataspace _io_mem { _env, _cfg.addr, IO_MEM_SIZE }; + Config _config { {_io_mem.local_addr(), IO_MEM_SIZE} }; Config_helper(Env & env, Driver::Device const & dev, @@ -125,8 +127,8 @@ struct Config_helper _config.write(cmd); /* apply different PCI quirks, bios handover etc. */ - Driver::pci_uhci_quirks(_env, _dev, _cfg, _config.base()); - Driver::pci_ehci_quirks(_env, _dev, _cfg, _config.base()); + Driver::pci_uhci_quirks(_env, _dev, _cfg, _config.range()); + Driver::pci_ehci_quirks(_env, _dev, _cfg, _config.range()); Driver::pci_hd_audio_quirks(_cfg, _config); _config.write(cmd_old); @@ -163,8 +165,10 @@ void Driver::pci_msi_enable(Env & env, Irq_session::Info const info, Irq_session::Type type) { - Attached_io_mem_dataspace io_mem { env, cfg_space, 0x1000 }; - Config config { (addr_t)io_mem.local_addr() }; + static constexpr size_t IO_MEM_SIZE = 0x1000; + + Attached_io_mem_dataspace io_mem { env, cfg_space, IO_MEM_SIZE }; + Config config { {io_mem.local_addr(), IO_MEM_SIZE} }; config.scan(); if (type == Irq_session::TYPE_MSIX && config.msi_x_cap.constructed()) { @@ -174,14 +178,15 @@ void Driver::pci_msi_enable(Env & env, unsigned idx = dc.io_mem_index({config.msi_x_cap->bar()}); Io_mem_session_client dsc(dc.io_mem(idx, range)); Attached_dataspace msix_table_ds(env.rm(), dsc.dataspace()); - addr_t msix_table_start = (addr_t)msix_table_ds.local_addr() - + config.msi_x_cap->table_offset(); + Byte_range_ptr msix_table = { + msix_table_ds.local_addr() + config.msi_x_cap->table_offset(), + msix_table_ds.size() - config.msi_x_cap->table_offset() }; /* disable all msi-x table entries beside the first one */ unsigned slots = config.msi_x_cap->slots(); for (unsigned i = 0; i < slots; i++) { using Entry = Config::Msi_x_capability::Table_entry; - Entry e (msix_table_start + Entry::SIZE * i); + Entry e ({msix_table.start + Entry::SIZE*i, msix_table.num_bytes - Entry::SIZE*i}); if (!i) { uint32_t lower = info.address & 0xfffffffc; uint32_t upper = sizeof(info.address) > 4 ? diff --git a/repos/os/src/drivers/platform/pci_ehci.h b/repos/os/src/drivers/platform/pci_ehci.h index 59b1294a9b..b5892cb745 100644 --- a/repos/os/src/drivers/platform/pci_ehci.h +++ b/repos/os/src/drivers/platform/pci_ehci.h @@ -16,14 +16,14 @@ namespace Driver { static void pci_ehci_quirks(Env &, Device const &, - Device::Pci_config const &, addr_t); + Device::Pci_config const &, Pci::Config const &); } void Driver::pci_ehci_quirks(Env & env, Device const & dev, Device::Pci_config const & cfg, - addr_t base) + Pci::Config const & pci_config) { enum { EHCI_CLASS_CODE = 0xc0320 }; @@ -31,7 +31,7 @@ void Driver::pci_ehci_quirks(Env & env, return; /* EHCI host controller register definitions */ - struct Ehci : Mmio + struct Ehci : Mmio<0x44> { struct Capability_parameters : Register<0x8, 32> { @@ -42,7 +42,7 @@ void Driver::pci_ehci_quirks(Env & env, using Mmio::Mmio; }; - struct Ehci_pci : Mmio + struct Ehci_pci : Mmio<0x64> { struct Port_wake : Register<0x62, 16> {}; @@ -50,7 +50,7 @@ void Driver::pci_ehci_quirks(Env & env, }; /* PCI extended capability for EHCI */ - struct Cap : Mmio + struct Cap : Mmio<0x8> { struct Pointer : Register<0x0, 16> { @@ -72,16 +72,18 @@ void Driver::pci_ehci_quirks(Env & env, if (!bar.valid() || bar.number != 0) return; - Ehci_pci pw(base); + Ehci_pci pw(pci_config.range()); - Attached_io_mem_dataspace iomem(env, range.start, 0x1000); - Ehci ehci((addr_t)iomem.local_addr()); + static constexpr size_t IO_MEM_SIZE = 0x1000; + + Attached_io_mem_dataspace iomem(env, range.start, IO_MEM_SIZE); + Ehci ehci({iomem.local_addr(), IO_MEM_SIZE}); addr_t offset = ehci.read(); /* iterate over EHCI extended capabilities */ while (offset) { - Cap cap(base + offset); + Cap cap(pci_config.range_at(offset)); if (cap.read() != Cap::Pointer::Id::SYNC) break; diff --git a/repos/os/src/drivers/platform/pci_hd_audio.h b/repos/os/src/drivers/platform/pci_hd_audio.h index baa72a91ef..6ec93c73ce 100644 --- a/repos/os/src/drivers/platform/pci_hd_audio.h +++ b/repos/os/src/drivers/platform/pci_hd_audio.h @@ -27,7 +27,7 @@ void Driver::pci_hd_audio_quirks(Device::Pci_config const & cfg, Pci::Config & c return; /* PCI configuration register for HDAUDIO */ - struct Hdaudio : Mmio + struct Hdaudio : Mmio<0x7a> { struct Traffic_class_select : Register<0x44, 8> {}; @@ -46,7 +46,7 @@ void Driver::pci_hd_audio_quirks(Device::Pci_config const & cfg, Pci::Config & c config.write(1); - Hdaudio audio(config.base()); + Hdaudio audio(config.range()); audio.write(0); if (cfg.vendor_id == 0x8086) diff --git a/repos/os/src/drivers/platform/pci_intel_graphics.h b/repos/os/src/drivers/platform/pci_intel_graphics.h index 6b6ff66b06..f6b9f780b8 100644 --- a/repos/os/src/drivers/platform/pci_intel_graphics.h +++ b/repos/os/src/drivers/platform/pci_intel_graphics.h @@ -91,7 +91,7 @@ void Driver::pci_intel_graphics_info(Device::Pci_config const & cfg, return; /* PCI configuration registers of host bridge */ - struct Host_bridge : Mmio + struct Host_bridge : Mmio<0x54> { struct Gen_old_gmch_control : Register<0x52, 16> {}; struct Gen_gmch_control : Register<0x50, 16> {}; @@ -105,8 +105,10 @@ void Driver::pci_intel_graphics_info(Device::Pci_config const & cfg, if (cfg.bus_num || cfg.dev_num || cfg.func_num) return; - Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000); - Host_bridge config((addr_t)io_mem.local_addr()); + static constexpr size_t IO_MEM_SIZE = 0x1000; + + Attached_io_mem_dataspace io_mem(env, cfg.addr, IO_MEM_SIZE); + Host_bridge config({io_mem.local_addr(), IO_MEM_SIZE}); unsigned gen = pci_intel_graphics_generation(cfg.device_id); uint16_t gmch = 0; diff --git a/repos/os/src/drivers/platform/pci_uhci.h b/repos/os/src/drivers/platform/pci_uhci.h index 9be2abdbd5..d895c007b2 100644 --- a/repos/os/src/drivers/platform/pci_uhci.h +++ b/repos/os/src/drivers/platform/pci_uhci.h @@ -17,14 +17,14 @@ namespace Driver { static void pci_uhci_quirks(Env &, Device const &, - Device::Pci_config const &, addr_t); + Device::Pci_config const &, Pci::Config const &); } void Driver::pci_uhci_quirks(Env & env, Device const & dev, Device::Pci_config const & cfg, - addr_t base) + Pci::Config const & pci_config) { enum { UHCI_CLASS_CODE = 0xc0300 }; @@ -32,7 +32,7 @@ void Driver::pci_uhci_quirks(Env & env, return; /* PCI configuration register for UHCI */ - struct Uhci : Mmio + struct Uhci : Mmio<0xc6> { struct Usb_legacy_support : Register<0xc0, 16> { @@ -56,7 +56,7 @@ void Driver::pci_uhci_quirks(Env & env, if (!range.size) range = r; }); Io_port_connection io_ports(env, range.addr, range.size); - Uhci config(base); + Uhci config(pci_config.range()); bool have_to_reset = false; uint16_t UHCI_CMD = range.addr; diff --git a/repos/os/src/drivers/platform/pci_virtio.h b/repos/os/src/drivers/platform/pci_virtio.h index 19c34c2d54..9d60e2dbb7 100644 --- a/repos/os/src/drivers/platform/pci_virtio.h +++ b/repos/os/src/drivers/platform/pci_virtio.h @@ -33,7 +33,7 @@ void Driver::pci_virtio_info(Device const & dev, struct Virtio : Pci::Config { - struct Capability : Pci::Config::Pci_capability + struct Capability : Pci::Config::Pci_capability<0x14> { enum { COMMON = 1, NOTIFY = 2, ISR = 3, DEVICE = 4 }; @@ -43,7 +43,7 @@ void Driver::pci_virtio_info(Device const & dev, struct Length : Register<0xc, 32> {}; struct Offset_factor : Register<0x10, 32> {}; - using Pci::Config::Pci_capability::Pci_capability; + using Pci_capability::Pci_capability; bool valid() { @@ -100,18 +100,20 @@ void Driver::pci_virtio_info(Device const & dev, uint16_t off = read(); while (off) { - Capability cap(base() + off); - if (cap.read() == - Pci_capability::Id::VENDOR && + Capability cap(Mmio::range_at(off)); + if (cap.read() == + Capability::Id::VENDOR && cap.valid()) capability(cap, dev, xml); - off = cap.read(); + off = cap.read(); } } }; - Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000); - Virtio config((addr_t)io_mem.local_addr()); + static constexpr size_t IO_MEM_SIZE = 0x1000; + + Attached_io_mem_dataspace io_mem(env, cfg.addr, IO_MEM_SIZE); + Virtio config({io_mem.local_addr(), IO_MEM_SIZE}); config.for_each_capability(dev, xml); } diff --git a/repos/os/src/drivers/ps2/pl050/main.cc b/repos/os/src/drivers/ps2/pl050/main.cc index 12c2f1a576..518c1a395b 100644 --- a/repos/os/src/drivers/ps2/pl050/main.cc +++ b/repos/os/src/drivers/ps2/pl050/main.cc @@ -42,8 +42,8 @@ struct Ps2::Main Device _device { _platform }; - Device::Mmio _mmio_keyboard { _device, { 0 } }; - Device::Mmio _mmio_mouse { _device, { 1 } }; + Device::Mmio<0> _mmio_keyboard { _device, { 0 } }; + Device::Mmio<0> _mmio_mouse { _device, { 1 } }; Device::Irq _irq_keyboard { _device, { 0 } }; Device::Irq _irq_mouse { _device, { 1 } }; diff --git a/repos/os/src/drivers/ps2/pl050/pl050.h b/repos/os/src/drivers/ps2/pl050/pl050.h index 40b7524e2e..3415dd21a7 100644 --- a/repos/os/src/drivers/ps2/pl050/pl050.h +++ b/repos/os/src/drivers/ps2/pl050/pl050.h @@ -77,7 +77,7 @@ class Pl050 public: - _Channel(Platform::Device::Mmio &mmio) + _Channel(Platform::Device::Mmio<0> &mmio) : _reg_base(mmio.local_addr()) { } @@ -119,8 +119,8 @@ class Pl050 public: - Pl050(Platform::Device::Mmio &keyboard_mmio, - Platform::Device::Mmio &mouse_mmio) + Pl050(Platform::Device::Mmio<0> &keyboard_mmio, + Platform::Device::Mmio<0> &mouse_mmio) : _kbd(keyboard_mmio), _aux(mouse_mmio) { diff --git a/repos/os/src/drivers/sd_card/imx/driver.cc b/repos/os/src/drivers/sd_card/imx/driver.cc index 6b705cf668..fefa5bc4c5 100644 --- a/repos/os/src/drivers/sd_card/imx/driver.cc +++ b/repos/os/src/drivers/sd_card/imx/driver.cc @@ -524,7 +524,7 @@ Driver::Driver(Env & env, Platform::Connection & platform) : Driver_base(env.ram()), Platform::Device(platform), - Platform::Device::Mmio(*static_cast(this)), + Platform::Device::Mmio(*static_cast(this)), _env(env), _platform(platform) { diff --git a/repos/os/src/drivers/sd_card/imx/driver.h b/repos/os/src/drivers/sd_card/imx/driver.h index d225708b59..7004b55b1b 100644 --- a/repos/os/src/drivers/sd_card/imx/driver.h +++ b/repos/os/src/drivers/sd_card/imx/driver.h @@ -27,9 +27,9 @@ namespace Sd_card { class Driver; } class Sd_card::Driver : public Driver_base, private Platform::Device, - private Platform::Device::Mmio + private Platform::Device::Mmio<0x100> { - using Mmio = Genode::Mmio; + using Mmio = Genode::Mmio; private: diff --git a/repos/os/src/drivers/sd_card/pl180/driver.cc b/repos/os/src/drivers/sd_card/pl180/driver.cc index 8e7d7bc900..1c80fa449b 100644 --- a/repos/os/src/drivers/sd_card/pl180/driver.cc +++ b/repos/os/src/drivers/sd_card/pl180/driver.cc @@ -142,7 +142,7 @@ Driver::Driver(Env &env, Platform::Connection & platform) : Block::Driver(env.ram()), Platform::Device(platform), - Platform::Device::Mmio(*this, { 0 }), + Platform::Device::Mmio(*this, { 0 }), _platform(platform), _timer(env) { diff --git a/repos/os/src/drivers/sd_card/pl180/driver.h b/repos/os/src/drivers/sd_card/pl180/driver.h index 052950519e..564876fdb5 100644 --- a/repos/os/src/drivers/sd_card/pl180/driver.h +++ b/repos/os/src/drivers/sd_card/pl180/driver.h @@ -30,7 +30,7 @@ namespace Sd_card { class Sd_card::Driver : public Block::Driver, private Platform::Device, - private Platform::Device::Mmio + private Platform::Device::Mmio<0> { private: diff --git a/repos/os/src/drivers/sd_card/sd_card.h b/repos/os/src/drivers/sd_card/sd_card.h index e3181c538b..75447741c2 100644 --- a/repos/os/src/drivers/sd_card/sd_card.h +++ b/repos/os/src/drivers/sd_card/sd_card.h @@ -114,9 +114,9 @@ namespace Sd_card { }; - struct Ext_csd : Mmio + struct Ext_csd : Mmio<0xd8> { - Ext_csd(addr_t base) : Mmio(base) { } + using Mmio::Mmio; struct Revision : Register<0xc0, 8> { }; struct Sector_count : Register<0xd4, 32> { }; diff --git a/repos/os/src/drivers/touch/synaptics_dsx/i2c.h b/repos/os/src/drivers/touch/synaptics_dsx/i2c.h index 4793092f8f..ca56879647 100644 --- a/repos/os/src/drivers/touch/synaptics_dsx/i2c.h +++ b/repos/os/src/drivers/touch/synaptics_dsx/i2c.h @@ -27,7 +27,7 @@ namespace I2c } -class I2c::I2c : Platform::Device::Mmio +class I2c::I2c : Platform::Device::Mmio<0x12> { private: @@ -112,7 +112,7 @@ class I2c::I2c : Platform::Device::Mmio public: I2c(Genode::Env & env, Platform::Device & dev) - : Platform::Device::Mmio(dev, {0}), + : Platform::Device::Mmio(dev, {0}), _irq_handler(env, dev) { write(0); diff --git a/repos/os/src/drivers/usb_block/cbw_csw.h b/repos/os/src/drivers/usb_block/cbw_csw.h index 59715cd2db..61d73affa2 100644 --- a/repos/os/src/drivers/usb_block/cbw_csw.h +++ b/repos/os/src/drivers/usb_block/cbw_csw.h @@ -34,7 +34,7 @@ using Genode::addr_t; ** USB Command Block/Status Wrapper implementation ** *****************************************************/ -struct Usb::Cbw : Genode::Mmio +struct Usb::Cbw : Genode::Mmio<0xf> { enum { LENGTH = 31 }; @@ -46,8 +46,8 @@ struct Usb::Cbw : Genode::Mmio struct Lun : Register<0xd, 8> { }; /* logical unit number */ struct Cbl : Register<0xe, 8> { }; /* command buffer length */ - Cbw(addr_t addr, uint32_t t, uint32_t d, - uint8_t f, uint8_t l, uint8_t len) : Mmio(addr) + Cbw(Byte_range_ptr const &range, uint32_t t, uint32_t d, + uint8_t f, uint8_t l, uint8_t len) : Mmio(range) { write(SIG); write(t); @@ -72,11 +72,11 @@ struct Usb::Cbw : Genode::Mmio struct Test_unit_ready : Usb::Cbw, Scsi::Test_unit_ready { - Test_unit_ready(addr_t addr, uint32_t tag, uint8_t lun) + Test_unit_ready(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun) : - Cbw(addr, tag, 0, Usb::ENDPOINT_IN, lun, + Cbw(range, tag, 0, Usb::ENDPOINT_IN, lun, Scsi::Test_unit_ready::LENGTH), - Scsi::Test_unit_ready(addr+15) + Scsi::Test_unit_ready(Cbw::range_at(15)) { if (verbose_scsi) dump(); } void dump() @@ -90,11 +90,11 @@ struct Test_unit_ready : Usb::Cbw, struct Request_sense : Usb::Cbw, Scsi::Request_sense { - Request_sense(addr_t addr, uint32_t tag, uint8_t lun) + Request_sense(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun) : - Cbw(addr, tag, Scsi::Request_sense_response::LENGTH, + Cbw(range, tag, Scsi::Request_sense_response::LENGTH, Usb::ENDPOINT_IN, lun, Scsi::Request_sense::LENGTH), - Scsi::Request_sense(addr+15) + Scsi::Request_sense(Cbw::range_at(15)) { if (verbose_scsi) dump(); } void dump() @@ -108,10 +108,10 @@ struct Request_sense : Usb::Cbw, Scsi::Request_sense struct Start_stop : Usb::Cbw, Scsi::Start_stop { - Start_stop(addr_t addr, uint32_t tag, uint8_t lun) + Start_stop(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun) : - Cbw(addr, tag, 0, Usb::ENDPOINT_IN, lun, Scsi::Start_stop::LENGTH), - Scsi::Start_stop(addr+15) + Cbw(range, tag, 0, Usb::ENDPOINT_IN, lun, Scsi::Start_stop::LENGTH), + Scsi::Start_stop(Cbw::range_at(15)) { if (verbose_scsi) dump(); } void dump() @@ -125,11 +125,11 @@ struct Start_stop : Usb::Cbw, Scsi::Start_stop struct Inquiry : Usb::Cbw, Scsi::Inquiry { - Inquiry(addr_t addr, uint32_t tag, uint8_t lun) + Inquiry(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun) : - Cbw(addr, tag, Scsi::Inquiry_response::LENGTH, + Cbw(range, tag, Scsi::Inquiry_response::LENGTH, Usb::ENDPOINT_IN, lun, Scsi::Inquiry::LENGTH), - Scsi::Inquiry(addr+15) + Scsi::Inquiry(Cbw::range_at(15)) { if (verbose_scsi) dump(); } void dump() @@ -143,11 +143,11 @@ struct Inquiry : Usb::Cbw, Scsi::Inquiry struct Read_capacity_10 : Usb::Cbw, Scsi::Read_capacity_10 { - Read_capacity_10(addr_t addr, uint32_t tag, uint8_t lun) + Read_capacity_10(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun) : - Cbw(addr, tag, Scsi::Capacity_response_10::LENGTH, + Cbw(range, tag, Scsi::Capacity_response_10::LENGTH, Usb::ENDPOINT_IN, lun, Scsi::Read_capacity_10::LENGTH), - Scsi::Read_capacity_10(addr+15) + Scsi::Read_capacity_10(Cbw::range_at(15)) { if (verbose_scsi) dump(); } void dump() @@ -161,12 +161,12 @@ struct Read_capacity_10 : Usb::Cbw, Scsi::Read_capacity_10 struct Read_10 : Usb::Cbw, Scsi::Read_10 { - Read_10(addr_t addr, uint32_t tag, uint8_t lun, + Read_10(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun, uint32_t lba, uint16_t len, uint32_t block_size) : - Cbw(addr, tag, len * block_size, + Cbw(range, tag, len * block_size, Usb::ENDPOINT_IN, lun, Scsi::Read_10::LENGTH), - Scsi::Read_10(addr+15, lba, len) + Scsi::Read_10(Cbw::range_at(15), lba, len) { if (verbose_scsi) dump(); } void dump() @@ -180,12 +180,12 @@ struct Read_10 : Usb::Cbw, Scsi::Read_10 struct Write_10 : Usb::Cbw, Scsi::Write_10 { - Write_10(addr_t addr, uint32_t tag, uint8_t lun, + Write_10(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun, uint32_t lba, uint16_t len, uint32_t block_size) : - Cbw(addr, tag, len * block_size, + Cbw(range, tag, len * block_size, Usb::ENDPOINT_OUT, lun, Scsi::Write_10::LENGTH), - Scsi::Write_10(addr+15, lba, len) + Scsi::Write_10(Cbw::range_at(15), lba, len) { if (verbose_scsi) dump(); } void dump() @@ -199,11 +199,11 @@ struct Write_10 : Usb::Cbw, Scsi::Write_10 struct Read_capacity_16 : Usb::Cbw, Scsi::Read_capacity_16 { - Read_capacity_16(addr_t addr, uint32_t tag, uint8_t lun) + Read_capacity_16(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun) : - Cbw(addr, tag, Scsi::Capacity_response_16::LENGTH, + Cbw(range, tag, Scsi::Capacity_response_16::LENGTH, Usb::ENDPOINT_IN, lun, Scsi::Read_capacity_16::LENGTH), - Scsi::Read_capacity_16(addr+15) + Scsi::Read_capacity_16(Cbw::range_at(15)) { if (verbose_scsi) dump(); } void dump() @@ -217,12 +217,12 @@ struct Read_capacity_16 : Usb::Cbw, Scsi::Read_capacity_16 struct Read_16 : Usb::Cbw, Scsi::Read_16 { - Read_16(addr_t addr, uint32_t tag, uint8_t lun, + Read_16(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun, uint64_t lba, uint32_t len, uint32_t block_size) : - Cbw(addr, tag, len * block_size, + Cbw(range, tag, len * block_size, Usb::ENDPOINT_IN, lun, Scsi::Read_16::LENGTH), - Scsi::Read_16(addr+15, lba, len) + Scsi::Read_16(Cbw::range_at(15), (uint32_t)lba, (uint16_t)len) { if (verbose_scsi) dump(); } void dump() @@ -236,12 +236,12 @@ struct Read_16 : Usb::Cbw, Scsi::Read_16 struct Write_16 : Usb::Cbw, Scsi::Write_16 { - Write_16(addr_t addr, uint32_t tag, uint8_t lun, + Write_16(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun, uint64_t lba, uint32_t len, uint32_t block_size) : - Cbw(addr, tag, len * block_size, + Cbw(range, tag, len * block_size, Usb::ENDPOINT_OUT, lun, Scsi::Write_16::LENGTH), - Scsi::Write_16(addr+15, lba, len) + Scsi::Write_16(Cbw::range_at(15), (uint32_t)lba, (uint16_t)len) { if (verbose_scsi) dump(); } void dump() @@ -253,7 +253,7 @@ struct Write_16 : Usb::Cbw, Scsi::Write_16 }; -struct Usb::Csw : Genode::Mmio +struct Usb::Csw : Genode::Mmio<0xd> { enum { LENGTH = 13 }; @@ -264,7 +264,7 @@ struct Usb::Csw : Genode::Mmio enum { PASSED = 0, FAILED = 1, PHASE_ERROR = 2 }; struct Sts : Register<0xc, 8> { }; /* status */ - Csw(addr_t addr) : Mmio(addr) { } + Csw(Genode::Byte_range_ptr const &range) : Mmio(range) { } uint32_t sig() const { return read(); } uint32_t tag() const { return read(); } diff --git a/repos/os/src/drivers/usb_block/main.cc b/repos/os/src/drivers/usb_block/main.cc index 5f4f4f2572..5f029277f0 100644 --- a/repos/os/src/drivers/usb_block/main.cc +++ b/repos/os/src/drivers/usb_block/main.cc @@ -238,14 +238,14 @@ struct Usb::Block_driver : Usb::Completion } int const actual_size = p.transfer.actual_size; - char * const data = reinterpret_cast(iface.content(p)); + Byte_range_ptr data {(char *)iface.content(p), p.size()}; using namespace Scsi; switch (actual_size) { case Inquiry_response::LENGTH: { - Inquiry_response r((addr_t)data); + Inquiry_response r(data); if (verbose_scsi) r.dump(); if (!r.sbc()) { @@ -258,7 +258,7 @@ struct Usb::Block_driver : Usb::Completion } case Capacity_response_10::LENGTH: { - Capacity_response_10 r((addr_t)data); + Capacity_response_10 r(data); if (verbose_scsi) r.dump(); block_count = r.last_block() + 1; @@ -267,7 +267,7 @@ struct Usb::Block_driver : Usb::Completion } case Capacity_response_16::LENGTH: { - Capacity_response_16 r((addr_t)data); + Capacity_response_16 r(data); if (verbose_scsi) r.dump(); block_count = r.last_block() + 1; @@ -276,7 +276,7 @@ struct Usb::Block_driver : Usb::Completion } case Request_sense_response::LENGTH: { - Request_sense_response r((addr_t)data); + Request_sense_response r(data); if (verbose_scsi) r.dump(); uint8_t const asc = r.read(); @@ -322,7 +322,7 @@ struct Usb::Block_driver : Usb::Completion } case Csw::LENGTH: { - Csw csw((addr_t)data); + Csw csw(data); uint32_t const sig = csw.sig(); if (sig != Csw::SIG) { @@ -528,6 +528,7 @@ struct Usb::Block_driver : Usb::Completion */ char cbw_buffer[Cbw::LENGTH]; + Byte_range_ptr cbw_buf_range {(char *)cbw_buffer, Cbw::LENGTH}; /* * We should probably execute the SCSI REPORT_LUNS command first @@ -537,7 +538,7 @@ struct Usb::Block_driver : Usb::Completion */ /* Scsi::Opcode::INQUIRY */ - Inquiry inq((addr_t)cbw_buffer, INQ_TAG, active_lun); + Inquiry inq(cbw_buf_range, INQ_TAG, active_lun); cbw(cbw_buffer, init, true); resp(Scsi::Inquiry_response::LENGTH, init, true); @@ -559,13 +560,13 @@ struct Usb::Block_driver : Usb::Completion enum { MAX_RETRIES = 10 }; int retries; for (retries = 0; retries < MAX_RETRIES; retries++) { - Test_unit_ready unit_ready((addr_t)cbw_buffer, RDY_TAG, active_lun); + Test_unit_ready unit_ready(cbw_buf_range, RDY_TAG, active_lun); cbw(cbw_buffer, init, true); csw(init, true); if (!init.unit_ready) { - Request_sense sense((addr_t)cbw_buffer, REQ_TAG, active_lun); + Request_sense sense(cbw_buf_range, REQ_TAG, active_lun); cbw(cbw_buffer, init, true); resp(Scsi::Request_sense_response::LENGTH, init, true); @@ -582,7 +583,7 @@ struct Usb::Block_driver : Usb::Completion } else if (init.start_stop) { init.start_stop = false; - Start_stop start_stop((addr_t)cbw_buffer, SS_TAG, active_lun); + Start_stop start_stop(cbw_buf_range, SS_TAG, active_lun); cbw(cbw_buffer, init, true); csw(init, true); @@ -609,7 +610,7 @@ struct Usb::Block_driver : Usb::Completion */ /* Scsi::Opcode::READ_CAPACITY_10 */ - Read_capacity_10 read_cap((addr_t)cbw_buffer, CAP_TAG, active_lun); + Read_capacity_10 read_cap(cbw_buf_range, CAP_TAG, active_lun); cbw(cbw_buffer, init, true); resp(Scsi::Capacity_response_10::LENGTH, init, true); @@ -626,7 +627,7 @@ struct Usb::Block_driver : Usb::Completion */ if (init.block_count > ~(uint32_t)0U) { - Read_capacity_16 read_cap((addr_t)cbw_buffer, CAP_TAG, active_lun); + Read_capacity_16 read_cap(cbw_buf_range, CAP_TAG, active_lun); init.read_capacity = false; @@ -779,7 +780,7 @@ struct Usb::Block_driver : Usb::Completion warning("This is not the actual size you are looking for"); do { - Csw csw((addr_t)iface.content(p)); + Csw csw({(char *)iface.content(p), p.size()}); uint32_t const sig = csw.sig(); if (sig != Csw::SIG) { @@ -879,12 +880,13 @@ struct Usb::Block_driver : Usb::Completion * before entering this function */ char cb[Cbw::LENGTH]; + Byte_range_ptr cb_range {(char *)cb, Cbw::LENGTH}; if (read) { - if (force_cmd_16) Read_16 r((addr_t)cb, t, active_lun, lba, c, _block_size); - else Read_10 r((addr_t)cb, t, active_lun, (uint32_t)lba, c, _block_size); + if (force_cmd_16) Read_16 r(cb_range, t, active_lun, lba, c, _block_size); + else Read_10 r(cb_range, t, active_lun, (uint32_t)lba, c, _block_size); } else { - if (force_cmd_16) Write_16 w((addr_t)cb, t, active_lun, lba, c, _block_size); - else Write_10 w((addr_t)cb, t, active_lun, (uint32_t)lba, c, _block_size); + if (force_cmd_16) Write_16 w(cb_range, t, active_lun, lba, c, _block_size); + else Write_10 w(cb_range, t, active_lun, (uint32_t)lba, c, _block_size); } cbw(cb, *this); diff --git a/repos/os/src/drivers/usb_block/scsi.h b/repos/os/src/drivers/usb_block/scsi.h index 9d7e23b8e4..88ecf28255 100644 --- a/repos/os/src/drivers/usb_block/scsi.h +++ b/repos/os/src/drivers/usb_block/scsi.h @@ -84,7 +84,7 @@ namespace Scsi { * SCSI command responses ** ***************************/ -struct Scsi::Inquiry_response : Genode::Mmio +struct Scsi::Inquiry_response : Genode::Mmio<0x24> { /* * Minimum response length is 36 bytes. @@ -105,7 +105,7 @@ struct Scsi::Inquiry_response : Genode::Mmio struct Pid : Register_array<0x10, 8, 16, 8> { }; /* product identification */ struct Rev : Register_array<0x20, 8, 4, 8> { }; /* product revision level */ - Inquiry_response(addr_t addr) : Mmio(addr) { } + Inquiry_response(Byte_range_ptr const &range) : Mmio(range) { } bool sbc() const { return read
() == 0x00; } bool removable() const { return read(); } @@ -132,7 +132,7 @@ struct Scsi::Inquiry_response : Genode::Mmio }; -struct Scsi::Request_sense_response : Genode::Mmio +struct Scsi::Request_sense_response : Genode::Mmio<0x13> { enum { LENGTH = 18 }; @@ -153,7 +153,7 @@ struct Scsi::Request_sense_response : Genode::Mmio struct Fru : Register<0xe, 8> { }; /* field replaceable unit code */ struct Sks : Register<0xf, 32> { }; /* sense key specific (3 byte) */ - Request_sense_response(addr_t addr) : Mmio(addr) { } + Request_sense_response(Byte_range_ptr const &range) : Mmio(range) { } void dump() { @@ -167,14 +167,14 @@ struct Scsi::Request_sense_response : Genode::Mmio }; -struct Scsi::Capacity_response_10 : Genode::Mmio +struct Scsi::Capacity_response_10 : Genode::Mmio<0x8> { enum { LENGTH = 8 }; struct Lba : Register<0x0, 32> { }; struct Bs : Register<0x4, 32> { }; - Capacity_response_10(addr_t addr) : Mmio(addr) { } + Capacity_response_10(Byte_range_ptr const &range) : Mmio(range) { } uint32_t last_block() const { return be(read()); } uint32_t block_size() const { return be(read()); } @@ -188,14 +188,14 @@ struct Scsi::Capacity_response_10 : Genode::Mmio }; -struct Scsi::Capacity_response_16 : Genode::Mmio +struct Scsi::Capacity_response_16 : Genode::Mmio<0xc> { enum { LENGTH = 32 }; struct Lba : Register<0x0, 64> { }; struct Bs : Register<0x8, 32> { }; - Capacity_response_16(addr_t addr) : Mmio(addr) { } + Capacity_response_16(Byte_range_ptr const &range) : Mmio(range) { } uint64_t last_block() const { return be(read()); } uint32_t block_size() const { return be(read()); } @@ -213,7 +213,7 @@ struct Scsi::Capacity_response_16 : Genode::Mmio ** CBD 6 byte commands ** *************************/ -struct Scsi::Cmd_6 : Genode::Mmio +struct Scsi::Cmd_6 : Genode::Mmio<0x6> { enum { LENGTH = 6 }; struct Op : Register<0x0, 8> { }; /* SCSI command */ @@ -221,7 +221,7 @@ struct Scsi::Cmd_6 : Genode::Mmio struct Len : Register<0x4, 8> { }; /* transfer length */ struct Ctl : Register<0x5, 8> { }; /* controll */ - Cmd_6(addr_t addr) : Mmio(addr) { memset((void*)addr, 0, LENGTH); } + Cmd_6(Byte_range_ptr const &range) : Mmio(range) { memset((void*)base(), 0, LENGTH); } void dump() { @@ -235,7 +235,7 @@ struct Scsi::Cmd_6 : Genode::Mmio struct Scsi::Test_unit_ready : Cmd_6 { - Test_unit_ready(addr_t addr) : Cmd_6(addr) + Test_unit_ready(Byte_range_ptr const &range) : Cmd_6(range) { write(Opcode::TEST_UNIT_READY); } @@ -244,7 +244,7 @@ struct Scsi::Test_unit_ready : Cmd_6 struct Scsi::Request_sense : Cmd_6 { - Request_sense(addr_t addr) : Cmd_6(addr) + Request_sense(Byte_range_ptr const &range) : Cmd_6(range) { write(Opcode::REQUEST_SENSE); write(Request_sense_response::LENGTH); @@ -254,7 +254,7 @@ struct Scsi::Request_sense : Cmd_6 struct Scsi::Inquiry : Cmd_6 { - Inquiry(addr_t addr) : Cmd_6(addr) + Inquiry(Byte_range_ptr const &range) : Cmd_6(range) { write(Opcode::INQUIRY); write(Inquiry_response::LENGTH); @@ -262,7 +262,7 @@ struct Scsi::Inquiry : Cmd_6 }; -struct Scsi::Start_stop : Genode::Mmio +struct Scsi::Start_stop : Genode::Mmio<0x5> { enum { LENGTH = 6 }; struct Op : Register<0x0, 8> { }; /* SCSI command */ @@ -275,9 +275,9 @@ struct Scsi::Start_stop : Genode::Mmio struct St : Bitfield<0, 1> { }; /* start */ }; /* flags */ - Start_stop(addr_t addr) : Mmio(addr) + Start_stop(Byte_range_ptr const &range) : Mmio(range) { - memset((void*)addr, 0, LENGTH); + memset((void*)base(), 0, LENGTH); write(Opcode::START_STOP); write(1); @@ -301,7 +301,7 @@ struct Scsi::Start_stop : Genode::Mmio ** CBD 10 byte commands ** **************************/ -struct Scsi::Cmd_10 : Genode::Mmio +struct Scsi::Cmd_10 : Genode::Mmio<0xa> { enum { LENGTH = 10 }; struct Op : Register<0x0, 8> { }; /* SCSI command */ @@ -309,7 +309,7 @@ struct Scsi::Cmd_10 : Genode::Mmio struct Len : Register<0x7, 16> { }; /* transfer length */ struct Ctl : Register<0x9, 8> { }; /* controll */ - Cmd_10(addr_t addr) : Mmio(addr) { memset((void*)addr, 0, LENGTH); } + Cmd_10(Byte_range_ptr const &range) : Mmio(range) { memset((void*)base(), 0, LENGTH); } void dump() { @@ -323,7 +323,7 @@ struct Scsi::Cmd_10 : Genode::Mmio struct Scsi::Read_capacity_10 : Cmd_10 { - Read_capacity_10(addr_t addr) : Cmd_10(addr) + Read_capacity_10(Byte_range_ptr const &range) : Cmd_10(range) { write(Opcode::READ_CAPACITY_10); } @@ -332,7 +332,7 @@ struct Scsi::Read_capacity_10 : Cmd_10 struct Scsi::Io_10 : Cmd_10 { - Io_10(addr_t addr, uint32_t lba, uint16_t len) : Cmd_10(addr) + Io_10(Byte_range_ptr const &range, uint32_t lba, uint16_t len) : Cmd_10(range) { write(be(lba)); write(be(len)); @@ -342,7 +342,7 @@ struct Scsi::Io_10 : Cmd_10 struct Scsi::Read_10 : Io_10 { - Read_10(addr_t addr, uint32_t lba, uint16_t len) : Io_10(addr, lba, len) + Read_10(Byte_range_ptr const &range, uint32_t lba, uint16_t len) : Io_10(range, lba, len) { write(Opcode::READ_10); } @@ -351,7 +351,7 @@ struct Scsi::Read_10 : Io_10 struct Scsi::Write_10 : Io_10 { - Write_10(addr_t addr, uint32_t lba, uint16_t len) : Io_10(addr, lba, len) + Write_10(Byte_range_ptr const &range, uint32_t lba, uint16_t len) : Io_10(range, lba, len) { write(Opcode::WRITE_10); } @@ -362,7 +362,7 @@ struct Scsi::Write_10 : Io_10 ** CBD 16 long LBA byte commands ** ***********************************/ -struct Scsi::Cmd_16 : Genode::Mmio +struct Scsi::Cmd_16 : Genode::Mmio<0x10> { enum { LENGTH = 16 }; struct Op : Register<0x0, 8> { }; /* SCSI command */ @@ -370,7 +370,7 @@ struct Scsi::Cmd_16 : Genode::Mmio struct Len : Register<0xa, 32> { }; /* transfer length */ struct Ctl : Register<0xf, 8> { }; /* controll */ - Cmd_16(addr_t addr) : Mmio(addr) { memset((void*)addr, 0, LENGTH); } + Cmd_16(Byte_range_ptr const &range) : Mmio(range) { memset((void*)base(), 0, LENGTH); } void dump() { @@ -384,7 +384,7 @@ struct Scsi::Cmd_16 : Genode::Mmio struct Scsi::Read_capacity_16 : Cmd_16 { - Read_capacity_16(addr_t addr) : Cmd_16(addr) + Read_capacity_16(Byte_range_ptr const &range) : Cmd_16(range) { write(Opcode::READ_CAPACITY_16); } @@ -393,7 +393,7 @@ struct Scsi::Read_capacity_16 : Cmd_16 struct Scsi::Io_16 : Cmd_16 { - Io_16(addr_t addr, uint64_t lba, uint32_t len) : Cmd_16(addr) + Io_16(Byte_range_ptr const &range, uint32_t lba, uint16_t len) : Cmd_16(range) { write(be(lba)); write(be(len)); @@ -403,7 +403,7 @@ struct Scsi::Io_16 : Cmd_16 struct Scsi::Read_16 : Io_16 { - Read_16(addr_t addr, uint64_t lba, uint32_t len) : Io_16(addr, lba, len) + Read_16(Byte_range_ptr const &range, uint32_t lba, uint16_t len) : Io_16(range, lba, len) { write(Opcode::READ_16); } @@ -412,7 +412,7 @@ struct Scsi::Read_16 : Io_16 struct Scsi::Write_16 : Io_16 { - Write_16(addr_t addr, uint64_t lba, uint32_t len) : Io_16(addr, lba, len) + Write_16(Byte_range_ptr const &range, uint32_t lba, uint16_t len) : Io_16(range, lba, len) { write(Opcode::WRITE_16); } diff --git a/repos/os/src/drivers/virtdev_rom/main.cc b/repos/os/src/drivers/virtdev_rom/main.cc index 15a72fe01e..369d8b917f 100644 --- a/repos/os/src/drivers/virtdev_rom/main.cc +++ b/repos/os/src/drivers/virtdev_rom/main.cc @@ -92,7 +92,7 @@ struct Virtdev_rom::Main Sliced_heap _heap { _env.ram(), _env.rm() }; Virtdev_rom::Root _root { _env, _heap, _ds }; - struct Device : public Attached_mmio + struct Device : public Attached_mmio<0xc> { struct Magic : Register<0x000, 32> { }; struct Id : Register<0x008, 32> { @@ -108,8 +108,8 @@ struct Virtdev_rom::Main }; }; - Device(Env &env, addr_t base, size_t size) - : Attached_mmio(env, base, size, false) { } + Device(Env &env, Byte_range_ptr const &range) + : Attached_mmio(env, range, false) { } }; static char const *_name_for_id(unsigned id) @@ -138,7 +138,7 @@ struct Virtdev_rom::Main for (size_t idx = 0; idx < NUM_VIRTIO_TRANSPORTS; ++idx) { addr_t addr = BASE_ADDRESS + idx * DEVICE_SIZE; - Device device { _env, BASE_ADDRESS + idx * DEVICE_SIZE, DEVICE_SIZE }; + Device device { _env, {(char *)(BASE_ADDRESS + idx * DEVICE_SIZE), DEVICE_SIZE} }; if (device.read() != VIRTIO_MMIO_MAGIC) { warning("Found non VirtIO MMIO device @ ", Hex(addr)); diff --git a/repos/os/src/server/part_block/ahdi.h b/repos/os/src/server/part_block/ahdi.h index e14f4b2cba..2ff475bc64 100644 --- a/repos/os/src/server/part_block/ahdi.h +++ b/repos/os/src/server/part_block/ahdi.h @@ -96,7 +96,7 @@ class Block::Ahdi : public Partition_table { bool any_partition_valid = false; - Root_sector const root = *sector.addr(); + Root_sector const root = *(Root_sector const *)sector.buffer().start; for (unsigned i = 0; i < MAX_PARTITIONS; i++) if (root.partitions[i].valid()) any_partition_valid = true; @@ -107,7 +107,7 @@ class Block::Ahdi : public Partition_table template void _parse_ahdi(Sync_read const §or, FUNC const &fn) { - Root_sector &root = *sector.addr(); + Root_sector &root = *(Root_sector *)sector.buffer().start; for (unsigned i = 0; i < MAX_PARTITIONS; i++) { Partition_record const &part = root.partitions[i]; diff --git a/repos/os/src/server/part_block/block.h b/repos/os/src/server/part_block/block.h index deb70f8de4..ec0b42a4e7 100644 --- a/repos/os/src/server/part_block/block.h +++ b/repos/os/src/server/part_block/block.h @@ -63,11 +63,11 @@ class Block::Sync_read : Noncopyable private: - Handler &_handler; - Allocator &_alloc; - size_t _size { 0 }; - void *_buffer { nullptr }; - bool _success { false }; + Handler &_handler; + Allocator &_alloc; + size_t _size { 0 }; + Constructible _buffer { }; + bool _success { false }; /* * Noncopyable @@ -100,7 +100,7 @@ class Block::Sync_read : Noncopyable ~Sync_read() { - _alloc.free(_buffer, _size); + _alloc.free(_buffer->start, _size); } bool success() const { return _success; } @@ -108,8 +108,8 @@ class Block::Sync_read : Noncopyable void consume_read_result(Block_connection::Job &, off_t offset, char const *src, size_t length) { - _buffer = _alloc.alloc(length); - memcpy((char *)_buffer + offset, src, length); + _buffer.construct((char *)_alloc.alloc(length), length); + memcpy(_buffer->start + offset, src, length); _size += length; } @@ -126,8 +126,7 @@ class Block::Sync_read : Noncopyable _success = success; } - template T addr() const { - return reinterpret_cast(_buffer); } + Byte_range_ptr const &buffer() const { return *_buffer; } }; diff --git a/repos/os/src/server/part_block/gpt.h b/repos/os/src/server/part_block/gpt.h index 7681f34da0..fd3c562e00 100644 --- a/repos/os/src/server/part_block/gpt.h +++ b/repos/os/src/server/part_block/gpt.h @@ -60,7 +60,7 @@ class Block::Gpt : public Block::Partition_table /** * DCE uuid struct */ - struct Uuid : Mmio + struct Uuid : Mmio<16> { struct Time_low : Register<0, 32> { }; struct Time_mid : Register<4, 16> { }; @@ -72,7 +72,7 @@ class Block::Gpt : public Block::Partition_table struct Node : Register_array<10, 8, 6, 8> { }; Uuid() = delete; - Uuid(addr_t base) : Mmio(base) { }; + using Mmio::Mmio; unsigned time_low() const { return read(); } @@ -98,7 +98,7 @@ class Block::Gpt : public Block::Partition_table /** * GUID parition table header */ - struct Gpt_hdr : Mmio + struct Gpt_hdr : Mmio<92> { struct Sig : Register<0, 64> { }; /* identifies GUID Partition Table */ struct Revision : Register<8, 32> { }; /* GPT specification revision */ @@ -112,7 +112,7 @@ class Block::Gpt : public Block::Partition_table struct Part_lba_start : Register<40, 64> { }; /* first LBA usable for partitions */ struct Part_lba_end : Register<48, 64> { }; /* last LBA usable for partitions */ - Uuid guid() { return Uuid(base() + 56); } /* GUID to identify the disk */ + Uuid guid() { return Uuid(range_at(56)); } /* GUID to identify the disk */ struct Gpe_lba : Register<72, 64> { }; /* first LBA of GPE array */ struct Entries : Register<80, 32> { }; /* number of entries in GPE array */ @@ -120,7 +120,7 @@ class Block::Gpt : public Block::Partition_table struct Gpe_crc : Register<88, 32> { }; /* CRC32 of GPE array */ Gpt_hdr() = delete; - Gpt_hdr(addr_t base) : Mmio(base) { }; + using Mmio::Mmio; uint64_t part_lba_start() const { return read(); } uint64_t part_lba_end() const { return read(); } @@ -190,7 +190,7 @@ class Block::Gpt : public Block::Partition_table size_t length = entries() * entry_size(); Sync_read gpe(handler, alloc, gpe_lba(), length / block_size); if (!gpe.success() - || crc32(gpe.addr(), length) != read()) + || crc32((addr_t)gpe.buffer().start, length) != read()) return false; if (check_primary) { @@ -199,7 +199,7 @@ class Block::Gpt : public Block::Partition_table if (!backup_hdr.success()) return false; - Gpt_hdr backup(backup_hdr.addr()); + Gpt_hdr backup(backup_hdr.buffer()); if (!backup.valid(handler, alloc, block_size, false)) warning("Backup GPT header is corrupted"); } @@ -220,12 +220,12 @@ class Block::Gpt : public Block::Partition_table /** * GUID partition entry format */ - struct Gpt_entry : Mmio + struct Gpt_entry : Mmio<56 + 36 * 2> { enum { NAME_LEN = 36 }; - Uuid type() const { return Uuid(base()); } /* partition type GUID */ - Uuid guid() const { return Uuid(base()+ Uuid::size()); } /* unique partition GUID */ + Uuid type() const { return Uuid(range()); } /* partition type GUID */ + Uuid guid() const { return Uuid(range_at(Uuid::size())); } /* unique partition GUID */ struct Lba_start : Register<32, 64> { }; /* start of partition */ struct Lba_end : Register<40, 64> { }; /* end of partition */ @@ -233,7 +233,7 @@ class Block::Gpt : public Block::Partition_table struct Name : Register_array<56, 16, NAME_LEN, 16> { }; /* partition name in UNICODE-16 */ Gpt_entry() = delete; - Gpt_entry(addr_t base) : Mmio(base) { } + using Mmio::Mmio; uint64_t lba_start() const { return read(); } uint64_t lba_end() const { return read(); } @@ -340,7 +340,7 @@ class Block::Gpt : public Block::Partition_table uint64_t used = 0; for (uint32_t i = 0; i < num; i++) { - Gpt_entry const e(entries.base() + i * header.entry_size()); + Gpt_entry const e(entries.range_at(i * header.entry_size())); if (!e.valid()) { continue; } @@ -364,7 +364,7 @@ class Block::Gpt : public Block::Partition_table gpt.entries() * gpt.entry_size() / _info.block_size); if (!entry_array.success()) return false; - Gpt_entry entries(entry_array.addr()); + Gpt_entry entries(entry_array.buffer()); _gpt_part_lba_end = gpt.part_lba_end(); _gpt_total = (gpt.part_lba_end() - gpt.part_lba_start()) + 1; @@ -372,7 +372,7 @@ class Block::Gpt : public Block::Partition_table for (int i = 0; i < MAX_PARTITIONS; i++) { - Gpt_entry e(entries.base() + i * gpt.entry_size()); + Gpt_entry e(entries.range_at(i * gpt.entry_size())); if (!e.valid()) continue; @@ -404,7 +404,7 @@ class Block::Gpt : public Block::Partition_table if (!s.success()) return false; - Gpt_hdr gpt_hdr(s.addr()); + Gpt_hdr gpt_hdr(s.buffer()); if (!_parse_gpt(gpt_hdr)) return false; diff --git a/repos/os/src/server/part_block/mbr.h b/repos/os/src/server/part_block/mbr.h index b7ce3edf81..b426425686 100644 --- a/repos/os/src/server/part_block/mbr.h +++ b/repos/os/src/server/part_block/mbr.h @@ -52,7 +52,7 @@ class Block::Mbr : public Partition_table /** * Partition table entry format */ - struct Partition_record : Mmio + struct Partition_record : Mmio<16> { struct Type : Register<4, 8> { @@ -66,8 +66,7 @@ class Block::Mbr : public Partition_table Partition_record() = delete; - Partition_record(addr_t base) - : Mmio(base) { } + using Mmio::Mmio; bool valid() const { return read() != Type::INVALID; } bool extended() const { return read() == Type::EXTENTED_CHS || @@ -83,7 +82,7 @@ class Block::Mbr : public Partition_table /** * Master/Extented boot record format */ - struct Boot_record : Mmio + struct Boot_record : Mmio<512> { struct Magic : Register<510, 16> { @@ -92,7 +91,7 @@ class Block::Mbr : public Partition_table Boot_record() = delete; - Boot_record(addr_t base) : Mmio(base) { } + using Mmio::Mmio; bool valid() const { @@ -100,9 +99,9 @@ class Block::Mbr : public Partition_table return read() == Magic::NUMBER; } - addr_t record(unsigned index) const + Byte_range_ptr record(unsigned index) const { - return base() + 446 + (index * Partition_record::size()); + return range_at(446 + (index * Partition_record::size())); } }; @@ -113,7 +112,7 @@ class Block::Mbr : public Partition_table template void _parse_extended(Partition_record const &record, FUNC const &f) const { - Reconstructible r(record.base()); + Reconstructible r(record.range()); unsigned lba = r->lba(); unsigned last_lba = 0; @@ -124,7 +123,7 @@ class Block::Mbr : public Partition_table if (!s.success()) return; - Boot_record const ebr(s.addr()); + Boot_record const ebr(s.buffer()); if (!ebr.valid()) return; @@ -188,7 +187,7 @@ class Block::Mbr : public Partition_table return Parse_result::NO_MBR; /* check for MBR */ - Boot_record const mbr(s.addr()); + Boot_record const mbr(s.buffer()); if (!mbr.valid()) return Parse_result::NO_MBR; diff --git a/repos/os/src/server/part_block/partition_table.h b/repos/os/src/server/part_block/partition_table.h index 3a1190465a..ec6341922e 100644 --- a/repos/os/src/server/part_block/partition_table.h +++ b/repos/os/src/server/part_block/partition_table.h @@ -54,7 +54,7 @@ class Block::Partition_table : Interface, Noncopyable enum { BYTES = 4096 }; Sync_read fs(_handler, _alloc, lba, BYTES / _info.block_size); if (fs.success()) - return Fs::probe(fs.addr(), BYTES); + return Fs::probe((uint8_t *)fs.buffer().start, BYTES); else return Fs::Type(); } diff --git a/repos/os/src/server/tz_vmm/spec/imx53/m4if.h b/repos/os/src/server/tz_vmm/spec/imx53/m4if.h index dff8a275ed..4da1513734 100644 --- a/repos/os/src/server/tz_vmm/spec/imx53/m4if.h +++ b/repos/os/src/server/tz_vmm/spec/imx53/m4if.h @@ -17,7 +17,7 @@ /* Genode includes */ #include -class M4if : Genode::Attached_mmio +class M4if : Genode::Attached_mmio<0x11c> { private: @@ -58,8 +58,8 @@ class M4if : Genode::Attached_mmio public: - M4if(Genode::Env &env, Genode::addr_t base, Genode::size_t size) - : Genode::Attached_mmio(env, base, size) { } + M4if(Genode::Env &env, Genode::Byte_range_ptr const &range) + : Attached_mmio(env, range) { } void set_region0(Genode::addr_t addr, Genode::size_t size) { diff --git a/repos/os/src/server/tz_vmm/spec/imx53/main.cc b/repos/os/src/server/tz_vmm/spec/imx53/main.cc index 45ab0f73a4..fb6de05ab6 100644 --- a/repos/os/src/server/tz_vmm/spec/imx53/main.cc +++ b/repos/os/src/server/tz_vmm/spec/imx53/main.cc @@ -55,7 +55,7 @@ class Main KERNEL_OFFSET, Machine_type(MACHINE_QSB), Board_revision(BOARD_QSB), _heap, _exception_handler }; - M4if _m4if { _env, Imx53::M4IF_BASE, Imx53::M4IF_SIZE }; + M4if _m4if { _env, {(char *)Imx53::M4IF_BASE, Imx53::M4IF_SIZE} }; Serial_driver _serial { _env.ram(), _env.rm() }; Block_driver _block { _env, _config.xml(), _heap, _vm }; diff --git a/repos/os/src/server/vmm/fdt.cc b/repos/os/src/server/vmm/fdt.cc index b95009386f..6d1470c677 100644 --- a/repos/os/src/server/vmm/fdt.cc +++ b/repos/os/src/server/vmm/fdt.cc @@ -26,7 +26,7 @@ class Mmio_big_endian_access private: - addr_t const _base; + Byte_range_ptr const _range; /** * Write '_ACCESS_T' typed 'value' to MMIO base + 'offset' @@ -34,8 +34,7 @@ class Mmio_big_endian_access template inline void _write(off_t const offset, ACCESS_T const value) { - addr_t const dst = _base + offset; - *(ACCESS_T volatile *)dst = host_to_big_endian(value); + *(ACCESS_T volatile *)(_range.start + offset) = host_to_big_endian(value); } /** @@ -44,30 +43,38 @@ class Mmio_big_endian_access template inline ACCESS_T _read(off_t const &offset) const { - addr_t const dst = _base + offset; - ACCESS_T const value = *(ACCESS_T volatile *)dst; - return host_to_big_endian(value); + return host_to_big_endian(*(ACCESS_T volatile *)(_range.start + offset)); } public: - Mmio_big_endian_access(addr_t const base) : _base(base) { } + Mmio_big_endian_access(Byte_range_ptr const &range) : _range(range.start, range.num_bytes) { } - addr_t base() const { return _base; } + Byte_range_ptr range_at(off_t offset) const + { + return {_range.start + offset, _range.num_bytes - offset}; + } + + Byte_range_ptr range() const { return range_at(0); } + + addr_t base() const { return (addr_t)range().start; } }; +template struct Mmio : Mmio_big_endian_access, - Register_set + Register_set { - Mmio(addr_t const base) + static constexpr size_t SIZE = MMIO_SIZE; + + Mmio(Byte_range_ptr const &range) : - Mmio_big_endian_access(base), - Register_set(*static_cast(this)) { } + Mmio_big_endian_access(range), + Register_set(*static_cast(this)) { } }; -struct Fdt_header : Mmio +struct Fdt_header : Mmio<10*4> { struct Magic : Register<0x0, 32> {}; struct Totalsize : Register<0x4, 32> {}; @@ -81,19 +88,15 @@ struct Fdt_header : Mmio struct Size_dt_struct : Register<0x24, 32> {}; using Mmio::Mmio; - - enum { SIZE = 10*4 }; }; -struct Fdt_reserve_entry : Mmio +struct Fdt_reserve_entry : Mmio<2*8> { struct Address : Register<0, 64> {}; struct Size : Register<8, 64> {}; using Mmio::Mmio; - - enum { SIZE = 2*8 }; }; @@ -106,35 +109,37 @@ enum Fdt_tokens { }; -struct Fdt_token : Mmio +template +struct Fdt_token_tpl : Mmio { - struct Type : Register<0, 32> {}; + using Base = Mmio; - Fdt_token(addr_t const base, Fdt_tokens type) + struct Type : Base::template Register<0, 32> {}; + + Fdt_token_tpl(Byte_range_ptr const &range, Fdt_tokens type) : - Mmio(base) + Base(range) { - write(type); + Base::template write(type); } - - enum { SIZE = 4 }; }; -struct Fdt_prop : Fdt_token +using Fdt_token = Fdt_token_tpl<0x4>; + + +struct Fdt_prop : Fdt_token_tpl { struct Len : Register<4, 32> {}; struct Nameoff : Register<8, 32> {}; - Fdt_prop(addr_t base, uint32_t len, uint32_t name_offset) + Fdt_prop(Byte_range_ptr const &range, uint32_t len, uint32_t name_offset) : - Fdt_token(base, FDT_PROP) + Fdt_token_tpl(range, FDT_PROP) { write(len); write(name_offset); } - - enum { SIZE = Fdt_token::SIZE + 2*4 }; }; @@ -220,20 +225,20 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config, auto node = [&] (auto const & name, auto const & fn) { - Fdt_token start(_buffer.addr+off, FDT_BEGIN_NODE); + Fdt_token start({(char *)_buffer.addr+off, _buffer.size-off}, FDT_BEGIN_NODE); off += Fdt_token::SIZE; _buffer.write(off, name.string(), name.length()); off += (uint32_t)name.length(); off = align_addr(off, 2); fn(); - Fdt_token end(_buffer.addr+off, FDT_END_NODE); + Fdt_token end({(char *)_buffer.addr+off, _buffer.size-off}, FDT_END_NODE); off += Fdt_token::SIZE; }; auto property = [&] (auto const & name, auto const & val) { _dict.add(name); - Fdt_prop prop(_buffer.addr+off, (uint32_t)val.length(), + Fdt_prop prop({(char *)_buffer.addr+off, _buffer.size-off}, (uint32_t)val.length(), _dict.offset(name)); off += Fdt_prop::SIZE; val.write(off, _buffer); @@ -366,7 +371,7 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config, }); }); - Fdt_token end(_buffer.addr+off, FDT_END); + Fdt_token end({(char *)_buffer.addr+off, _buffer.size-off}, FDT_END); off += Fdt_token::SIZE; } @@ -374,7 +379,7 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config, void Vmm::Fdt_generator::generate(Config const & config, void * initrd_start, size_t initrd_size) { - Fdt_header header(_buffer.addr); + Fdt_header header({(char *)_buffer.addr, _buffer.size}); header.write(FDT_MAGIC); header.write(FDT_VERSION); header.write(FDT_COMP_VERSION); @@ -382,7 +387,7 @@ void Vmm::Fdt_generator::generate(Config const & config, uint32_t off = Fdt_header::SIZE; header.write(off); - Fdt_reserve_entry memory(_buffer.addr+off); + Fdt_reserve_entry memory({(char *)_buffer.addr+off, _buffer.size-off}); memory.write(0); memory.write(0); @@ -391,7 +396,7 @@ void Vmm::Fdt_generator::generate(Config const & config, _generate_tree(off, config, initrd_start, initrd_size); - header.write(off-Fdt_header::SIZE-Fdt_reserve_entry::SIZE); + header.write((uint32_t)(off-Fdt_header::SIZE-Fdt_reserve_entry::SIZE)); header.write(off); header.write(_dict.length()); diff --git a/repos/os/src/server/vmm/ram.h b/repos/os/src/server/vmm/ram.h index 8b219f0103..790c44ffef 100644 --- a/repos/os/src/server/vmm/ram.h +++ b/repos/os/src/server/vmm/ram.h @@ -21,29 +21,34 @@ class Ram { private: - Genode::addr_t const _base; - Genode::size_t const _size; - Genode::addr_t const _local; + using Byte_range_ptr = Genode::Byte_range_ptr; + using addr_t = Genode::addr_t; + using size_t = Genode::size_t; + + addr_t const _guest_base; + Byte_range_ptr const _local_range; public: - Ram(Genode::addr_t const addr, - Genode::size_t const sz, - Genode::addr_t const local) - : _base(addr), _size(sz), _local(local) { } + Ram(addr_t guest_base, Byte_range_ptr const &local_range) + : _guest_base(guest_base), _local_range(local_range.start, local_range.num_bytes) { } - Genode::addr_t base() const { return _base; } - Genode::size_t size() const { return _size; } - Genode::addr_t local() const { return _local; } + size_t size() const { return _local_range.num_bytes; } + addr_t guest_base() const { return _guest_base; } + addr_t local_base() const { return (addr_t)_local_range.start; } - Genode::addr_t local_address(Genode::addr_t guest, Genode::size_t size) + Byte_range_ptr to_local_range(Byte_range_ptr const &guest_range) { - if (guest < _base || guest >= _base + _size || - size == 0 || guest + size >= _base + _size) + addr_t guest_base = (addr_t)guest_range.start; + if (guest_base < _guest_base || + guest_base >= _guest_base + _local_range.num_bytes || + guest_range.num_bytes == 0 || + guest_base + guest_range.num_bytes >= _guest_base + _local_range.num_bytes) throw Vmm::Exception("Invalid guest physical address: ", - Genode::Hex(guest), " size: ", Genode::Hex(size)); + Genode::Hex(guest_base), " size: ", Genode::Hex(guest_range.num_bytes)); - return _local + (guest - _base); + Genode::off_t offset = guest_base - _guest_base; + return {_local_range.start + offset, guest_range.num_bytes}; } }; diff --git a/repos/os/src/server/vmm/virtio_block.h b/repos/os/src/server/vmm/virtio_block.h index 44aae3040d..86f8e2d877 100644 --- a/repos/os/src/server/vmm/virtio_block.h +++ b/repos/os/src/server/vmm/virtio_block.h @@ -103,8 +103,7 @@ class Vmm::Virtio_block_request template T * _desc_addr(Descriptor const & desc) const { - return (T*) _ram.local_address((addr_t)desc.address(), - desc.length()); } + return (T*) _ram.to_local_range({(char *)desc.address(), desc.length()}).start; } Index _request_idx; Descriptor _request { _array.get(_request_idx) }; diff --git a/repos/os/src/server/vmm/virtio_console.h b/repos/os/src/server/vmm/virtio_console.h index ca95cbf6c1..683f691278 100644 --- a/repos/os/src/server/vmm/virtio_console.h +++ b/repos/os/src/server/vmm/virtio_console.h @@ -34,11 +34,11 @@ class Vmm::Virtio_console : public Virtio_device { Genode::Mutex::Guard guard(_mutex); - auto read = [&] (addr_t data, size_t size) + auto read = [&] (Byte_range_ptr const &data) { if (!_terminal.avail()) return 0ul; - size_t length = _terminal.read((void *)data, size); + size_t length = _terminal.read((void *)data.start, data.num_bytes); return length; }; @@ -52,10 +52,10 @@ class Vmm::Virtio_console : public Virtio_device { if (idx != TX) return; - auto write = [&] (addr_t data, size_t size) + auto write = [&] (Byte_range_ptr const &data) { - _terminal.write((void *)data, size); - return size; + _terminal.write((void *)data.start, data.num_bytes); + return data.num_bytes; }; if (_queue[TX]->notify(write)) diff --git a/repos/os/src/server/vmm/virtio_device.h b/repos/os/src/server/vmm/virtio_device.h index 29482e16ab..aaaaf3107e 100644 --- a/repos/os/src/server/vmm/virtio_device.h +++ b/repos/os/src/server/vmm/virtio_device.h @@ -73,21 +73,24 @@ class Vmm::Virtio_split_queue using Descriptor_index = Index; - struct Queue_base : Mmio + template + struct Queue_base : Mmio { + using Base = Mmio; + uint16_t const max; - Queue_base(addr_t base, uint16_t max) - : Mmio(base), max(max) {} + Queue_base(Byte_range_ptr const &range, uint16_t max) + : Base(range), max(max) {} - struct Flags : Register<0x0, 16> { }; - struct Idx : Register<0x2, 16> { }; + struct Flags : Base::template Register<0x0, 16> { }; + struct Idx : Base::template Register<0x2, 16> { }; - Ring_index current() { return read(); } + Ring_index current() { return Base::template read(); } }; - struct Avail_queue : Queue_base + struct Avail_queue : Queue_base<0x4 + MAX_SIZE * 2> { using Queue_base::Queue_base; @@ -105,7 +108,7 @@ class Vmm::Virtio_split_queue } _avail; - struct Used_queue : Queue_base + struct Used_queue : Queue_base<0x4 + MAX_SIZE * 8> { using Queue_base::Queue_base; @@ -129,7 +132,7 @@ class Vmm::Virtio_split_queue } _used; - struct Descriptor : Mmio + struct Descriptor : Mmio<0x10> { using Mmio::Mmio; @@ -154,19 +157,24 @@ class Vmm::Virtio_split_queue struct Descriptor_array { - size_t const elem_size { 16 }; - unsigned const max; - addr_t const start; + size_t const elem_size { 16 }; + unsigned const max; + Byte_range_ptr const guest_range; + Byte_range_ptr const local_range; Descriptor_array(Ram & ram, addr_t base, unsigned const max) : max(max), - start(ram.local_address(base, max * elem_size)) {} + guest_range((char *)base, max * elem_size), + local_range( + ram.to_local_range(guest_range).start, + ram.to_local_range(guest_range).num_bytes) {} Descriptor get(Descriptor_index idx) { if (idx.idx() >= max) error("Descriptor_index out of bounds"); - return Descriptor(start + (elem_size * idx.idx())); + off_t offset = elem_size * idx.idx(); + return Descriptor({local_range.start + offset, local_range.num_bytes - offset}); } } _descriptors; @@ -182,8 +190,8 @@ class Vmm::Virtio_split_queue uint16_t const queue_num, Ram & ram) : - _avail(ram.local_address(driver_area, 6+2*queue_num), queue_num), - _used(ram.local_address(device_area, 6+8*queue_num), queue_num), + _avail(ram.to_local_range({(char *)driver_area, 6+2*(size_t)queue_num}), queue_num), + _used(ram.to_local_range({(char *)device_area, 6+8*(size_t)queue_num}), queue_num), _descriptors(ram, descriptor_area, queue_num), _ram(ram) { } @@ -205,8 +213,7 @@ class Vmm::Virtio_split_queue if (!address || !size) { break; } try { - addr_t data = _ram.local_address((addr_t)address, size); - size_t consumed = func(data, size); + size_t consumed = func(_ram.to_local_range({(char *)address, size})); if (!consumed) { break; } _used.add(_cur_idx, id, consumed); written = true; diff --git a/repos/os/src/server/vmm/virtio_gpu.cc b/repos/os/src/server/vmm/virtio_gpu.cc index 0a1099f969..8d0a9235f5 100644 --- a/repos/os/src/server/vmm/virtio_gpu.cc +++ b/repos/os/src/server/vmm/virtio_gpu.cc @@ -44,7 +44,7 @@ void Vmm::Virtio_gpu_queue::notify(Virtio_gpu_device & dev) void Vmm::Virtio_gpu_control_request::_get_display_info() { Framebuffer::Mode mode = _device.resize(); - Display_info_response dir { _desc_addr(1) }; + Display_info_response dir { _desc_range(1) }; memset((void*)dir.base(), 0, Display_info_response::SIZE); dir.write(Control_header::Type::OK_DISPLAY_INFO); @@ -59,8 +59,8 @@ void Vmm::Virtio_gpu_control_request::_get_display_info() void Vmm::Virtio_gpu_control_request::_resource_create_2d() { - Resource_create_2d c2d { _desc_addr(0) }; - Control_header response { _desc_addr(1) }; + Resource_create_2d c2d { _desc_range(0) }; + Control_header response { _desc_range(1) }; if (c2d.read() != Resource_create_2d::Format::B8G8R8X8) { @@ -90,8 +90,8 @@ void Vmm::Virtio_gpu_control_request::_resource_delete() using Resource = Virtio_gpu_device::Resource; using Scanout = Resource::Scanout; - Resource_unref rur { _desc_addr(0) }; - Control_header response { _desc_addr(1) }; + Resource_unref rur { _desc_range(0) }; + Control_header response { _desc_range(1) }; response.write(Control_header::Type::ERR_INVALID_RESOURCE_ID); uint32_t id = rur.read(); @@ -113,9 +113,9 @@ void Vmm::Virtio_gpu_control_request::_resource_attach_backing() using Resource = Virtio_gpu_device::Resource; using Entry = Resource_attach_backing::Memory_entry; - Resource_attach_backing rab { _desc_addr(0) }; - addr_t entry_base { _desc_addr(1) }; - Control_header response { _desc_addr(2) }; + Resource_attach_backing rab { _desc_range(0) }; + Byte_range_ptr entry_range { _desc_range(1) }; + Control_header response { _desc_range(2) }; response.write(Control_header::Type::ERR_INVALID_RESOURCE_ID); uint32_t id = rab.read(); @@ -127,10 +127,11 @@ void Vmm::Virtio_gpu_control_request::_resource_attach_backing() try { for (unsigned i = 0; i < nr; i++) { - Entry entry(entry_base+i*Entry::SIZE); + off_t offset = i*Entry::SIZE; + Entry entry({entry_range.start + offset, entry_range.num_bytes - offset}); size_t sz = entry.read(); - addr_t off = _device._ram.local_address((addr_t)entry.read(), sz) - - _device._ram.local(); + addr_t off = (addr_t)_device._ram.to_local_range({(char *)entry.read(), sz}).start + - _device._ram.local_base(); res.attach(off, sz); } response.write(Control_header::Type::OK_NO_DATA); @@ -143,8 +144,8 @@ void Vmm::Virtio_gpu_control_request::_resource_attach_backing() void Vmm::Virtio_gpu_control_request::_set_scanout() { - Set_scanout scr { _desc_addr(0) }; - Control_header response { _desc_addr(1) }; + Set_scanout scr { _desc_range(0) }; + Control_header response { _desc_range(1) }; uint32_t id = scr.read(); uint32_t sid = scr.read(); @@ -177,8 +178,8 @@ void Vmm::Virtio_gpu_control_request::_set_scanout() void Vmm::Virtio_gpu_control_request::_resource_flush() { - Resource_flush rf { _desc_addr(0) }; - Control_header response { _desc_addr(1) }; + Resource_flush rf { _desc_range(0) }; + Control_header response { _desc_range(1) }; uint32_t id = rf.read(); response.write(Control_header::Type::ERR_INVALID_RESOURCE_ID); @@ -229,8 +230,8 @@ void Vmm::Virtio_gpu_control_request::_resource_flush() void Vmm::Virtio_gpu_control_request::_transfer_to_host_2d() { - Transfer_to_host_2d tth { _desc_addr(0) }; - Control_header response { _desc_addr(1) }; + Transfer_to_host_2d tth { _desc_range(0) }; + Control_header response { _desc_range(1) }; uint32_t id = tth.read(); response.write(Control_header::Type::ERR_INVALID_RESOURCE_ID); diff --git a/repos/os/src/server/vmm/virtio_gpu.h b/repos/os/src/server/vmm/virtio_gpu.h index bded8e8cda..0d3ee53364 100644 --- a/repos/os/src/server/vmm/virtio_gpu.h +++ b/repos/os/src/server/vmm/virtio_gpu.h @@ -56,11 +56,12 @@ class Vmm::Virtio_gpu_control_request using Descriptor = Virtio_gpu_queue::Descriptor; using Descriptor_array = Virtio_gpu_queue::Descriptor_array; - struct Control_header : Mmio + template + struct Control_header_tpl : Mmio { - enum { SIZE = 24 }; + using Base = Mmio; - struct Type : Register<0, 32> + struct Type : Base::template Register<0, 32> { enum Commands { /* 2D commands */ @@ -95,17 +96,17 @@ class Vmm::Virtio_gpu_control_request ERR_INVALID_PARAMETER, }; }; - struct Flags : Register<0x4, 32> {}; - struct Fence_id : Register<0x8, 64> {}; - struct Ctx_id : Register<0x10, 32> {}; + struct Flags : Base::template Register<0x4, 32> {}; + struct Fence_id : Base::template Register<0x8, 64> {}; + struct Ctx_id : Base::template Register<0x10, 32> {}; - using Mmio::Mmio; + using Base::Mmio; }; - struct Display_info_response : Control_header - { - enum { SIZE = Control_header::SIZE + 24*16 }; + using Control_header = Control_header_tpl<24>; + struct Display_info_response : Control_header_tpl + { struct X : Register<0x18, 32> {}; struct Y : Register<0x1c, 32> {}; struct Width : Register<0x20, 32> {}; @@ -113,13 +114,11 @@ class Vmm::Virtio_gpu_control_request struct Enabled : Register<0x28, 32> {}; struct Flags : Register<0x2c, 32> {}; - using Control_header::Control_header; + using Control_header_tpl::Control_header_tpl; }; - struct Resource_create_2d : Control_header + struct Resource_create_2d : Control_header_tpl { - enum { SIZE = Control_header::SIZE + 16 }; - struct Resource_id : Register<0x18, 32> {}; struct Format : Register<0x1c, 32> @@ -139,42 +138,34 @@ class Vmm::Virtio_gpu_control_request struct Width : Register<0x20, 32> {}; struct Height : Register<0x24, 32> {}; - using Control_header::Control_header; + using Control_header_tpl::Control_header_tpl; }; - struct Resource_unref : Control_header + struct Resource_unref : Control_header_tpl { - enum { SIZE = Control_header::SIZE + 8 }; - struct Resource_id : Register<0x18, 32> {}; - using Control_header::Control_header; + using Control_header_tpl::Control_header_tpl; }; - struct Resource_attach_backing : Control_header + struct Resource_attach_backing : Control_header_tpl { - enum { SIZE = Control_header::SIZE + 8 }; - struct Resource_id : Register<0x18, 32> {}; struct Nr_entries : Register<0x1c, 32> {}; - struct Memory_entry : Mmio + struct Memory_entry : Mmio<16> { - enum { SIZE = 16 }; - struct Address : Register<0x0, 64> {}; struct Length : Register<0x8, 32> {}; using Mmio::Mmio; }; - using Control_header::Control_header; + using Control_header_tpl::Control_header_tpl; }; - struct Set_scanout : Control_header + struct Set_scanout : Control_header_tpl { - enum { SIZE = Control_header::SIZE + 24 }; - struct X : Register<0x18, 32> {}; struct Y : Register<0x1c, 32> {}; struct Width : Register<0x20, 32> {}; @@ -182,26 +173,22 @@ class Vmm::Virtio_gpu_control_request struct Scanout_id : Register<0x28, 32> {}; struct Resource_id : Register<0x2c, 32> {}; - using Control_header::Control_header; + using Control_header_tpl::Control_header_tpl; }; - struct Resource_flush : Control_header + struct Resource_flush : Control_header_tpl { - enum { SIZE = Control_header::SIZE + 24 }; - struct X : Register<0x18, 32> {}; struct Y : Register<0x1c, 32> {}; struct Width : Register<0x20, 32> {}; struct Height : Register<0x24, 32> {}; struct Resource_id : Register<0x28, 32> {}; - using Control_header::Control_header; + using Control_header_tpl::Control_header_tpl; }; - struct Transfer_to_host_2d :Control_header + struct Transfer_to_host_2d :Control_header_tpl { - enum { SIZE = Control_header::SIZE + 32 }; - struct X : Register<0x18, 32> {}; struct Y : Register<0x1c, 32> {}; struct Width : Register<0x20, 32> {}; @@ -209,7 +196,7 @@ class Vmm::Virtio_gpu_control_request struct Offset : Register<0x28, 64> {}; struct Resource_id : Register<0x30, 32> {}; - using Control_header::Control_header; + using Control_header_tpl::Control_header_tpl; }; Descriptor_array & _array; @@ -232,14 +219,14 @@ class Vmm::Virtio_gpu_control_request return _array.get(idx); } - addr_t _desc_addr(unsigned i) + Byte_range_ptr _desc_range(unsigned i) { Descriptor d = _desc(i); /* we only support 32-bit ram addresses by now */ - return _ram.local_address((addr_t)d.address(), d.length()); + return _ram.to_local_range({(char *)d.address(), d.length()}); } - Control_header _ctrl_hdr { _desc_addr(0) }; + Control_header _ctrl_hdr { _desc_range(0) }; void _get_display_info(); void _resource_create_2d(); diff --git a/repos/os/src/server/vmm/virtio_input.h b/repos/os/src/server/vmm/virtio_input.h index 36afc210ed..9433ed74e4 100644 --- a/repos/os/src/server/vmm/virtio_input.h +++ b/repos/os/src/server/vmm/virtio_input.h @@ -67,10 +67,8 @@ class Vmm::Virtio_input_device : public Virtio_device Cpu::Signal_handler _handler; - struct Virtio_input_event : Mmio + struct Virtio_input_event : Mmio<8> { - enum { SIZE = 8 }; - struct Type : Register<0, 16> {}; struct Code : Register<2, 16> {}; struct Value : Register<4, 32> {}; @@ -213,20 +211,20 @@ class Vmm::Virtio_input_device : public Virtio_device if (!_queue[0].constructed()) return; - bool irq = _queue[0]->notify([&] (addr_t addr, size_t size) { - if (size < Virtio_input_event::SIZE) { - warning("wrong virtioqueue packet size for input ", size); + bool irq = _queue[0]->notify([&] (Byte_range_ptr const &data) { + if (data.num_bytes < Virtio_input_event::SIZE) { + warning("wrong virtioqueue packet size for input ", data.num_bytes); return 0UL; } - Virtio_input_event vie(addr); + Virtio_input_event vie(data); if (_state == IN_MOTION) { vie.write(Linux_evdev::EV_ABS); vie.write(Linux_evdev::ABS_Y); vie.write(_motion_y); _state = SYNC; - return size; + return data.num_bytes; } if (_state == SYNC) { @@ -234,7 +232,7 @@ class Vmm::Virtio_input_device : public Virtio_device vie.write(0); vie.write(0); _state = READY; - return size; + return data.num_bytes; } if (_num_events == _idx_events) { @@ -269,7 +267,7 @@ class Vmm::Virtio_input_device : public Virtio_device _motion_y = y; _state = IN_MOTION; }); - return size; + return data.num_bytes; }); if (irq) _buffer_notification(); diff --git a/repos/os/src/server/vmm/virtio_net.h b/repos/os/src/server/vmm/virtio_net.h index 8a67f66c37..81db2f2486 100644 --- a/repos/os/src/server/vmm/virtio_net.h +++ b/repos/os/src/server/vmm/virtio_net.h @@ -51,21 +51,21 @@ class Vmm::Virtio_net : public Virtio_device void _rx() { /* RX */ - auto recv = [&] (addr_t data, size_t size) + auto recv = [&] (Byte_range_ptr const &data) { if (!_nic.rx()->packet_avail() || !_nic.rx()->ready_to_ack()) return 0ul; Nic::Packet_descriptor const rx_packet = _nic.rx()->get_packet(); - size_t sz = Genode::min(size, rx_packet.size() + NIC_HEADER_SIZE); + size_t sz = Genode::min(data.num_bytes, rx_packet.size() + NIC_HEADER_SIZE); - Genode::memcpy((void *)(data + NIC_HEADER_SIZE), + Genode::memcpy((void *)(data.start + NIC_HEADER_SIZE), _nic.rx()->packet_content(rx_packet), sz - NIC_HEADER_SIZE); _nic.rx()->acknowledge_packet(rx_packet); - Genode::memset((void*)data, 0, NIC_HEADER_SIZE); + Genode::memset((void*)data.start, 0, NIC_HEADER_SIZE); return sz; }; @@ -79,22 +79,22 @@ class Vmm::Virtio_net : public Virtio_device void _tx() { - auto send = [&] (addr_t data, size_t size) + auto send = [&] (Byte_range_ptr const &data) { if (!_nic.tx()->ready_to_submit()) return 0lu; - data += NIC_HEADER_SIZE; size -= NIC_HEADER_SIZE; + Byte_range_ptr body {data.start + NIC_HEADER_SIZE, data.num_bytes - NIC_HEADER_SIZE}; Nic::Packet_descriptor tx_packet; try { - tx_packet = _nic.tx()->alloc_packet(size); } + tx_packet = _nic.tx()->alloc_packet(body.num_bytes); } catch (Nic::Session::Tx::Source::Packet_alloc_failed) { return 0ul; } Genode::memcpy(_nic.tx()->packet_content(tx_packet), - (void *)data, size); + (void *)body.start, body.num_bytes); _nic.tx()->submit_packet(tx_packet); - return size; + return body.num_bytes; }; if (!_queue[TX].constructed()) return; diff --git a/repos/os/src/server/vmm/vm.cc b/repos/os/src/server/vmm/vm.cc index 790888b2e4..29e8bcace7 100644 --- a/repos/os/src/server/vmm/vm.cc +++ b/repos/os/src/server/vmm/vm.cc @@ -61,7 +61,7 @@ Genode::addr_t Vm::_dtb_offset() const void Vm::_load_kernel() { - memcpy((void*)(_ram.local() + KERNEL_OFFSET), + memcpy((void*)(_ram.local_base() + KERNEL_OFFSET), _kernel_rom.local_addr(), _kernel_rom.size()); } @@ -72,15 +72,15 @@ void Vm::_load_initrd() return; _initrd_rom.construct(_env, _config.initrd_name()); - memcpy((void*)(_ram.local() + _initrd_offset()), + memcpy((void*)(_ram.local_base() + _initrd_offset()), _initrd_rom->local_addr(), _initrd_size()); } void Vm::_load_dtb() { - Fdt_generator fdt(_env, _heap, _ram.local() + _dtb_offset(), 1 << LOG2_2MB); - fdt.generate(_config, (void*)(_ram.base() + _initrd_offset()), + Fdt_generator fdt(_env, _heap, _ram.local_base() + _dtb_offset(), 1 << LOG2_2MB); + fdt.generate(_config, (void*)(_ram.guest_base() + _initrd_offset()), _initrd_size()); } diff --git a/repos/os/src/server/vmm/vm.h b/repos/os/src/server/vmm/vm.h index d5f7bbf6b1..2ffbd8e512 100644 --- a/repos/os/src/server/vmm/vm.h +++ b/repos/os/src/server/vmm/vm.h @@ -57,8 +57,7 @@ class Vmm::Vm Attached_rom_dataspace _kernel_rom { _env, _config.kernel_name() }; Attached_ram_dataspace _vm_ram { _env.ram(), _env.rm(), _config.ram_size(), CACHED }; - Ram _ram { RAM_START, _config.ram_size(), - (addr_t)_vm_ram.local_addr()}; + Ram _ram { RAM_START, {_vm_ram.local_addr(), _config.ram_size()}}; Mmio_bus _bus {}; Gic _gic; List _cpu_list {}; @@ -99,11 +98,11 @@ class Vmm::Vm } addr_t dtb_addr() { - return _ram.base() + _dtb_offset(); + return _ram.guest_base() + _dtb_offset(); } addr_t kernel_addr() { - return _ram.base() + KERNEL_OFFSET; + return _ram.guest_base() + KERNEL_OFFSET; } }; diff --git a/repos/os/src/test/platform_drv/main.cc b/repos/os/src/test/platform_drv/main.cc index f859c9ed4b..30b0be207d 100644 --- a/repos/os/src/test/platform_drv/main.cc +++ b/repos/os/src/test/platform_drv/main.cc @@ -32,9 +32,9 @@ struct Main { struct Device { - Constructible device {}; - Constructible mmio {}; - Constructible irq {}; + Constructible device {}; + Constructible > mmio {}; + Constructible irq {}; Device(Platform::Connection & plat, Platform::Device::Name name) { @@ -44,7 +44,7 @@ struct Main return; } - mmio.construct(*device, Platform::Device::Mmio::Index{0}); + mmio.construct(*device, Platform::Device::Mmio<0>::Index{0}); irq.construct(*device, Platform::Device::Irq::Index{0}); } diff --git a/repos/pc/src/drivers/platform/pc/intel/io_mmu.cc b/repos/pc/src/drivers/platform/pc/intel/io_mmu.cc index ee8b762dc3..7ddb3aa208 100644 --- a/repos/pc/src/drivers/platform/pc/intel/io_mmu.cc +++ b/repos/pc/src/drivers/platform/pc/intel/io_mmu.cc @@ -409,7 +409,7 @@ Intel::Io_mmu::Io_mmu(Env & env, Device::Io_mem::Range range, Context_table_allocator & table_allocator, unsigned irq_number) -: Attached_mmio(env, range.start, range.size), +: Attached_mmio(env, {(char *)range.start, range.size}), Driver::Io_mmu(io_mmu_devices, name), _env(env), _managed_root_table(_env, table_allocator, *this, !coherent_page_walk()), diff --git a/repos/pc/src/drivers/platform/pc/intel/io_mmu.h b/repos/pc/src/drivers/platform/pc/intel/io_mmu.h index 42ad666c53..b831f4d042 100644 --- a/repos/pc/src/drivers/platform/pc/intel/io_mmu.h +++ b/repos/pc/src/drivers/platform/pc/intel/io_mmu.h @@ -44,7 +44,7 @@ namespace Intel { } -class Intel::Io_mmu : private Attached_mmio, +class Intel::Io_mmu : private Attached_mmio<0x800>, public Driver::Io_mmu, private Translation_table_registry { diff --git a/repos/ports/src/test/microcode/main.cc b/repos/ports/src/test/microcode/main.cc index fc23664ef5..70c536b00e 100644 --- a/repos/ports/src/test/microcode/main.cc +++ b/repos/ports/src/test/microcode/main.cc @@ -20,7 +20,7 @@ using Genode::uint8_t; -struct Microcode : Genode::Mmio +struct Microcode : Genode::Mmio<36> { struct Version : Register< 0, 32> { }; struct Revision : Register< 4, 32> { }; @@ -43,7 +43,7 @@ struct Microcode : Genode::Mmio struct Datasize : Register<28, 32> { }; struct Totalsize : Register<32, 32> { }; - Microcode(Genode::addr_t const addr) : Mmio(addr) { } + using Mmio::Mmio; }; static void read_micro_code_rom(Genode::Env &env, Genode::String<9> &rom_name, @@ -55,7 +55,7 @@ static void read_micro_code_rom(Genode::Env &env, Genode::String<9> &rom_name, try { Attached_rom_dataspace mc_rom(env, rom_name.string()); - Microcode mc_bits(reinterpret_cast(mc_rom.local_addr())); + Microcode mc_bits({mc_rom.local_addr(), mc_rom.size()}); unsigned total_size = mc_bits.read(); unsigned data_size = mc_bits.read();