From 1336b0a751c51b4a3e4efe00caf6fdf31d4b24d6 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Wed, 10 Jan 2024 15:08:53 +0100 Subject: [PATCH] mmio: upper-bounds checks The classes Genode::Mmio, Genode::Register_set, Genode::Attached_mmio, and Platform::Device::Mmio now receive a template parameter 'size_t SIZE'. In each type that derives from one of these classes, it is now statically checked that the range of each Genode::Register::Register- and Genode::Register_set::Register_array-deriving sub-type is within [0..SIZE). That said, SIZE is the minimum size of the memory region provided to the above mentioned Mmio classes in order to avoid page faults or memory corruption when accessing the registers and register arrays declared inside. Note, that the range end of a register array is not the end of the last item but the end of integer access that is used for accessing the last bit in the last item. The constructors of Genode::Mmio, Genode::Attached_mmio, and Platform::Device::Mmio now receive an argument 'Byte_range_ptr range' that is expected to be the range of the backing memory region. In each type that derives from on of these classes, it is now dynamically checked that 'range.num_bytes >= SIZE', thereby implementing the above mention protection against page faults and memory corruption. The rest of the commit adapts the code throughout the Genode Labs repositories regarding the changes. Note that for that code inside Core, the commits mostly uses a simplified approach by constructing MMIO objects with range [base..base+SIZE) and not with a mapping- or specification-related range size. This should be fixed in the future. Furthermore, there are types that derive from an MMIO class but don't declare any registers or register arrays (especially with Platform::Device::Mmio). In this case SIZE is set to 0. This way, the parameters must be actively corrected by someone who later wants to add registers or register arrays, plus the places can be easily found by grep'ing for Mmio<0>. Fix #4081 --- .../bootstrap/board/imx7d_sabre/platform.cc | 4 +- .../src/bootstrap/board/pbxa9/platform.cc | 4 +- .../src/bootstrap/spec/arm/cortex_a9_mmu.cc | 4 +- repos/base-hw/src/bootstrap/spec/arm/gicv3.cc | 12 +- .../src/bootstrap/spec/arm/imx_aipstz.h | 4 +- .../base-hw/src/bootstrap/spec/arm/imx_csu.h | 4 +- .../src/bootstrap/spec/arm/imx_tzic.cc | 2 +- .../src/bootstrap/spec/x86_64/multiboot.h | 8 +- .../src/bootstrap/spec/x86_64/multiboot2.h | 19 +- .../src/bootstrap/spec/x86_64/platform.cc | 4 +- .../core/spec/arm/cortex_a9_global_timer.cc | 2 +- .../core/spec/arm/cortex_a9_global_timer.h | 2 +- repos/base-hw/src/core/spec/arm/gicv3.cc | 6 +- repos/base-hw/src/core/spec/arm/imx_epit.cc | 2 +- repos/base-hw/src/core/spec/arm/imx_epit.h | 2 +- repos/base-hw/src/core/spec/arm/imx_tzic.cc | 2 +- .../src/core/spec/arm/virtualization/gicv2.cc | 2 +- .../src/core/spec/arm/virtualization/gicv2.h | 2 +- repos/base-hw/src/core/spec/riscv/pic.cc | 2 +- repos/base-hw/src/core/spec/x86_64/fpu.h | 6 +- repos/base-hw/src/core/spec/x86_64/pic.cc | 5 +- repos/base-hw/src/core/spec/x86_64/pic.h | 5 +- repos/base-hw/src/core/spec/x86_64/pit.cc | 2 +- repos/base-hw/src/core/spec/x86_64/pit.h | 2 +- .../spec/x86_64/virtualization/kernel/svm.cc | 2 +- .../src/core/spec/x86_64/virtualization/svm.h | 5 +- repos/base-hw/src/include/hw/spec/arm/gicv2.h | 8 +- repos/base-hw/src/include/hw/spec/arm/gicv3.h | 15 +- .../src/include/hw/spec/arm/imx_tzic.h | 2 +- repos/base-hw/src/include/hw/spec/arm/pl310.h | 4 +- .../base-hw/src/include/hw/spec/x86_64/acpi.h | 16 +- .../src/include/hw/spec/x86_64/x86_64.h | 1 + repos/base/include/drivers/uart/imx.h | 4 +- repos/base/include/drivers/uart/pl011.h | 6 +- repos/base/include/spec/x86/bios_data_area.h | 8 +- repos/base/include/util/mmio.h | 49 +++-- repos/base/include/util/register_set.h | 78 ++++---- repos/base/src/test/mmio/main.cc | 6 +- repos/base/src/timer/epit/imx6/timer.cc | 2 +- repos/base/src/timer/epit/time_source.h | 3 +- repos/dde_bsd/src/lib/audio/pci.cc | 6 +- .../dde_ipxe/src/lib/dde_ipxe/dde_support.cc | 2 +- repos/dde_linux/src/include/lx_kit/device.h | 4 +- repos/os/include/os/attached_mmio.h | 12 +- repos/os/include/pci/config.h | 97 +++++---- repos/os/include/platform_session/device.h | 9 +- repos/os/include/virtio/mmio_device.h | 4 +- repos/os/include/virtio/pci_device.h | 20 +- repos/os/src/app/pci_decode/main.cc | 30 +-- repos/os/src/drivers/acpi/acpi.cc | 185 +++++++++--------- repos/os/src/drivers/ahci/ahci.h | 128 ++++++------ repos/os/src/drivers/ahci/ata_protocol.h | 12 +- repos/os/src/drivers/ahci/atapi_protocol.h | 20 +- repos/os/src/drivers/ahci/main.cc | 8 +- .../os/src/drivers/framebuffer/pl11x/main.cc | 12 +- repos/os/src/drivers/framebuffer/ram/main.cc | 46 ++--- repos/os/src/drivers/gpio/rpi/gpio.h | 4 +- repos/os/src/drivers/gpu/intel/context.h | 51 ++--- repos/os/src/drivers/gpu/intel/main.cc | 20 +- repos/os/src/drivers/gpu/intel/mmio.h | 13 +- .../src/drivers/gpu/intel/platform_session.h | 24 +-- repos/os/src/drivers/gpu/intel/ring_buffer.h | 4 +- repos/os/src/drivers/i2c/imx8q_evk/mmio.h | 4 +- repos/os/src/drivers/nic/lan9118/lan9118.h | 18 +- repos/os/src/drivers/nic/lan9118/main.cc | 14 +- repos/os/src/drivers/nvme/main.cc | 184 +++++++++-------- repos/os/src/drivers/platform/pci.cc | 23 ++- repos/os/src/drivers/platform/pci_ehci.h | 20 +- repos/os/src/drivers/platform/pci_hd_audio.h | 4 +- .../src/drivers/platform/pci_intel_graphics.h | 8 +- repos/os/src/drivers/platform/pci_uhci.h | 8 +- repos/os/src/drivers/platform/pci_virtio.h | 18 +- repos/os/src/drivers/ps2/pl050/main.cc | 4 +- repos/os/src/drivers/ps2/pl050/pl050.h | 6 +- repos/os/src/drivers/sd_card/imx/driver.cc | 2 +- repos/os/src/drivers/sd_card/imx/driver.h | 4 +- repos/os/src/drivers/sd_card/pl180/driver.cc | 2 +- repos/os/src/drivers/sd_card/pl180/driver.h | 2 +- repos/os/src/drivers/sd_card/sd_card.h | 4 +- .../os/src/drivers/touch/synaptics_dsx/i2c.h | 4 +- repos/os/src/drivers/usb_block/cbw_csw.h | 70 +++---- repos/os/src/drivers/usb_block/main.cc | 36 ++-- repos/os/src/drivers/usb_block/scsi.h | 56 +++--- repos/os/src/drivers/virtdev_rom/main.cc | 8 +- repos/os/src/server/part_block/ahdi.h | 4 +- repos/os/src/server/part_block/block.h | 19 +- repos/os/src/server/part_block/gpt.h | 30 +-- repos/os/src/server/part_block/mbr.h | 19 +- .../src/server/part_block/partition_table.h | 2 +- repos/os/src/server/tz_vmm/spec/imx53/m4if.h | 6 +- repos/os/src/server/tz_vmm/spec/imx53/main.cc | 2 +- repos/os/src/server/vmm/fdt.cc | 79 ++++---- repos/os/src/server/vmm/ram.h | 35 ++-- repos/os/src/server/vmm/virtio_block.h | 3 +- repos/os/src/server/vmm/virtio_console.h | 10 +- repos/os/src/server/vmm/virtio_device.h | 43 ++-- repos/os/src/server/vmm/virtio_gpu.cc | 35 ++-- repos/os/src/server/vmm/virtio_gpu.h | 69 +++---- repos/os/src/server/vmm/virtio_input.h | 18 +- repos/os/src/server/vmm/virtio_net.h | 18 +- repos/os/src/server/vmm/vm.cc | 8 +- repos/os/src/server/vmm/vm.h | 7 +- repos/os/src/test/platform_drv/main.cc | 8 +- .../src/drivers/platform/pc/intel/io_mmu.cc | 2 +- .../pc/src/drivers/platform/pc/intel/io_mmu.h | 2 +- repos/ports/src/test/microcode/main.cc | 6 +- 106 files changed, 1013 insertions(+), 938 deletions(-) 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();