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
This commit is contained in:
Martin Stein 2024-01-10 15:08:53 +01:00 committed by Christian Helmuth
parent ee6f5f3b1b
commit 1336b0a751
106 changed files with 1013 additions and 938 deletions

View File

@ -218,7 +218,7 @@ unsigned Bootstrap::Platform::enable_mmu()
void Board::Cpu::wake_up_all_cpus(void * const ip) 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> 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 Gpr3 : Register<0x7c, 32> {}; /* ep core 1 */
struct Gpr4 : Register<0x80, 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>((Gpr3::access_t)entry); write<Gpr3>((Gpr3::access_t)entry);
write<Gpr4>((Gpr4::access_t)entry); write<Gpr4>((Gpr4::access_t)entry);

View File

@ -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 * read out this register and jump to it after the cpu received
* an interrupt * an interrupt
*/ */
struct System_control : Genode::Mmio struct System_control : Genode::Mmio<0x38>
{ {
struct Flagsset : Register<0x30, 32> { }; struct Flagsset : Register<0x30, 32> { };
struct Flagsclr : Register<0x34, 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<Flagsclr>(~0UL); write<Flagsclr>(~0UL);
write<Flagsset>(reinterpret_cast<Flagsset::access_t>(ip)); write<Flagsset>(reinterpret_cast<Flagsset::access_t>(ip));

View File

@ -52,7 +52,7 @@ class Cpu_counter
}; };
struct Scu : Genode::Mmio struct Scu : Genode::Mmio<0x34>
{ {
struct Cr : Register<0x0, 32> struct Cr : Register<0x0, 32>
{ {
@ -72,7 +72,7 @@ struct Scu : Genode::Mmio
struct Cpu3_way : Bitfield<12, 4> { }; 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() void invalidate()
{ {

View File

@ -15,10 +15,14 @@
Hw::Pic::Pic() Hw::Pic::Pic()
: :
_distr(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE), _distr({(char *)Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE,
_redistr(Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE), Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_SIZE}),
_redistr_sgi(Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE + _redistr({(char *)Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_BASE,
Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE / 2), 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()) _max_irq(_distr.max_irq())
{ {
/* disable device */ /* disable device */

View File

@ -29,7 +29,7 @@ namespace Bootstrap {
} }
class Bootstrap::Aipstz : public Genode::Mmio class Bootstrap::Aipstz : public Genode::Mmio<0x54>
{ {
private: private:
@ -66,7 +66,7 @@ class Bootstrap::Aipstz : public Genode::Mmio
/** /**
* Configure this module appropriately for the first kernel run * 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 */ /* avoid AIPS intervention at any memory access */
write<Mpr1>(Mpr::ALL_UNBUFFERED_AND_FULLY_TRUSTED); write<Mpr1>(Mpr::ALL_UNBUFFERED_AND_FULLY_TRUSTED);

View File

@ -20,7 +20,7 @@
namespace Bootstrap { struct Csu; } namespace Bootstrap { struct Csu; }
struct Bootstrap::Csu : Genode::Mmio struct Bootstrap::Csu : Genode::Mmio<0x36c>
{ {
template <Genode::off_t OFF> template <Genode::off_t OFF>
struct Csl : public Register<OFF, 32> struct Csl : public Register<OFF, 32>
@ -99,7 +99,7 @@ struct Bootstrap::Csu : Genode::Mmio
bool secure_uart, bool secure_uart,
bool secure_gpio, bool secure_gpio,
bool secure_esdhc, 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) */ /* Power (CCM, SRC, DPLLIP1-4, GPC and OWIRE) */
write<Csl09::Slave_a>(Csl00::UNSECURE); write<Csl09::Slave_a>(Csl00::UNSECURE);

View File

@ -15,7 +15,7 @@
Hw::Pic::Pic() 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++) { for (unsigned i = 0; i < NR_OF_IRQ; i++) {
write<Intsec::Nonsecure>(!Board::secure_irq(i), i); write<Intsec::Nonsecure>(!Board::secure_irq(i), i);

View File

@ -21,7 +21,7 @@
namespace Genode { class Multiboot_info; } namespace Genode { class Multiboot_info; }
class Genode::Multiboot_info : Mmio class Genode::Multiboot_info : Mmio<0x34>
{ {
private: private:
@ -39,17 +39,17 @@ class Genode::Multiboot_info : Mmio
MAGIC = 0x2badb002, 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); Multiboot_info(addr_t mbi, bool strip);
struct Mmap : Genode::Mmio struct Mmap : Genode::Mmio<0x1c>
{ {
struct Size : Register <0x00, 32> { }; struct Size : Register <0x00, 32> { };
struct Addr : Register <0x04, 64> { }; struct Addr : Register <0x04, 64> { };
struct Length : Register <0x0c, 64> { }; struct Length : Register <0x0c, 64> { };
struct Type : Register <0x14, 8> { enum { MEMORY = 1 }; }; 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}) { }
}; };
/** /**

View File

@ -19,13 +19,14 @@
namespace Genode { class Multiboot2_info; } namespace Genode { class Multiboot2_info; }
class Genode::Multiboot2_info : Mmio class Genode::Multiboot2_info : Mmio<0x8>
{ {
private: private:
struct Size : Register <0x0, 32> { }; struct Size : Register <0x0, 32> { };
struct Tag : Genode::Mmio template <size_t SIZE>
struct Tag_tpl : Genode::Mmio<SIZE>
{ {
enum { LOG2_SIZE = 3 }; enum { LOG2_SIZE = 3 };
@ -42,21 +43,23 @@ class Genode::Multiboot2_info : Mmio
}; };
struct Size : Register <0x04, 32> { }; struct Size : Register <0x04, 32> { };
Tag(addr_t addr) : Mmio(addr) { } Tag_tpl(addr_t addr) : Mmio<SIZE>({(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> { }; 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: public:
enum { MAGIC = 0x36d76289UL }; enum { MAGIC = 0x36d76289UL };
struct Memory : Genode::Mmio struct Memory : Genode::Mmio<0x14>
{ {
enum { SIZE = 3 * 8 }; enum { SIZE = 3 * 8 };
@ -64,10 +67,10 @@ class Genode::Multiboot2_info : Mmio
struct Size : Register <0x08, 64> { }; struct Size : Register <0x08, 64> { };
struct Type : Register <0x10, 32> { enum { MEMORY = 1 }; }; 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 <typename FUNC_MEM, template <typename FUNC_MEM,
typename FUNC_ACPI, typename FUNC_ACPI,

View File

@ -272,7 +272,7 @@ Bootstrap::Platform::Board::Board()
} }
struct Lapic : Mmio struct Lapic : Mmio<Hw::Cpu_memory_map::LAPIC_SIZE>
{ {
struct Svr : Register<0x0f0, 32> struct Svr : Register<0x0f0, 32>
{ {
@ -299,7 +299,7 @@ struct Lapic : Mmio
struct Destination : Bitfield<24, 8> { }; struct Destination : Bitfield<24, 8> { };
}; };
Lapic(addr_t const addr) : Mmio(addr) { } Lapic(addr_t const addr) : Mmio({(char *)addr, Mmio::SIZE}) { }
}; };

View File

@ -35,7 +35,7 @@ enum {
Board::Timer::Timer(unsigned cpu_id) 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 }; enum { PRESCALER = Board::CORTEX_A9_GLOBAL_TIMER_DIV - 1 };

View File

@ -26,7 +26,7 @@ namespace Board { class Timer; }
/** /**
* Timer driver for core * Timer driver for core
*/ */
struct Board::Timer : Genode::Mmio struct Board::Timer : Genode::Mmio<0x18>
{ {
/** /**
* Counter value registers * Counter value registers

View File

@ -27,9 +27,9 @@ static inline addr_t redistributor_addr()
Hw::Pic::Pic() Hw::Pic::Pic()
: :
_distr(Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE)), _distr({(char *)Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE), Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_SIZE}),
_redistr(redistributor_addr()), _redistr({(char *)redistributor_addr(), Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE}),
_redistr_sgi(redistributor_addr() + 0x10000), _redistr_sgi({(char *)redistributor_addr() + 0x10000, Board::Cpu_mmio::IRQ_CONTROLLER_REDIST_SIZE - 0x10000}),
_max_irq(_distr.max_irq()) _max_irq(_distr.max_irq())
{ {
_redistributor_init(); _redistributor_init();

View File

@ -28,7 +28,7 @@ unsigned Timer::interrupt_id() const { return Board::EPIT_1_IRQ; }
Board::Timer::Timer(unsigned) 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(); init();
} }

View File

@ -23,7 +23,7 @@ namespace Board { class Timer; }
/** /**
* Timer driver for core * Timer driver for core
*/ */
struct Board::Timer : Genode::Mmio struct Board::Timer : Genode::Mmio<0x14>
{ {
enum { TICS_PER_MS = 33333 }; enum { TICS_PER_MS = 33333 };

View File

@ -18,4 +18,4 @@
using namespace Core; 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}) { }

View File

@ -23,7 +23,7 @@ using Board::Pic;
Pic::Gich::Gich() 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})
{ } { }

View File

@ -29,7 +29,7 @@ class Board::Pic : public Hw::Gicv2
using uint32_t = Genode::uint32_t; using uint32_t = Genode::uint32_t;
struct Gich : Genode::Mmio struct Gich : Genode::Mmio<0x104>
{ {
struct Gich_hcr : Register<0x00, 32> { }; struct Gich_hcr : Register<0x00, 32> { };
struct Gich_vmcr : Register<0x08, 32> { }; struct Gich_vmcr : Register<0x08, 32> { };

View File

@ -17,7 +17,7 @@
Board::Pic::Pic(Global_interrupt_controller &) 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 */ /* enable external interrupts */
enum { SEIE = 0x200 }; enum { SEIE = 0x200 };

View File

@ -35,14 +35,14 @@ class Genode::Fpu_context
*/ */
char _fxsave_area[527]; char _fxsave_area[527];
struct Context : Mmio struct Context : Mmio<512>
{ {
struct Fcw : Register<0, 16> { }; struct Fcw : Register<0, 16> { };
struct Mxcsr : Register<24, 32> { }; 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<Fcw>(0x37f); /* mask exceptions SysV ABI */ write<Fcw>(0x37f); /* mask exceptions SysV ABI */
write<Mxcsr>(0x1f80); write<Mxcsr>(0x1f80);
} }

View File

@ -15,7 +15,6 @@
/* Genode includes */ /* Genode includes */
#include <irq_session/irq_session.h> #include <irq_session/irq_session.h>
#include <hw/spec/x86_64/x86_64.h>
/* core includes */ /* core includes */
#include <port_io.h> #include <port_io.h>
@ -40,7 +39,7 @@ enum {
Local_interrupt_controller:: Local_interrupt_controller::
Local_interrupt_controller(Global_interrupt_controller &global_irq_ctrl) 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 } _global_irq_ctrl { global_irq_ctrl }
{ {
init(); init();
@ -236,7 +235,7 @@ Global_interrupt_controller::_create_irt_entry(unsigned const irq)
Global_interrupt_controller::Global_interrupt_controller() 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<Ioregsel>(IOAPICVER); write<Ioregsel>(IOAPICVER);
_irte_count = read<Iowin::Maximum_redirection_entry>() + 1; _irte_count = read<Iowin::Maximum_redirection_entry>() + 1;

View File

@ -17,6 +17,7 @@
/* Genode includes */ /* Genode includes */
#include <util/mmio.h> #include <util/mmio.h>
#include <hw/spec/x86_64/x86_64.h>
namespace Board { 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<Hw::Cpu_memory_map::MMIO_IOAPIC_SIZE>
{ {
private: 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<Hw::Cpu_memory_map::LAPIC_SIZE>
{ {
private: private:

View File

@ -55,7 +55,7 @@ uint32_t Board::Timer::pit_calc_timer_freq(void)
Board::Timer::Timer(unsigned) 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(); init();
} }

View File

@ -28,7 +28,7 @@ namespace Board { class Timer; }
/** /**
* LAPIC-based timer driver for core * LAPIC-based timer driver for core
*/ */
struct Board::Timer: Genode::Mmio struct Board::Timer: Genode::Mmio<Hw::Cpu_memory_map::LAPIC_SIZE>
{ {
enum { enum {
/* PIT constants */ /* PIT constants */

View File

@ -26,7 +26,7 @@ using Board::Vmcb;
Vmcb::Vmcb(Genode::uint32_t id) Vmcb::Vmcb(Genode::uint32_t id)
: :
Mmio((Genode::addr_t)this) Mmio({(char *)this, Mmio::SIZE})
{ {
write<Guest_asid>(id); write<Guest_asid>(id);
write<Msrpm_base_pa>(dummy_msrpm()); write<Msrpm_base_pa>(dummy_msrpm());

View File

@ -77,11 +77,10 @@ struct Board::Vmcb_control_area
struct Board::Vmcb_reserved_for_host struct Board::Vmcb_reserved_for_host
{ {
/* 64bit used by the inherited Mmio class here */ /* 64bit used by the inherited Mmio class here */
Genode::uint64_t _reserved[1];
Genode::addr_t root_vmcb_phys = 0U; Genode::addr_t root_vmcb_phys = 0U;
}; };
static_assert(Board::Vmcb_control_area::total_size - 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) == sizeof(Board::Vmcb_reserved_for_host) ==
0); 0);
@ -136,7 +135,7 @@ struct Board::Vmcb_state_save_area
struct alignas(Genode::get_page_size()) Board::Vmcb struct alignas(Genode::get_page_size()) Board::Vmcb
: :
Board::Vmcb_control_area, Board::Vmcb_control_area,
public Genode::Mmio, public Genode::Mmio<Genode::get_page_size()>,
Board::Vmcb_reserved_for_host, Board::Vmcb_reserved_for_host,
Board::Vmcb_state_save_area Board::Vmcb_state_save_area
{ {

View File

@ -27,7 +27,7 @@ class Hw::Gicv2
/** /**
* Distributor of the ARM generic interrupt controller * Distributor of the ARM generic interrupt controller
*/ */
struct Distributor : Genode::Mmio struct Distributor : Genode::Mmio<0xf04>
{ {
static constexpr unsigned nr_of_irq = 1024; 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 * Return minimum IRQ priority
@ -125,7 +125,7 @@ class Hw::Gicv2
/** /**
* CPU interface of the ARM generic interrupt controller * CPU interface of the ARM generic interrupt controller
*/ */
struct Cpu_interface : Genode::Mmio struct Cpu_interface : Genode::Mmio<0x14>
{ {
/** /**
* Control register * Control register
@ -162,7 +162,7 @@ class Hw::Gicv2
struct Eoir : Register<0x10, 32, true> { struct Eoir : Register<0x10, 32, true> {
struct Irq_id : Bitfield<0,10> { }; }; 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}) { }
}; };

View File

@ -42,7 +42,7 @@ class Hw::Pic
static constexpr unsigned min_spi = 32; static constexpr unsigned min_spi = 32;
static constexpr unsigned spurious_id = 1023; static constexpr unsigned spurious_id = 1023;
struct Distributor : Genode::Mmio struct Distributor : Genode::Mmio<0x7fe0>
{ {
static constexpr unsigned nr_of_irq = 1024; static constexpr unsigned nr_of_irq = 1024;
@ -103,19 +103,17 @@ class Hw::Pic
unsigned max_irq() { return 32 * (read<Typer::It_lines_number>() + 1) - 1; } unsigned max_irq() { return 32 * (read<Typer::It_lines_number>() + 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 Ctlr : Register<0x0, 32>
{ {
struct Uwp : Bitfield<31, 1> { }; struct Uwp : Bitfield<31, 1> { };
}; };
Redistributor(Genode::addr_t const base) : Genode::Mmio(base) using Mmio::Mmio;
{ }
/* wait for upstream writes */ /* wait for upstream writes */
void wait_for_uwp() 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> { }; struct Igroupr0 : Register<0x80, 32> { };
@ -143,8 +141,7 @@ class Hw::Pic
struct Icfgr1 : Register<0xc04, 32> { }; struct Icfgr1 : Register<0xc04, 32> { };
Redistributor_sgi_ppi(Genode::addr_t const base) : Genode::Mmio(base) using Mmio::Mmio;
{ }
}; };
struct Cpu_interface struct Cpu_interface

View File

@ -19,7 +19,7 @@
namespace Hw { class Pic; } namespace Hw { class Pic; }
class Hw::Pic : public Genode::Mmio class Hw::Pic : public Genode::Mmio<0xf04>
{ {
public: public:

View File

@ -22,7 +22,7 @@
namespace Hw { struct Pl310; } namespace Hw { struct Pl310; }
class Hw::Pl310 : public Genode::Mmio class Hw::Pl310 : public Genode::Mmio<0xf64>
{ {
protected: protected:
@ -104,7 +104,7 @@ class Hw::Pl310 : public Genode::Mmio
public: public:
Pl310(Genode::addr_t const base) : Mmio(base) { } Pl310(Genode::addr_t const base) : Mmio({(char *)base, Mmio::SIZE}) { }
void enable() {} void enable() {}
void disable() {} void disable() {}

View File

@ -59,20 +59,20 @@ struct Hw::Apic_madt
Apic_madt *next() const { return reinterpret_cast<Apic_madt *>((Genode::uint8_t *)this + length); } Apic_madt *next() const { return reinterpret_cast<Apic_madt *>((Genode::uint8_t *)this + length); }
struct Ioapic : Genode::Mmio struct Ioapic : Genode::Mmio<0xc>
{ {
struct Id : Register <0x02, 8> { }; struct Id : Register <0x02, 8> { };
struct Paddr : Register <0x04, 32> { }; struct Paddr : Register <0x04, 32> { };
struct Gsi_base : Register <0x08, 32> { }; struct Gsi_base : Register <0x08, 32> { };
Ioapic(Apic_madt const * a) : Mmio(reinterpret_cast<Genode::addr_t>(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 }; }; struct Flags : Register <0x04, 32> { enum { VALID = 1 }; };
Lapic(Apic_madt const * a) : Mmio(reinterpret_cast<Genode::addr_t>(a)) { } Lapic(Apic_madt const * a) : Mmio({(char *)a, Mmio::SIZE}) { }
bool valid() { return read<Flags>() & Flags::VALID; }; bool valid() { return read<Flags>() & Flags::VALID; };
}; };
@ -81,7 +81,7 @@ struct Hw::Apic_madt
/* ACPI spec 5.2.9 and ACPI GAS 5.2.3.2 */ /* 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 }; enum Addressspace { IO = 0x1 };
@ -174,7 +174,7 @@ struct Hw::Acpi_fadt : Genode::Mmio
asm volatile ("outl %0, %w1" : : "a"(val), "Nd"(port)); 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 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 Length : Register < 0x04, 32> { };
struct Fw_wake_vector : Register < 0x0c, 32> { }; struct Fw_wake_vector : Register < 0x0c, 32> { };
@ -362,7 +362,7 @@ struct Hw::Acpi_facs : Genode::Mmio
write<Fw_wake_vector_ext>(0); write<Fw_wake_vector_ext>(0);
} }
Acpi_facs(addr_t const mmio) : Mmio(mmio) { } Acpi_facs(addr_t const mmio) : Mmio({(char *)mmio, Mmio::SIZE}) { }
}; };

View File

@ -31,6 +31,7 @@ struct Hw::Cpu_memory_map
enum { enum {
MMIO_IOAPIC_BASE = 0xfec00000, MMIO_IOAPIC_BASE = 0xfec00000,
MMIO_IOAPIC_SIZE = 0x1000, MMIO_IOAPIC_SIZE = 0x1000,
LAPIC_SIZE = 0xe34,
}; };
static Genode::addr_t lapic_phys_base() static Genode::addr_t lapic_phys_base()

View File

@ -24,7 +24,7 @@ namespace Genode { class Imx_uart; }
/** /**
* Driver base for i.MX UART-module * Driver base for i.MX UART-module
*/ */
class Genode::Imx_uart: Mmio class Genode::Imx_uart: Mmio<0xa2>
{ {
/** /**
* Control register 1 * Control register 1
@ -246,7 +246,7 @@ class Genode::Imx_uart: Mmio
* *
* \param base device MMIO base * \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(); init();
} }

View File

@ -23,7 +23,7 @@ namespace Genode { class Pl011_uart; }
/** /**
* Driver base for the PrimeCell UART PL011 Revision r1p3 * Driver base for the PrimeCell UART PL011 Revision r1p3
*/ */
class Genode::Pl011_uart : Mmio class Genode::Pl011_uart : Mmio<0x3a>
{ {
protected: protected:
@ -132,7 +132,7 @@ class Genode::Pl011_uart : Mmio
Genode::Pl011_uart::Pl011_uart(addr_t const base, uint32_t const clock, 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>(Uartcr::Uarten::bits(1) | write<Uartcr>(Uartcr::Uarten::bits(1) |
Uartcr::Txe::bits(1) | Uartcr::Txe::bits(1) |

View File

@ -22,21 +22,21 @@
namespace Genode { class Bios_data_area; } namespace Genode { class Bios_data_area; }
class Genode::Bios_data_area : Mmio class Genode::Bios_data_area : Mmio<0x12>
{ {
friend Unmanaged_singleton_constructor; friend Unmanaged_singleton_constructor;
private: private:
struct Serial_base_com1 : Register<0x400, 16> { }; struct Serial_base_com1 : Register<0x0, 16> { };
struct Equipment : Register<0x410, 16> struct Equipment : Register<0x10, 16>
{ {
struct Serial_count : Bitfield<9, 3> { }; struct Serial_count : Bitfield<9, 3> { };
}; };
static addr_t _mmio_base_virt(); 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: public:

View File

@ -15,12 +15,14 @@
#define _INCLUDE__UTIL__MMIO_H_ #define _INCLUDE__UTIL__MMIO_H_
/* Genode includes */ /* Genode includes */
#include <base/log.h>
#include <util/string.h>
#include <util/register_set.h> #include <util/register_set.h>
namespace Genode { namespace Genode {
class Mmio_plain_access; class Mmio_plain_access;
class Mmio; template <size_t> class Mmio;
} }
/** /**
@ -32,27 +34,24 @@ class Genode::Mmio_plain_access
private: 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 <typename ACCESS_T> template <typename ACCESS_T>
inline void _write(off_t const offset, ACCESS_T const value) inline void _write(off_t const offset, ACCESS_T const value)
{ {
addr_t const dst = _base + offset; *(ACCESS_T volatile *)(_range.start + offset) = value;
*(ACCESS_T volatile *)dst = value;
} }
/** /**
* Read '_ACCESS_T' typed from MMIO base + 'offset' * Read 'ACCESS_T' typed from MMIO base + 'offset'
*/ */
template <typename ACCESS_T> template <typename ACCESS_T>
inline ACCESS_T _read(off_t const &offset) const inline ACCESS_T _read(off_t const &offset) const
{ {
addr_t const dst = _base + offset; return *(ACCESS_T volatile *)(_range.start + offset);
ACCESS_T const value = *(ACCESS_T volatile *)dst;
return value;
} }
public: public:
@ -62,9 +61,16 @@ class Genode::Mmio_plain_access
* *
* \param base base address of targeted MMIO region * \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. * For further details refer to the documentation of the 'Register_set' class.
*/ */
struct Genode::Mmio : Mmio_plain_access, Register_set<Mmio_plain_access> template <Genode::size_t MMIO_SIZE>
struct Genode::Mmio : Mmio_plain_access, Register_set<Mmio_plain_access, MMIO_SIZE>
{ {
static constexpr size_t SIZE = MMIO_SIZE;
class Range_violation : Exception { };
/** /**
* Constructor * 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), Mmio_plain_access(range),
Register_set(*static_cast<Mmio_plain_access *>(this)) { } Register_set<Mmio_plain_access, SIZE>(*static_cast<Mmio_plain_access *>(this))
{
if (range.num_bytes < SIZE) {
error("MMIO range is unexpectedly too small");
throw Range_violation { };
}
}
}; };
#endif /* _INCLUDE__UTIL__MMIO_H_ */ #endif /* _INCLUDE__UTIL__MMIO_H_ */

View File

@ -23,7 +23,8 @@
namespace Genode { namespace Genode {
struct Register_set_plain_access; struct Register_set_plain_access;
template <typename> class Register_set; struct Register_set_base;
template <typename, size_t> 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 * 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', * must not define members named 'Register_base', 'Bitfield_base',
* 'Register_array_base' or 'Array_bitfield_base'. * 'Register_array_base' or 'Array_bitfield_base'.
*/ */
template <typename PLAIN_ACCESS> template <typename PLAIN_ACCESS, Genode::size_t REGISTER_SET_SIZE>
class Genode::Register_set : Noncopyable class Genode::Register_set : public Register_set_base
{ {
private: private:
@ -225,6 +241,8 @@ class Genode::Register_set : Noncopyable
typedef typename Genode::Register<_ACCESS_WIDTH>::access_t typedef typename Genode::Register<_ACCESS_WIDTH>::access_t
access_t; access_t;
static_assert(OFFSET + sizeof(access_t) <= REGISTER_SET_SIZE);
/** /**
* A region within a register * A region within a register
* *
@ -333,28 +351,27 @@ class Genode::Register_set : Noncopyable
Compound_array; Compound_array;
}; };
struct Dst { off_t offset; uint8_t shift; };
/** /**
* Calculate destination of an array-item access * 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 * \param index index of the targeted array item
*/ */
static inline void dst(off_t & offset, static constexpr Dst dst(unsigned long index)
unsigned long & shift,
unsigned long const index)
{ {
unsigned long const bit_off = index << ITEM_WIDTH_LOG2; off_t bit_offset = off_t(index << ITEM_WIDTH_LOG2);
offset = (off_t) ((bit_off >> BYTE_WIDTH_LOG2) off_t byte_offset = bit_offset >> BYTE_WIDTH_LOG2;
& ~(sizeof(access_t)-1) ); off_t offset = byte_offset & ~(sizeof(access_t) - 1);
shift = bit_off - ( offset << BYTE_WIDTH_LOG2 ); uint8_t shift = uint8_t(bit_offset - (offset << BYTE_WIDTH_LOG2));
offset += OFFSET; 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 * 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 */ /* access width and item width differ */
} else { } else {
long unsigned shift; typename Array::Dst dst { Array::dst(index) };
Array::dst(offset, shift, index); return (Plain_access::read<access_t>(_plain_access, dst.offset)
return (Plain_access::read<access_t>(_plain_access, offset) >> dst.shift) & Array::ITEM_MASK;
>> shift) & Array::ITEM_MASK;
} }
} }
@ -517,8 +533,7 @@ class Genode::Register_set : Noncopyable
/* access width and item width differ */ /* access width and item width differ */
} else { } else {
long unsigned shift; typename Array::Dst dst { Array::dst(index) };
Array::dst(offset, shift, index);
/* insert new value into old register value */ /* insert new value into old register value */
access_t write_value; access_t write_value;
@ -530,12 +545,12 @@ class Genode::Register_set : Noncopyable
/* apply bitfield to the old register value */ /* apply bitfield to the old register value */
write_value = Plain_access::read<access_t>(_plain_access, write_value = Plain_access::read<access_t>(_plain_access,
offset); dst.offset);
write_value &= ~(Array::ITEM_MASK << shift); write_value &= ~(Array::ITEM_MASK << dst.shift);
} }
/* apply bitfield value and override register */ /* apply bitfield value and override register */
write_value |= (value & Array::ITEM_MASK) << shift; write_value |= (value & Array::ITEM_MASK) << dst.shift;
Plain_access::write<access_t>(_plain_access, offset, Plain_access::write<access_t>(_plain_access, dst.offset,
write_value); write_value);
} }
} }
@ -680,17 +695,6 @@ class Genode::Register_set : Noncopyable
explicit Microseconds(uint64_t value) : value(value) { } 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 * Wait until a list of IO conditions is met

View File

@ -58,9 +58,9 @@ struct Cpu_state : Register<16>
/** /**
* Exemplary MMIO region type * Exemplary MMIO region type
*/ */
struct Test_mmio : public Mmio struct Test_mmio : public Mmio<MMIO_SIZE>
{ {
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> 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_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> struct Strict_reg : Register<0x0, 32, true>
{ {

View File

@ -27,7 +27,7 @@ using namespace Genode;
Timer::Time_source::Time_source(Env &env) 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), Signalled_time_source(env),
_timer_irq(env, unsigned(EPIT_2_IRQ)) _timer_irq(env, unsigned(EPIT_2_IRQ))
{ {

View File

@ -26,8 +26,7 @@
namespace Timer { class Time_source; } namespace Timer { class Time_source; }
class Timer::Time_source : private Genode::Attached_mmio<0x14>,
class Timer::Time_source : private Genode::Attached_mmio,
public Genode::Signalled_time_source public Genode::Signalled_time_source
{ {
private: private:

View File

@ -51,9 +51,9 @@ class Pci_driver
struct Device struct Device
{ {
Platform::Device dev; Platform::Device dev;
Platform::Device::Irq irq; Platform::Device::Irq irq;
Platform::Device::Mmio mmio; Platform::Device::Mmio<0> mmio;
Device(Platform::Connection &pci, Device(Platform::Connection &pci,
Platform::Device::Name const &name) Platform::Device::Name const &name)

View File

@ -148,7 +148,7 @@ extern "C" void dde_mdelay(unsigned long msecs)
struct Range { addr_t start; size_t size; }; 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; using Io_port = Platform::Device::Io_port_range;
struct Pci_driver struct Pci_driver

View File

@ -45,14 +45,14 @@ class Lx_kit::Device : List<Device>::Element
struct Io_mem : List<Io_mem>::Element struct Io_mem : List<Io_mem>::Element
{ {
using Index = Platform::Device::Mmio::Index; using Index = Platform::Device::Mmio<0>::Index;
Index idx; Index idx;
addr_t addr; addr_t addr;
size_t size; size_t size;
unsigned pci_bar; unsigned pci_bar;
Constructible<Platform::Device::Mmio> io_mem {}; Constructible<Platform::Device::Mmio<0> > io_mem {};
bool match(addr_t addr, size_t size); bool match(addr_t addr, size_t size);

View File

@ -18,7 +18,7 @@
#include <base/attached_io_mem_dataspace.h> #include <base/attached_io_mem_dataspace.h>
#include <util/mmio.h> #include <util/mmio.h>
namespace Genode { class Attached_mmio; } namespace Genode { template <size_t> class Attached_mmio; }
/** /**
@ -30,8 +30,9 @@ namespace Genode { class Attached_mmio; }
* and cast the received address. This helper undertakes all of this * and cast the received address. This helper undertakes all of this
* generic work when inheriting from it. * generic work when inheriting from it.
*/ */
template <Genode::size_t SIZE>
class Genode::Attached_mmio : public Attached_io_mem_dataspace, class Genode::Attached_mmio : public Attached_io_mem_dataspace,
public Mmio public Mmio<SIZE>
{ {
public: public:
@ -49,10 +50,9 @@ class Genode::Attached_mmio : public Attached_io_mem_dataspace,
* \throw Out_of_caps * \throw Out_of_caps
* \throw Region_map::Region_conflict * \throw Region_map::Region_conflict
*/ */
Attached_mmio(Env &env, addr_t base, size_t size, Attached_mmio(Env &env, Byte_range_ptr const &range, bool write_combined = false)
bool write_combined = false) : Attached_io_mem_dataspace(env, (addr_t)range.start, range.num_bytes, write_combined),
: Attached_io_mem_dataspace(env, base, size, write_combined), Mmio<SIZE>({local_addr<char>(), range.num_bytes}) { }
Mmio((addr_t)local_addr<void>()) { }
}; };
#endif /* _INCLUDE__OS__ATTACHED_MMIO_H_ */ #endif /* _INCLUDE__OS__ATTACHED_MMIO_H_ */

View File

@ -33,7 +33,7 @@ namespace Pci {
}; };
}; };
struct Pci::Config : Genode::Mmio struct Pci::Config : Genode::Mmio<0x45>
{ {
struct Vendor : Register<0x0, 16> struct Vendor : Register<0x0, 16>
{ {
@ -82,7 +82,7 @@ struct Pci::Config : Genode::Mmio
struct Multi_function : Bitfield<7,1> {}; struct Multi_function : Bitfield<7,1> {};
}; };
struct Base_address : Mmio struct Base_address : Mmio<0x8>
{ {
struct Bar_32bit : Register<0, 32> struct Bar_32bit : Register<0, 32>
{ {
@ -126,7 +126,7 @@ struct Pci::Config : Genode::Mmio
return _conf_value; 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; } bool valid() { return _conf() != 0; }
@ -202,7 +202,8 @@ struct Pci::Config : Genode::Mmio
** PCI Capabilities ** ** PCI Capabilities **
**********************/ **********************/
struct Pci_capability : Genode::Mmio template <Genode::size_t SIZE>
struct Pci_capability : Genode::Mmio<SIZE>
{ {
struct Id : Register<0,8> struct Id : Register<0,8>
{ {
@ -223,11 +224,17 @@ struct Pci::Config : Genode::Mmio
struct Pointer : Register<1,8> {}; struct Pointer : Register<1,8> {};
using Genode::Mmio::Mmio; using Mmio<SIZE>::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> {}; 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> 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> struct Control : Register<0x2, 16>
{ {
@ -337,7 +344,7 @@ struct Pci::Config : Genode::Mmio
struct Offset : Bitfield<3, 29> {}; struct Offset : Bitfield<3, 29> {};
}; };
struct Table_entry : Genode::Mmio struct Table_entry : Genode::Mmio<0x10>
{ {
enum { SIZE = 16 }; enum { SIZE = 16 };
@ -349,7 +356,7 @@ struct Pci::Config : Genode::Mmio
struct Mask : Bitfield <0, 1> { }; struct Mask : Bitfield <0, 1> { };
}; };
using Genode::Mmio::Mmio; using Mmio::Mmio;
}; };
using Pci_capability::Pci_capability; 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> {}; struct Capabilities : Register<0x2, 16> {};
@ -484,7 +491,8 @@ struct Pci::Config : Genode::Mmio
enum { PCI_E_EXTENDED_CAPS_OFFSET = 0x100U }; enum { PCI_E_EXTENDED_CAPS_OFFSET = 0x100U };
struct Pci_express_extended_capability : Genode::Mmio template<Genode::size_t SIZE>
struct Pci_express_extended_capability : Genode::Mmio<SIZE>
{ {
struct Id : Register<0x0, 16> struct Id : Register<0x0, 16>
{ {
@ -504,11 +512,17 @@ struct Pci::Config : Genode::Mmio
struct Offset : Bitfield<4, 12> {}; struct Offset : Bitfield<4, 12> {};
}; };
using Genode::Mmio::Mmio; using Mmio<SIZE>::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 Uncorrectable_error_status : Register<0x4, 32> {};
struct Correctable_error_status : Register<0x10, 32> {}; struct Correctable_error_status : Register<0x10, 32> {};
@ -547,8 +561,8 @@ struct Pci::Config : Genode::Mmio
Genode::Constructible<Pci_express_capability> pci_e_cap {}; Genode::Constructible<Pci_express_capability> pci_e_cap {};
Genode::Constructible<Advanced_error_reporting_capability> adv_err_cap {}; Genode::Constructible<Advanced_error_reporting_capability> adv_err_cap {};
Base_address bar0 { base() + BASE_ADDRESS_0 }; Base_address bar0 { Mmio::range_at(BASE_ADDRESS_0) };
Base_address bar1 { base() + BASE_ADDRESS_0 + 0x4 }; Base_address bar1 { Mmio::range_at(BASE_ADDRESS_0 + 0x4) };
void clear_errors() { void clear_errors() {
if (adv_err_cap.constructed()) adv_err_cap->clear(); } if (adv_err_cap.constructed()) adv_err_cap->clear(); }
@ -562,21 +576,22 @@ struct Pci::Config : Genode::Mmio
uint16_t off = read<Capability_pointer>(); uint16_t off = read<Capability_pointer>();
while (off) { while (off) {
Pci_capability cap(base() + off); using Capability_header = Pci_capability_header;
switch(cap.read<Pci_capability::Id>()) { Capability_header cap(Mmio::range_at(off));
case Pci_capability::Id::POWER_MANAGEMENT: switch(cap.read<Capability_header::Id>()) {
power_cap.construct(base()+off); break; case Capability_header::Id::POWER_MANAGEMENT:
case Pci_capability::Id::MSI: power_cap.construct(Mmio::range_at(off)); break;
msi_cap.construct(base()+off); break; case Capability_header::Id::MSI:
case Pci_capability::Id::MSI_X: msi_cap.construct(Mmio::range_at(off)); break;
msi_x_cap.construct(base()+off); break; case Capability_header::Id::MSI_X:
case Pci_capability::Id::PCI_E: msi_x_cap.construct(Mmio::range_at(off)); break;
pci_e_cap.construct(base()+off); break; case Capability_header::Id::PCI_E:
pci_e_cap.construct(Mmio::range_at(off)); break;
default: default:
/* ignore unhandled capability */ ; /* ignore unhandled capability */ ;
} }
off = cap.read<Pci_capability::Pointer>(); off = cap.read<Capability_header::Pointer>();
} }
if (!pci_e_cap.constructed()) if (!pci_e_cap.constructed())
@ -584,21 +599,22 @@ struct Pci::Config : Genode::Mmio
off = PCI_E_EXTENDED_CAPS_OFFSET; off = PCI_E_EXTENDED_CAPS_OFFSET;
while (off) { while (off) {
Pci_express_extended_capability cap(base() + off); using Capability_header = Pci_express_extended_capability_header;
switch (cap.read<Pci_express_extended_capability::Id>()) { Capability_header cap(Mmio::range_at(off));
case Pci_express_extended_capability::Id::INVALID: switch (cap.read<Capability_header::Id>()) {
case Capability_header::Id::INVALID:
return; return;
case Pci_express_extended_capability::Id::ADVANCED_ERROR_REPORTING: case Capability_header::Id::ADVANCED_ERROR_REPORTING:
adv_err_cap.construct(base() + off); break; adv_err_cap.construct(Mmio::range_at(off)); break;
default: default:
/* ignore unhandled extended capability */ ; /* ignore unhandled extended capability */ ;
} }
off = cap.read<Pci_express_extended_capability::Next_and_version::Offset>(); off = cap.read<Capability_header::Next_and_version::Offset>();
} }
} }
using Genode::Mmio::Mmio; using Mmio::Mmio;
bool valid() { bool valid() {
return read<Vendor>() != Vendor::INVALID; } return read<Vendor>() != Vendor::INVALID; }
@ -612,13 +628,12 @@ struct Pci::Config : Genode::Mmio
template <typename MEM_FN, typename IO_FN> template <typename MEM_FN, typename IO_FN>
void for_each_bar(MEM_FN const & memory, IO_FN const & io) 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 = Genode::size_t const reg_cnt =
(read<Header_type::Type>()) ? BASE_ADDRESS_COUNT_TYPE_1 (read<Header_type::Type>()) ? BASE_ADDRESS_COUNT_TYPE_1
: BASE_ADDRESS_COUNT_TYPE_0; : BASE_ADDRESS_COUNT_TYPE_0;
for (unsigned i = 0; i < reg_cnt; i++) { 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()) if (!reg0.valid())
continue; continue;
if (reg0.memory()) { if (reg0.memory()) {
@ -634,7 +649,7 @@ struct Pci::Config : Genode::Mmio
if (idx > 5 || (idx > 1 && bridge())) if (idx > 5 || (idx > 1 && bridge()))
return; return;
Base_address bar { base() + BASE_ADDRESS_0 + idx*0x4 }; Base_address bar { Mmio::range_at(BASE_ADDRESS_0 + idx*0x4) };
bar.set(addr); bar.set(addr);
} }
@ -660,10 +675,10 @@ struct Pci::Config_type0 : Pci::Config
using Pci::Config::Config; using Pci::Config::Config;
Base_address bar2 { base() + BASE_ADDRESS_0 + 0x8 }; Base_address bar2 { Mmio::range_at(BASE_ADDRESS_0 + 0x8 ) };
Base_address bar3 { base() + BASE_ADDRESS_0 + 0xc }; Base_address bar3 { Mmio::range_at(BASE_ADDRESS_0 + 0xc ) };
Base_address bar4 { base() + BASE_ADDRESS_0 + 0x10 }; Base_address bar4 { Mmio::range_at(BASE_ADDRESS_0 + 0x10) };
Base_address bar5 { base() + BASE_ADDRESS_0 + 0x14 }; Base_address bar5 { Mmio::range_at(BASE_ADDRESS_0 + 0x14) };
struct Subsystem_vendor : Register<0x2c, 16> { }; struct Subsystem_vendor : Register<0x2c, 16> { };
struct Subsystem_device : Register<0x2e, 16> { }; struct Subsystem_device : Register<0x2e, 16> { };

View File

@ -28,7 +28,7 @@ class Platform::Device : Interface, Noncopyable
{ {
public: public:
struct Mmio; template <size_t> struct Mmio;
struct Irq; struct Irq;
struct Io_port_range; struct Io_port_range;
@ -38,8 +38,6 @@ class Platform::Device : Interface, Noncopyable
typedef Device_interface::Range Range; typedef Device_interface::Range Range;
friend class Mmio;
::Platform::Connection &_platform; ::Platform::Connection &_platform;
Capability<Device_interface> _cap; Capability<Device_interface> _cap;
@ -86,7 +84,8 @@ class Platform::Device : Interface, Noncopyable
}; };
class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio template <Genode::size_t SIZE>
class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio<SIZE>
{ {
private: private:
@ -108,7 +107,7 @@ class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio
Mmio(Device &device, Index index) Mmio(Device &device, Index index)
: :
Attached_dataspace(device._rm(), _ds_cap(device, index.value)), Attached_dataspace(device._rm(), _ds_cap(device, index.value)),
Genode::Mmio(_local_addr()) Genode::Mmio<SIZE>({(char *)_local_addr(), size()})
{ } { }
explicit Mmio(Device &device) : Mmio(device, Index { 0 }) { } explicit Mmio(Device &device) : Mmio(device, Index { 0 }) { }

View File

@ -25,7 +25,7 @@ namespace Virtio {
} }
class Virtio::Device : Platform::Device::Mmio class Virtio::Device : Platform::Device::Mmio<0x200>
{ {
public: public:
@ -102,7 +102,7 @@ class Virtio::Device : Platform::Device::Mmio
Device(Platform::Device & device) Device(Platform::Device & device)
: :
Platform::Device::Mmio(device), _irq(device, {0}) Platform::Device::Mmio<SIZE>(device), _irq(device, {0})
{ {
if (read<Magic>() != VIRTIO_MMIO_MAGIC) { if (read<Magic>() != VIRTIO_MMIO_MAGIC) {
throw Invalid_device(); } throw Invalid_device(); }

View File

@ -23,7 +23,7 @@ namespace Virtio {
class Device; class Device;
} }
struct Virtio::Device_mmio : public Genode::Mmio struct Virtio::Device_mmio : public Genode::Mmio<0x100>
{ {
struct DeviceFeatureSelect : Register<0x00, 32> { }; struct DeviceFeatureSelect : Register<0x00, 32> { };
struct DeviceFeature : Register<0x04, 32> { }; struct DeviceFeature : Register<0x04, 32> { };
@ -96,13 +96,13 @@ class Virtio::Device
Platform::Device _device { _plat }; Platform::Device _device { _plat };
Platform::Device::Irq _irq { _device, { 0 } }; Platform::Device::Irq _irq { _device, { 0 } };
Constructible<Platform::Device::Mmio> _mmio[MMIO_MAX] { }; Constructible<Platform::Device::Mmio<0> > _mmio[MMIO_MAX] { };
Mmio _cfg_common { _bar_offset("common") }; Device_mmio _cfg_common { _bar_range("common") };
Mmio _dev_config { _bar_offset("device") }; Device_mmio _dev_config { _bar_range("device") };
Mmio _notify { _bar_offset("notify") }; Device_mmio _notify { _bar_range("notify") };
Mmio _isr { _bar_offset("irq_status") }; Device_mmio _isr { _bar_range("irq_status") };
size_t _notify_offset_multiplier { 0 }; size_t _notify_offset_multiplier { 0 };
template <typename FN> template <typename FN>
void with_virtio_range(String<16> type, FN const & fn) 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; unsigned idx = MMIO_MAX;
addr_t off = ~0UL; addr_t off = ~0UL;
@ -137,8 +137,8 @@ class Virtio::Device
if (!_mmio[idx].constructed()) if (!_mmio[idx].constructed())
_mmio[idx].construct(_device, _mmio[idx].construct(_device,
Platform::Device::Mmio::Index{idx}); Platform::Device::Mmio<0>::Index{idx});
return _mmio[idx]->base() + off; return _mmio[idx]->range_at(off);
} }
public: public:

View File

@ -56,7 +56,7 @@ struct Main
bus_t parse_pci_function(Bdf bdf, Config & cfg, bus_t parse_pci_function(Bdf bdf, Config & cfg,
addr_t cfg_phys_base, addr_t cfg_phys_base,
Xml_generator & generator, unsigned & msi); 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); Xml_generator & generator, unsigned & msi);
void parse_irq_override_rules(Xml_node & xml); void parse_irq_override_rules(Xml_node & xml);
@ -94,7 +94,7 @@ bus_t Main::parse_pci_function(Bdf bdf,
/* check for bridges */ /* check for bridges */
if (cfg.read<Config::Header_type::Type>()) { if (cfg.read<Config::Header_type::Type>()) {
for_bridge(bdf.bus, [&] (Bridge & parent) { for_bridge(bdf.bus, [&] (Bridge & parent) {
Config_type1 bcfg(cfg.base()); Config_type1 bcfg(cfg.range());
new (heap) Bridge(parent.sub_bridges, bdf, new (heap) Bridge(parent.sub_bridges, bdf,
bcfg.secondary_bus_number(), bcfg.secondary_bus_number(),
bcfg.subordinate_bus_number()); bcfg.subordinate_bus_number());
@ -142,7 +142,7 @@ bus_t Main::parse_pci_function(Bdf bdf,
gen.attribute("revision", string(cfg.read<Cc::Revision>())); gen.attribute("revision", string(cfg.read<Cc::Revision>()));
gen.attribute("bridge", cfg.bridge() ? "yes" : "no"); gen.attribute("bridge", cfg.bridge() ? "yes" : "no");
if (!cfg.bridge()) { if (!cfg.bridge()) {
C0 cfg0(cfg.base()); C0 cfg0(cfg.range());
gen.attribute("sub_vendor_id", gen.attribute("sub_vendor_id",
string(cfg0.read<C0::Subsystem_vendor>())); string(cfg0.read<C0::Subsystem_vendor>()));
gen.attribute("sub_device_id", 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, bus_t Main::parse_pci_bus(bus_t bus,
addr_t base, Byte_range_ptr const & range,
addr_t phys_base, addr_t phys_base,
Xml_generator & generator, Xml_generator & generator,
unsigned & msi_number) unsigned & msi_number)
{ {
bus_t max_subordinate_bus = bus; 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) { dev_t dev, func_t fn) {
Config cfg(config_base); Config cfg(config_range);
if (!cfg.valid()) if (!cfg.valid())
return true; 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 (dev_t dev = 0; dev < DEVICES_PER_BUS_MAX; dev++) {
for (func_t fn = 0; fn < FUNCTION_PER_DEVICE_MAX; fn++) { for (func_t fn = 0; fn < FUNCTION_PER_DEVICE_MAX; fn++) {
unsigned factor = dev * FUNCTION_PER_DEVICE_MAX + fn; unsigned factor = dev * FUNCTION_PER_DEVICE_MAX + fn;
addr_t config_base = base + factor * FUNCTION_CONFIG_SPACE_SIZE; off_t config_offset = factor * FUNCTION_CONFIG_SPACE_SIZE;
addr_t config_phys_base = Byte_range_ptr config_range { range.start + config_offset, range.num_bytes - config_offset };
phys_base + factor * FUNCTION_CONFIG_SPACE_SIZE; addr_t config_phys_base = phys_base + config_offset;
if (!per_function(config_base, config_phys_base, dev, fn)) if (!per_function(config_range, config_phys_base, dev, fn))
break; 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); pci_config_ds.construct(env, offset, BUS_SIZE);
bus_t const subordinate_bus = bus_t const subordinate_bus =
parse_pci_bus((bus_t)bus + bus_off, parse_pci_bus((bus_t)bus + bus_off,
(addr_t)pci_config_ds->local_addr<void>(), {pci_config_ds->local_addr<char>(), BUS_SIZE},
offset, generator, msi_number); offset, generator, msi_number);
max_subordinate_bus = max(max_subordinate_bus, subordinate_bus); max_subordinate_bus = max(max_subordinate_bus, subordinate_bus);

View File

@ -115,13 +115,13 @@ struct Generic
} __attribute__((packed)); } __attribute__((packed));
struct Dmar_common : Genode::Mmio struct Dmar_common : Genode::Mmio<0x4>
{ {
struct Type : Register<0x0, 16> { struct Type : Register<0x0, 16> {
enum { DRHD= 0U, RMRR = 0x1U, ATSR = 0x2U, RHSA = 0x3U }; }; enum { DRHD= 0U, RMRR = 0x1U, ATSR = 0x2U, RHSA = 0x3U }; };
struct Length : Register<0x2, 16> { }; 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(); addr_t addr = dmar_entry_start();
while (addr < dmar_entry_end()) { while (addr < dmar_entry_end()) {
Dmar_common dmar(addr); Dmar_common dmar({(char *)addr, dmar_entry_end() - addr});
func(dmar); func(dmar);
@ -163,38 +163,43 @@ struct Dmar_struct_header : Generic
/* Intel VT-d IO Spec - 8.3.1. */ /* 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(Byte_range_ptr const &range) : Mmio(range) { }
Device_scope(addr_t a) : Genode::Mmio(a) { }
struct Type : Register<0x0, 8> { enum { PCI_END_POINT = 0x1 }; }; struct Type : Register<0x0, 8> { enum { PCI_END_POINT = 0x1 }; };
struct Length : Register<0x1, 8> { }; struct Length : Register<0x1, 8> { };
struct Bus : Register<0x5, 8> { }; struct Bus : Register<0x5, 8> { };
struct Path : Register_array<0x6, 8, MAX_PATHS, 16> { struct Path : Genode::Mmio<0x2>
struct Dev : Bitfield<0,8> { }; {
struct Func : Bitfield<8,8> { }; Path(Byte_range_ptr const &range) : Mmio(range) { }
struct Dev : Register<0, 8> { };
struct Func : Register<1, 8> { };
uint8_t dev() const { return read<Dev >(); }
uint8_t func() const { return read<Func>(); }
}; };
unsigned count() const { void for_each_path(auto const &fn) const
unsigned const length = read<Length>(); {
if (length < 6) auto const length = read<Length>();
return 0;
unsigned paths = (read<Length>() - 6) / 2; unsigned offset = Device_scope::SIZE;
if (paths > MAX_PATHS) {
Genode::error("Device_scope: more paths (", paths, ") than" while (offset < length) {
" supported (", (int)MAX_PATHS,")"); Path const path(Mmio::range_at(offset));
return MAX_PATHS;
fn(path);
offset += Path::SIZE;
} }
return paths;
} }
}; };
/* DMA Remapping Hardware Definition - Intel VT-d IO Spec - 8.3. */ /* 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 Length : Register<0x2, 16> { };
struct Flags : Register<0x4, 8> { }; struct Flags : Register<0x4, 8> { };
@ -203,52 +208,52 @@ struct Dmar_drhd : Genode::Mmio
struct Segment : Register<0x6, 16> { }; struct Segment : Register<0x6, 16> { };
struct Phys : Register<0x8, 64> { }; struct Phys : Register<0x8, 64> { };
Dmar_drhd(addr_t a) : Genode::Mmio(a) { } Dmar_drhd(Byte_range_ptr const &range) : Mmio(range) { }
template <typename FUNC> template <typename FUNC>
void apply(FUNC const &func = [] () { } ) void apply(FUNC const &func = [] () { } )
{ {
addr_t addr = base() + 16; off_t offset = 16;
while (addr < base() + read<Length>()) { while (offset < read<Length>()) {
Device_scope scope(addr); Device_scope scope(Mmio::range_at(offset));
func(scope); func(scope);
addr = scope.base() + scope.read<Device_scope::Length>(); offset += scope.read<Device_scope::Length>();
} }
} }
}; };
/* DMA Remapping Reporting structure - Intel VT-d IO Spec - 8.3. */ /* 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 Length : Register<0x02, 16> { };
struct Base : Register<0x08, 64> { }; struct Base : Register<0x08, 64> { };
struct Limit : Register<0x10, 64> { }; struct Limit : Register<0x10, 64> { };
Dmar_rmrr(addr_t a) : Genode::Mmio(a) { } Dmar_rmrr(Byte_range_ptr const &range) : Mmio(range) { }
template <typename FUNC> template <typename FUNC>
void apply(FUNC const &func = [] () { } ) void apply(FUNC const &func = [] () { } )
{ {
addr_t addr = base() + 24; addr_t offset = 24;
while (addr < base() + read<Length>()) { while (offset < read<Length>()) {
Device_scope scope(addr); Device_scope scope(Mmio::range_at(offset));
func(scope); func(scope);
addr = scope.base() + scope.read<Device_scope::Length>(); offset += scope.read<Device_scope::Length>();
} }
} }
}; };
/* I/O Virtualization Definition Blocks for AMD IO-MMU */ /* I/O Virtualization Definition Blocks for AMD IO-MMU */
struct Ivdb : Genode::Mmio struct Ivdb : Genode::Mmio<0x4>
{ {
struct Type : Register<0x00, 8> { }; struct Type : Register<0x00, 8> { };
struct Length : Register<0x02, 16> { }; 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<Ivdb_entry>::Element
/* I/O Virtualization Reporting Structure (IVRS) for AMD IO-MMU */ /* 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 Length : Register<0x04, 32> { };
struct Ivinfo : Register<0x24, 32> { struct Ivinfo : Register<0x24, 32> {
@ -284,37 +289,33 @@ struct Ivrs : Genode::Mmio
static constexpr unsigned min_size() { return 0x30; } 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) void parse(Allocator &alloc)
{ {
addr_t addr = base() + 0x30; uint32_t offset = 0x30;
while (addr < base() + read<Ivrs::Length>()) { while (offset < read<Ivrs::Length>()) {
bool dmar = Ivinfo::Dmar::get(read<Ivinfo::Dmar>()); bool dmar = Ivinfo::Dmar::get(read<Ivinfo::Dmar>());
if (dmar) if (dmar)
Genode::warning("Predefined regions should be added to IOMMU"); Genode::warning("Predefined regions should be added to IOMMU");
Ivdb ivdb(addr); Ivdb ivdb(Mmio::range_at(offset));
uint32_t const type = ivdb.read<Ivdb::Type>(); uint32_t const type = ivdb.read<Ivdb::Type>();
uint32_t const size = ivdb.read<Ivdb::Length>(); uint32_t const size = ivdb.read<Ivdb::Length>();
Ivdb_entry::list()->insert(new (&alloc) Ivdb_entry(type)); 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> { struct Features : Register<0x70, 32> {
/* Table 5-35 Fixed ACPI Description Table Fixed Feature Flags */ /* Table 5-35 Fixed ACPI Description Table Fixed Feature Flags */
struct Reset : Bitfield<10, 1> { }; struct Reset : Bitfield<10, 1> { };
@ -328,25 +329,31 @@ struct Fadt : Genode::Mmio
struct Reset_reg : Register<0x78, 64> { }; struct Reset_reg : Register<0x78, 64> { };
struct Reset_value : Register<0x80, 8> { }; struct Reset_value : Register<0x80, 8> { };
bool dsdt_valid() { uint16_t io_port_reset() const { return read<Reset_reg>() & 0xffffu; }
return size >= Dsdt::OFFSET + Dsdt::ACCESS_WIDTH / 8; } uint8_t reset_value() const { return read<Fadt_reset::Reset_value>(); }
};
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) if (range.num_bytes < Fadt_reset::SIZE)
return false; return;
if (!read<Features::Reset>()) Fadt_reset const reset(range);
return false;
if (read<Reset_type::Address_space>() == Reset_type::Address_space::SYSTEM_IO) if (!read<Fadt_reset::Features::Reset>())
return true; return;
warning("unsupported reset mode ", read<Reset_type::Address_space>()); if (read<Fadt_reset::Reset_type::Address_space>() == Fadt_reset::Reset_type::Address_space::SYSTEM_IO)
return false; fn(reset);
} }
}; };
@ -421,16 +428,16 @@ class Pci_config_space : public List<Pci_config_space>::Element
return &_list; return &_list;
} }
struct Config_space : Mmio struct Config_space : Mmio<0x100>
{ {
struct Vendor : Register<0x00, 16> { enum { INTEL = 0x8086 }; }; struct Vendor : Register<0x00, 16> { enum { INTEL = 0x8086 }; };
struct Class : Register<0x0b, 8> { enum { DISPLAY = 0x3 }; }; struct Class : Register<0x0b, 8> { enum { DISPLAY = 0x3 }; };
struct Asls : Register<0xfc, 32> { }; 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 Minor : Register<0x16, 8> { };
struct Major : Register<0x17, 8> { }; struct Major : Register<0x17, 8> { };
@ -441,7 +448,7 @@ class Pci_config_space : public List<Pci_config_space>::Element
struct Asle_rvda : Register<0x3ba, 64> { }; struct Asle_rvda : Register<0x3ba, 64> { };
struct Asle_rvds : Register<0x3c2, 32> { }; 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) static void intel_opregion(Env &env)
@ -459,7 +466,7 @@ class Pci_config_space : public List<Pci_config_space>::Element
Attached_io_mem_dataspace pci_config(env, e->_base + Attached_io_mem_dataspace pci_config(env, e->_base +
config_offset * config_size, config_offset * config_size,
config_size); config_size);
Config_space device((addr_t)pci_config.local_addr<void>()); Config_space device({pci_config.local_addr<char>(), config_size});
if ((device.read<Config_space::Vendor>() != Config_space::Vendor::INTEL) || if ((device.read<Config_space::Vendor>() != Config_space::Vendor::INTEL) ||
(device.read<Config_space::Class>() != Config_space::Class::DISPLAY)) (device.read<Config_space::Class>() != Config_space::Class::DISPLAY))
@ -477,7 +484,7 @@ class Pci_config_space : public List<Pci_config_space>::Element
{ {
Attached_io_mem_dataspace map_asls(env, phys_asls, asls_size); Attached_io_mem_dataspace map_asls(env, phys_asls, asls_size);
Opregion opregion((addr_t)map_asls.local_addr<void>()); Opregion opregion({map_asls.local_addr<char>(), asls_size});
auto const rvda = opregion.read<Opregion::Asle_rvda>(); auto const rvda = opregion.read<Opregion::Asle_rvda>();
auto const rvds = opregion.read<Opregion::Asle_rvds>(); auto const rvds = opregion.read<Opregion::Asle_rvds>();
@ -1426,27 +1433,25 @@ class Acpi_table
if (table.is_ivrs() && Ivrs::min_size() <= table->size) { if (table.is_ivrs() && Ivrs::min_size() <= table->size) {
log("Found IVRS"); log("Found IVRS");
Ivrs ivrs(reinterpret_cast<Genode::addr_t>(table->signature)); Ivrs ivrs({(char *)table->signature, table->size});
ivrs.parse(_heap); ivrs.parse(_heap);
} }
if (table.is_facp()) { if (table.is_facp() && (Fadt::SIZE <= table->size)) {
Fadt fadt(reinterpret_cast<Genode::addr_t>(table->signature), table->size); Byte_range_ptr const range((char *)table->signature,
table->size);
if (fadt.dsdt_valid()) Fadt fadt(range);
dsdt = fadt.read<Fadt::Dsdt>();
if (fadt.io_reset_supported()) { dsdt = fadt.read<Fadt::Dsdt>();
uint16_t const reset_io_port = fadt.read<Fadt::Reset_reg>() & 0xffffu;
uint8_t const reset_value = fadt.read<Fadt::Reset_value>();
_reset_info.construct(Reset_info { .io_port = reset_io_port, _sci_int = fadt.read<Fadt::Sci_int>();
.value = reset_value }); _sci_int_valid = true;
}
if (fadt.sci_int_valid()) { fadt.detect_io_reset(range, [&](auto const &reset) {
_sci_int = fadt.read<Fadt::Sci_int>(); _reset_info.construct(Reset_info { .io_port = reset.io_port_reset(),
_sci_int_valid = true; .value = reset.reset_value() });
} });
} }
if (table.is_searched()) { 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 */ /* lambda definition for scope evaluation in rmrr */
auto func_scope = [&] (Device_scope const &scope) auto func_scope = [&] (Device_scope const &scope)
{ {
if (!scope.count())
return;
xml.node("scope", [&] () { xml.node("scope", [&] () {
xml.attribute("bus_start", scope.read<Device_scope::Bus>()); xml.attribute("bus_start", scope.read<Device_scope::Bus>());
xml.attribute("type", scope.read<Device_scope::Type>()); xml.attribute("type", scope.read<Device_scope::Type>());
for (unsigned j = 0 ; j < scope.count(); j++) {
scope.for_each_path([&](auto const &path) {
xml.node("path", [&] () { xml.node("path", [&] () {
attribute_hex(xml, "dev", attribute_hex(xml, "dev" , path.dev());
scope.read<Device_scope::Path::Dev>(j)); attribute_hex(xml, "func", path.func());
attribute_hex(xml, "func",
scope.read<Device_scope::Path::Func>(j));
}); });
} });
}); });
}; };
@ -1676,7 +1677,7 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc,
if (!ignore_drhd && if (!ignore_drhd &&
dmar.read<Dmar_common::Type>() == Dmar_common::Type::DRHD) dmar.read<Dmar_common::Type>() == Dmar_common::Type::DRHD)
{ {
Dmar_drhd drhd(dmar.base()); Dmar_drhd drhd(dmar.range());
size_t size_log2 = drhd.read<Dmar_drhd::Size::Num_pages>() + 12; size_t size_log2 = drhd.read<Dmar_drhd::Size::Num_pages>() + 12;
@ -1692,7 +1693,7 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc,
if (dmar.read<Dmar_common::Type>() != Dmar_common::Type::RMRR) if (dmar.read<Dmar_common::Type>() != Dmar_common::Type::RMRR)
return; return;
Dmar_rmrr rmrr(dmar.base()); Dmar_rmrr rmrr(dmar.range());
xml.node("rmrr", [&] () { xml.node("rmrr", [&] () {
attribute_hex(xml, "start", rmrr.read<Dmar_rmrr::Base>()); attribute_hex(xml, "start", rmrr.read<Dmar_rmrr::Base>());

View File

@ -31,7 +31,8 @@ namespace Ahci {
struct Protocol; struct Protocol;
struct Port; struct Port;
struct Port_base; template <size_t> struct Port_base_tpl;
using Port_base = Port_base_tpl<0x28>;
struct Hba; struct Hba;
using Response = Block::Request_stream::Response; using Response = Block::Request_stream::Response;
@ -42,10 +43,10 @@ namespace Ahci {
/** /**
* HBA definitions * HBA definitions
*/ */
struct Ahci::Hba : private Platform::Device::Mmio struct Ahci::Hba : private Platform::Device::Mmio<0x28>
{ {
using Platform::Device::Mmio::base; using Platform::Device::Mmio<SIZE>::base;
using Index = Platform::Device::Mmio::Index; using Index = Platform::Device::Mmio<SIZE>::Index;
Platform::Device::Irq _irq; Platform::Device::Irq _irq;
@ -85,7 +86,7 @@ struct Ahci::Hba : private Platform::Device::Mmio
Signal_context_capability cap, Signal_context_capability cap,
Platform::Connection & platform) Platform::Connection & platform)
: :
Platform::Device::Mmio(dev, _mmio_index(platform)), Platform::Device::Mmio<SIZE>(dev, _mmio_index(platform)),
_irq(dev) _irq(dev)
{ {
log("version: " log("version: "
@ -144,6 +145,8 @@ struct Ahci::Hba : private Platform::Device::Mmio
/** /**
* Ports implemented * Ports implemented
*
* Each bit set here corresponds to a port that can be accessed by software
*/ */
struct Pi : Register<0xc, 32> { }; struct Pi : Register<0xc, 32> { };
@ -176,6 +179,8 @@ struct Ahci::Hba : private Platform::Device::Mmio
/* clear status register */ /* clear status register */
ack_irq(); ack_irq();
} }
Byte_range_ptr range_at(off_t offset) const { return Platform::Device::Mmio<SIZE>::range_at(offset); }
}; };
@ -185,7 +190,7 @@ struct Ahci::Hba : private Platform::Device::Mmio
namespace Ahci { namespace Ahci {
struct Device_fis : Mmio struct Device_fis : Mmio<0x4>
{ {
struct Status : Register<0x2, 8> struct Status : Register<0x2, 8>
{ {
@ -194,12 +199,12 @@ namespace Ahci {
}; };
struct Error : Register<0x3, 8> { }; struct Error : Register<0x3, 8> { };
Device_fis(addr_t recv_base) Device_fis(Byte_range_ptr const &recv_range)
: Mmio(recv_base + 0x40) { } : 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 Type : Register<0x0, 8> { }; /* FIS type */
struct Bits : Register<0x1, 8, 1> struct Bits : Register<0x1, 8, 1>
@ -236,8 +241,8 @@ namespace Ahci {
struct Sector8_15 : Register<0xd, 8> { }; struct Sector8_15 : Register<0xd, 8> { };
struct Sector : Bitset_2<Sector0_7, Sector8_15> { }; /* sector count */ struct Sector : Bitset_2<Sector0_7, Sector8_15> { }; /* sector count */
Command_fis(addr_t base) Command_fis(Byte_range_ptr const &range)
: Mmio(base) : Mmio(range)
{ {
clear(); clear();
@ -310,7 +315,7 @@ namespace Ahci {
/** /**
* AHCI command list structure header * AHCI command list structure header
*/ */
struct Command_header : Mmio struct Command_header : Mmio<0x10>
{ {
struct Bits : Register<0x0, 16> struct Bits : Register<0x0, 16>
{ {
@ -326,7 +331,7 @@ namespace Ahci {
struct Ctba0 : Register<0x8, 32> { }; /* command table base addr (low) */ struct Ctba0 : Register<0x8, 32> { }; /* command table base addr (low) */
struct Ctba0_u0 : Register<0xc, 32> { }; /* command table base addr (upper) */ 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) void cmd_table_base(addr_t base_phys)
{ {
@ -354,7 +359,7 @@ namespace Ahci {
/** /**
* ATAPI packet 12 or 16 bytes * ATAPI packet 12 or 16 bytes
*/ */
struct Atapi_command : Mmio struct Atapi_command : Mmio<0xa>
{ {
struct Command : Register<0, 8> { }; struct Command : Register<0, 8> { };
@ -372,9 +377,9 @@ namespace Ahci {
struct Sector : Bitset_2<Sector0_7, Sector8_15> { }; struct Sector : Bitset_2<Sector0_7, Sector8_15> { };
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() void read_capacity()
@ -410,7 +415,7 @@ namespace Ahci {
/** /**
* Physical region descritpor table * Physical region descritpor table
*/ */
struct Prdt : Mmio struct Prdt : Mmio<0x10>
{ {
struct Dba : Register<0x0, 32> { }; /* data base address */ struct Dba : Register<0x0, 32> { }; /* data base address */
struct Dbau : Register<0x4, 32> { }; /* data base address upper 32 bits */ struct Dbau : Register<0x4, 32> { }; /* data base address upper 32 bits */
@ -421,8 +426,8 @@ namespace Ahci {
struct Irq : Bitfield<31,1> { }; /* interrupt completion */ struct Irq : Bitfield<31,1> { }; /* interrupt completion */
}; };
Prdt(addr_t base, addr_t phys, size_t bytes) Prdt(Byte_range_ptr const &range, addr_t phys, size_t bytes)
: Mmio(base) : Mmio(range)
{ {
uint64_t addr = phys; uint64_t addr = phys;
write<Dba>((uint32_t)addr); write<Dba>((uint32_t)addr);
@ -442,11 +447,14 @@ namespace Ahci {
/* in Genode we only need one PRD (for one packet) */ /* in Genode we only need one PRD (for one packet) */
Prdt prdt; 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, addr_t phys,
size_t bytes = 0) size_t bytes = 0)
: fis(base), atapi_cmd(base + 0x40), : fis(range), atapi_cmd({range.start + ATAPI_CMD_OFF, range.num_bytes - ATAPI_CMD_OFF}),
prdt(base + 0x80, phys, bytes) prdt({range.start + PRDT_OFF, range.num_bytes - PRDT_OFF}, phys, bytes)
{ } { }
static constexpr size_t size() { return 0x100; } static constexpr size_t size() { return 0x100; }
@ -456,8 +464,11 @@ namespace Ahci {
/** /**
* Minimalistic AHCI port structure to merely detect device signature * Minimalistic AHCI port structure to merely detect device signature
*/ */
struct Ahci::Port_base : Mmio template <Genode::size_t SIZE>
struct Ahci::Port_base_tpl : Mmio<SIZE>
{ {
using Base = Mmio<SIZE>;
/* device signature */ /* device signature */
enum Signature { enum Signature {
ATA_SIG = 0x101, ATA_SIG = 0x101,
@ -468,31 +479,26 @@ struct Ahci::Port_base : Mmio
unsigned index { }; unsigned index { };
Platform::Connection &plat; Platform::Connection &plat;
Hba &hba; Hba &hba;
Mmio::Delayer &delayer; Base::Delayer &delayer;
/** /**
* Port signature * Port signature
*/ */
struct Sig : Register<0x24, 32> { }; struct Sig : Base::template Register<0x24, 32> { };
static constexpr addr_t offset() { return 0x100; } static constexpr addr_t offset() { return 0x100; }
static constexpr size_t size() { return 0x80; } static constexpr size_t size() { return 0x80; }
Port_base(unsigned index, Platform::Connection &plat, Hba &hba, Port_base_tpl(unsigned index, Platform::Connection &plat, Hba &hba,
Mmio::Delayer &delayer) Base::Delayer &delayer)
: Mmio(hba.base() + offset() + (index * size())), : Base(hba.range_at(offset() + (index * size()))),
index(index), plat(plat), hba(hba), delayer(delayer) { } index(index), plat(plat), hba(hba), delayer(delayer) { }
bool implemented() const bool ata() const { return Base::template read<Sig>() == ATA_SIG; }
{
return hba.port_implemented(index);
}
bool ata() const { return read<Sig>() == ATA_SIG; }
bool atapi() const bool atapi() const
{ {
unsigned sig = read<Sig>(); unsigned sig = Base::template read<Sig>();
return sig == ATAPI_SIG || sig == ATAPI_SIG_QEMU; return sig == ATAPI_SIG || sig == ATAPI_SIG_QEMU;
} }
}; };
@ -513,17 +519,17 @@ struct Ahci::Protocol : Interface
/** /**
* AHCI port * AHCI port
*/ */
struct Ahci::Port : private Port_base struct Ahci::Port : private Port_base_tpl<0x3c>
{ {
using Port_base::write; using Port_base_tpl::write;
using Port_base::read; using Port_base_tpl::read;
using Port_base::wait_for_any; using Port_base_tpl::wait_for_any;
using Port_base::wait_for; using Port_base_tpl::wait_for;
using Port_base::Register_set::Polling_timeout; using Port_base_tpl::Register_set::Polling_timeout;
using Port_base::index; using Port_base_tpl::index;
using Port_base::hba; using Port_base_tpl::hba;
using Port_base::delayer; using Port_base_tpl::delayer;
using Port_base::plat; using Port_base_tpl::plat;
struct Not_ready : Exception { }; struct Not_ready : Exception { };
@ -538,10 +544,10 @@ struct Ahci::Port : private Port_base
addr_t device_info_dma_addr = 0; addr_t device_info_dma_addr = 0;
addr_t cmd_list = 0; Constructible<Byte_range_ptr> cmd_list { };
addr_t fis_base = 0; Constructible<Byte_range_ptr> fis { };
addr_t cmd_table = 0; Constructible<Byte_range_ptr> cmd_table { };
addr_t device_info = 0; Constructible<Byte_range_ptr> device_info { };
Constructible<Platform::Dma_buffer> dma_buffer { }; Constructible<Platform::Dma_buffer> dma_buffer { };
addr_t dma_base = 0; /* physical address of DMA memory */ 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, Port(Protocol &protocol, Region_map &rm, Platform::Connection & plat,
Hba &hba, Mmio::Delayer &delayer, unsigned index) Hba &hba, Mmio::Delayer &delayer, unsigned index)
: :
Port_base(index, plat, hba, delayer), Port_base_tpl(index, plat, hba, delayer),
protocol(protocol), rm(rm) protocol(protocol), rm(rm)
{ {
reset(); reset();
@ -871,11 +877,12 @@ struct Ahci::Port : private Port_base
{ {
/* command list 1K */ /* command list 1K */
addr_t phys = device_dma.dma_addr(); addr_t phys = device_dma.dma_addr();
cmd_list = addr_t(device_dma.local_addr<addr_t>()); cmd_list.construct(device_dma.local_addr<char>(), device_dma.size());
command_list_base(phys); command_list_base(phys);
/* receive FIS base 256 byte */ /* 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 * 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); fis_rcv_base(phys + 1024);
/* command table */ /* command table */
cmd_table = addr_t(cmd_dma.local_addr<addr_t>()); cmd_table.construct(cmd_dma.local_addr<char>(), cmd_dma.size());
phys = cmd_dma.dma_addr(); phys = cmd_dma.dma_addr();
/* set command table addresses in command list */ /* set command table addresses in command list */
for (unsigned i = 0; i < cmd_slots; i++) { 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())); h.cmd_table_base(phys + (i * Command_table::size()));
} }
/* dataspace for device info */ /* dataspace for device info */
device_info_dma_addr = device_info_dma.dma_addr(); device_info_dma_addr = device_info_dma.dma_addr();
device_info = addr_t(device_info_dma.local_addr<addr_t>()); device_info.construct(device_info_dma.local_addr<char>(), 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) void execute(unsigned slot)

View File

@ -29,9 +29,9 @@ namespace Ata {
/** /**
* Return data of 'identify_device' ATA command * 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 Serial_number : Register_array<0x14, 8, 20, 8> { };
struct Model_number : Register_array<0x36, 8, 40, 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 unsigned init(Port &port) override
{ {
/* identify device */ /* identify device */
Command_table table(port.command_table_addr(0), Command_table table(port.command_table_range(0),
port.device_info_dma_addr, 0x1000); port.device_info_dma_addr, 0x1000);
table.fis.identify_device(); table.fis.identify_device();
port.execute(0); port.execute(0);
@ -231,7 +231,7 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
Port::Is::Pss::Equal(1), Port::Is::Pss::Equal(1),
Port::Is::Dhrs::Equal(1)); Port::Is::Dhrs::Equal(1));
_identity.construct(port.device_info); _identity.construct(*port.device_info);
serial.construct(*_identity); serial.construct(*_identity);
model.construct(*_identity); model.construct(*_identity);
@ -316,7 +316,7 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
_slot_states |= 1u << slot; _slot_states |= 1u << slot;
/* setup fis */ /* 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 */ port.dma_base + request.offset, /* physical address */
op.count * _block_size()); op.count * _block_size());
@ -335,7 +335,7 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
} }
/* set or clear write flag in command header */ /* 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<Command_header::Bits::W>(write ? 1 : 0); header.write<Command_header::Bits::W>(write ? 1 : 0);
header.clear_byte_count(); header.clear_byte_count();

View File

@ -33,7 +33,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
void _atapi_command(Port &port) 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.atapi_command();
header.clear_byte_count(); header.clear_byte_count();
port.execute(0); port.execute(0);
@ -41,7 +41,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
void _read_sense(Port &port) 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); port.device_info_dma_addr, 0x1000);
table.fis.atapi(); table.fis.atapi();
table.atapi_cmd.read_sense(); table.atapi_cmd.read_sense();
@ -51,7 +51,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
void _test_unit_ready(Port &port) 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.fis.atapi();
table.atapi_cmd.test_unit_ready(); table.atapi_cmd.test_unit_ready();
@ -60,7 +60,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
void _read_capacity(Port &port) 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); port.device_info_dma_addr, 0x1000);
table.fis.atapi(); table.fis.atapi();
table.fis.byte_count(~0); table.fis.byte_count(~0);
@ -72,7 +72,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
void _start_unit(Port &port) 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.fis.atapi();
table.atapi_cmd.start_unit(); 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.wait_for(port.delayer, Port::Is::Dhrs::Equal(1));
port.ack_irq(); port.ack_irq();
Device_fis f(port.fis_base); Device_fis f(*port.fis);
/* check if devic is ready */ /* check if devic is ready */
if (!f.read<Device_fis::Status::Device_ready>() || f.read<Device_fis::Error>()) if (!f.read<Device_fis::Status::Device_ready>() || f.read<Device_fis::Error>())
throw Port::Polling_timeout(); throw Port::Polling_timeout();
@ -121,8 +121,8 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
Port::Is::Dhrs::Equal(1)); Port::Is::Dhrs::Equal(1));
port.ack_irq(); port.ack_irq();
_block_count = host_to_big_endian(((unsigned *)port.device_info)[0]) + 1; _block_count = host_to_big_endian(((unsigned *)port.device_info->start)[0]) + 1;
_block_size = host_to_big_endian(((unsigned *)port.device_info)[1]); _block_size = host_to_big_endian(((unsigned *)port.device_info->start)[1]);
}, },
[&] {}, 3); [&] {}, 3);
@ -158,7 +158,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
_pending.success = false; _pending.success = false;
/* setup fis */ /* setup fis */
Command_table table(port.command_table_addr(0), Command_table table(port.command_table_range(0),
port.dma_base + request.offset, port.dma_base + request.offset,
op.count * _block_size); op.count * _block_size);
table.fis.atapi(); table.fis.atapi();
@ -168,7 +168,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
table.fis.byte_count(~0); table.fis.byte_count(~0);
/* set and clear write flag in command header */ /* 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<Command_header::Bits::W>(0); header.write<Command_header::Bits::W>(0);
header.clear_byte_count(); header.clear_byte_count();

View File

@ -53,7 +53,7 @@ class Ahci::Driver : Noncopyable
Dispatch &_dispatch; Dispatch &_dispatch;
struct Timer_delayer : Mmio::Delayer, Timer::Connection struct Timer_delayer : Mmio<0>::Delayer, Timer::Connection
{ {
using Timer::Connection::Connection; using Timer::Connection::Connection;
@ -78,11 +78,11 @@ class Ahci::Driver : Noncopyable
for (unsigned index = 0; index < MAX_PORTS; index++) { for (unsigned index = 0; index < MAX_PORTS; index++) {
Port_base port(index, _plat, _hba, _delayer); if (_hba.port_implemented(index) == false)
if (port.implemented() == false)
continue; continue;
Port_base port(index, _plat, _hba, _delayer);
bool enabled = false; bool enabled = false;
if (port.ata()) { if (port.ata()) {
try { try {

View File

@ -86,12 +86,12 @@ struct Pl11x_driver::Main
using Type = Platform::Device::Type; using Type = Platform::Device::Type;
Platform::Connection _platform { _env }; Platform::Connection _platform { _env };
Platform::Device _pl11x_dev { _platform, Type { "arm,pl111" } }; Platform::Device _pl11x_dev { _platform, Type { "arm,pl111" } };
Platform::Device _sp810_dev { _platform, Type { "arm,sp810" } }; Platform::Device _sp810_dev { _platform, Type { "arm,sp810" } };
Platform::Device::Mmio _lcd_io_mem { _pl11x_dev }; Platform::Device::Mmio<0> _lcd_io_mem { _pl11x_dev };
Platform::Device::Mmio _sys_mem { _sp810_dev }; Platform::Device::Mmio<0> _sys_mem { _sp810_dev };
Platform::Dma_buffer _fb_dma { _platform, FRAMEBUFFER_SIZE, UNCACHED }; Platform::Dma_buffer _fb_dma { _platform, FRAMEBUFFER_SIZE, UNCACHED };
void _init_device(); void _init_device();

View File

@ -37,16 +37,14 @@ class Main
** Qemu firmware interface ** ** Qemu firmware interface **
*****************************/ *****************************/
struct Fw : Mmio struct Fw : Mmio<0x18>
{ {
template <typename T> template <typename T>
struct Data : Register<0x0, sizeof(T) * 8> { }; struct Data : Register<0x0, sizeof(T) * 8> { };
struct Selector : Register<0x8, 16> { }; struct Selector : Register<0x8, 16> { };
struct Dma : Register<0x10, 64> { }; struct Dma : Register<0x10, 64> { };
Fw(addr_t const base) Fw(Byte_range_ptr const &range) : Mmio(range) { }
:
Mmio(base) { }
}; };
Env &_env; Env &_env;
@ -57,10 +55,10 @@ class Main
using Type = Platform::Device::Type; using Type = Platform::Device::Type;
Platform::Connection _platform { _env }; Platform::Connection _platform { _env };
Platform::Device _fw_dev { _platform, Type { "qemu,fw-cfg-mmio" } }; Platform::Device _fw_dev { _platform, Type { "qemu,fw-cfg-mmio" } };
Platform::Device::Mmio _fw_mem { _fw_dev }; Platform::Device::Mmio<0> _fw_mem { _fw_dev };
Fw _fw { (addr_t)_fw_mem.local_addr<addr_t>() }; Fw _fw { {_fw_mem.local_addr<char>(), _fw_mem.size()} };
Platform::Dma_buffer _fb_dma { _platform, SCR_HEIGHT * SCR_STRIDE, UNCACHED }; Platform::Dma_buffer _fb_dma { _platform, SCR_HEIGHT * SCR_STRIDE, UNCACHED };
Platform::Dma_buffer _config_dma { _platform, 0x1000, UNCACHED }; Platform::Dma_buffer _config_dma { _platform, 0x1000, UNCACHED };
@ -91,15 +89,13 @@ class Main
return host_to_big_endian(_fw.read<Fw::Data<T>>()); } return host_to_big_endian(_fw.read<Fw::Data<T>>()); }
/* DMA control structure */ /* DMA control structure */
struct Fw_dma_config : Genode::Mmio struct Fw_dma_config : Genode::Mmio<0x10>
{ {
struct Control : Register<0x0, 32> { }; struct Control : Register<0x0, 32> { };
struct Length : Register<0x4, 32> { }; struct Length : Register<0x4, 32> { };
struct Address : Register<0x8, 64> { }; struct Address : Register<0x8, 64> { };
Fw_dma_config(addr_t const base) Fw_dma_config(Byte_range_ptr const &range) : Mmio(range)
:
Mmio(base)
{ {
/* set write bit */ /* set write bit */
write<Control>(host_to_big_endian(1u << 4)); write<Control>(host_to_big_endian(1u << 4));
@ -116,7 +112,7 @@ class Main
}; };
/* ramfb configuration */ /* ramfb configuration */
struct Ram_fb_config : Genode::Mmio struct Ram_fb_config : Genode::Mmio<0x1c>
{ {
struct Address : Register<0x0, 64> { }; struct Address : Register<0x0, 64> { };
struct Drm_format : Register<0x8, 32> { }; struct Drm_format : Register<0x8, 32> { };
@ -124,17 +120,15 @@ class Main
struct Height : Register<0x14, 32> { }; struct Height : Register<0x14, 32> { };
struct Stride : Register<0x18, 32> { }; struct Stride : Register<0x18, 32> { };
Ram_fb_config(addr_t const base) Ram_fb_config(Byte_range_ptr const &range) : Mmio(range)
: {
Mmio(base) enum {
{ DRM_FORMAT_ARGB8888 = 0x34325241,
enum { };
DRM_FORMAT_ARGB8888 = 0x34325241, /* RGBA32 */
}; write<Drm_format>(host_to_big_endian(DRM_FORMAT_ARGB8888));
/* RGBA32 */ write<Stride>(host_to_big_endian(SCR_STRIDE));
write<Drm_format>(host_to_big_endian(DRM_FORMAT_ARGB8888)); }
write<Stride>(host_to_big_endian(SCR_STRIDE));
}
}; };
Fw_config_file _find_ramfb() Fw_config_file _find_ramfb()
@ -173,12 +167,12 @@ class Main
addr_t config_phys = _config_dma.dma_addr(); addr_t config_phys = _config_dma.dma_addr();
addr_t fb_phys = _fb_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<Ram_fb_config::Address>(host_to_big_endian(fb_phys)); config.write<Ram_fb_config::Address>(host_to_big_endian(fb_phys));
config.write<Ram_fb_config::Width>(host_to_big_endian(SCR_WIDTH)); config.write<Ram_fb_config::Width>(host_to_big_endian(SCR_WIDTH));
config.write<Ram_fb_config::Height>(host_to_big_endian(SCR_HEIGHT)); config.write<Ram_fb_config::Height>(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<Fw_dma_config::Length>(host_to_big_endian(file.size)); fw_dma.write<Fw_dma_config::Length>(host_to_big_endian(file.size));
fw_dma.write<Fw_dma_config::Address>(host_to_big_endian(config_phys)); fw_dma.write<Fw_dma_config::Address>(host_to_big_endian(config_phys));

View File

@ -29,7 +29,7 @@ namespace Gpio {
class Reg; class Reg;
} }
class Gpio::Reg : Attached_io_mem_dataspace, Mmio class Gpio::Reg : Attached_io_mem_dataspace, Mmio<0xa0>
{ {
private: private:
@ -139,7 +139,7 @@ class Gpio::Reg : Attached_io_mem_dataspace, Mmio
addr_t base, off_t offset, size_t size) addr_t base, off_t offset, size_t size)
: :
Attached_io_mem_dataspace(env, base, size), Attached_io_mem_dataspace(env, base, size),
Mmio((addr_t)local_addr<Reg>() + offset), Mmio({local_addr<char>() + offset, size - offset}),
_delayer(env) _delayer(env)
{ } { }

View File

@ -25,9 +25,11 @@
namespace Igd { namespace Igd {
using Genode::Byte_range_ptr;
struct Context_status_qword; struct Context_status_qword;
struct Common_context_regs; template <size_t> struct Common_context_regs;
struct Generation; struct Generation;
@ -84,27 +86,30 @@ struct Igd::Context_status_qword : Genode::Register<64>
}; };
struct Igd::Common_context_regs : public Genode::Mmio template <Genode::size_t SIZE>
struct Igd::Common_context_regs : public Genode::Mmio<SIZE>
{ {
using Base = Genode::Mmio<SIZE>;
template <long int OFFSET> template <long int OFFSET>
struct Common_register : Register<OFFSET * sizeof(uint32_t), 32> { }; struct Common_register : Base::template Register<OFFSET * sizeof(uint32_t), 32> { };
template <long int OFFSET, size_t NUM> template <long int OFFSET, size_t NUM>
struct Common_register_array : Register_array<OFFSET * sizeof(uint32_t), 32, NUM, 32> { }; struct Common_register_array : Base::template Register_array<OFFSET * sizeof(uint32_t), 32, NUM, 32> { };
template <long int OFFSET, size_t NUM> template <long int OFFSET, size_t NUM>
struct Common_register_array_64 : Register_array<OFFSET * sizeof(uint32_t), 64, NUM, 64> { }; struct Common_register_array_64 : Base::template Register_array<OFFSET * sizeof(uint32_t), 64, NUM, 64> { };
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<SIZE>(range), _range(range.start, range.num_bytes) { }
addr_t base() const { return _base; } addr_t base() const { return (addr_t)_range.start; }
template <typename T> template <typename T>
void write_offset(typename T::access_t const value) void write_offset(typename T::access_t const value)
{ {
write<T>(value + T::OFFSET); Base::template write<T>(value + T::OFFSET);
} }
}; };
@ -118,7 +123,7 @@ struct Igd::Common_context_regs : public Genode::Mmio
* All engines use the same layout until offset 0x118. * All engines use the same layout until offset 0x118.
*/ */
template <Genode::addr_t RING_BASE> template <Genode::addr_t RING_BASE>
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: public:
@ -360,7 +365,7 @@ class Igd::Execlist_context : public Igd::Common_context_regs
public: 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, void setup(addr_t const ring_buffer_start,
size_t const ring_buffer_length, size_t const ring_buffer_length,
@ -461,7 +466,7 @@ class Igd::Execlist_context : public Igd::Common_context_regs
template <Genode::addr_t RING_BASE> template <Genode::addr_t RING_BASE>
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: public:
@ -596,7 +601,7 @@ class Igd::Ppgtt_context : public Igd::Common_context_regs
public: 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) 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 * 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: 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 Context_status_dwords : Common_register_array_64<16, CONTEXT_STATUS_REGISTERS> { };
struct Last_written_status_offset : Common_register<31> { }; struct Last_written_status_offset : Common_register<31> { };
Hardware_status_page(addr_t base) Hardware_status_page(Byte_range_ptr const &range)
: Common_context_regs(base) : Common_context_regs(range)
{ {
semaphore(0); 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 * 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: public:
struct Ring_head_ptr_storage : Common_register<4> { }; struct Ring_head_ptr_storage : Common_register<4> { };
Pphardware_status_page(addr_t base) Pphardware_status_page(Byte_range_ptr const &range)
: Common_context_regs(base) { } : Common_context_regs(range) { }
}; };
@ -848,11 +853,11 @@ class Igd::Rcs_context
public: public:
Rcs_context(addr_t const map_base) Rcs_context(Byte_range_ptr const &map_range)
: :
_hw_status_page (map_base), _hw_status_page (map_range),
_execlist_context(map_base + HW_STATUS_PAGE_SIZE), _execlist_context({map_range.start + HW_STATUS_PAGE_SIZE, map_range.num_bytes - HW_STATUS_PAGE_SIZE}),
_ppgtt_context (map_base + 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, void setup(addr_t const ring_buffer_start,

View File

@ -440,12 +440,12 @@ struct Igd::Device
return offset; 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; addr_t const offset = (map.map.offset + skip) * PAGE_SIZE;
if (!device._resources.with_gmadr(offset, [&](auto const addr) { if (!device._resources.with_gmadr(offset, [&](Byte_range_ptr const &range) {
fn(addr); fn(range);
})) }))
error("Gmadr object unavailable"); error("Gmadr object unavailable");
} }
@ -484,8 +484,8 @@ struct Igd::Device
void with_context(auto const &fn) void with_context(auto const &fn)
{ {
ctx.with_vaddr([&](auto const vaddr) { ctx.with_vrange([&](Byte_range_ptr const &vrange) {
auto context = CONTEXT(vaddr); auto context = CONTEXT(vrange);
fn(context); fn(context);
}); });
@ -493,8 +493,8 @@ struct Igd::Device
void with_context_ring(auto const &fn) void with_context_ring(auto const &fn)
{ {
ctx.with_vaddr([&](auto const vaddr) { ctx.with_vrange([&](Byte_range_ptr const &vrange) {
auto context = CONTEXT(vaddr); auto context = CONTEXT(vrange);
fn(context, _ring); fn(context, _ring);
}); });
@ -1247,9 +1247,9 @@ struct Igd::Device
if (!_hw_status_ctx.constructed()) if (!_hw_status_ctx.constructed())
_hw_status_ctx.construct(_md_alloc, *this, 1, 0); _hw_status_ctx.construct(_md_alloc, *this, 1, 0);
if (!_hw_status_page.constructed()) { if (!_hw_status_page.constructed()) {
/* global hw_status_ctx becomes never invalid up to now, so using vaddr is ok */ /* global hw_status_ctx becomes never invalid up to now, so using vrange is ok */
_hw_status_ctx->with_vaddr([&](auto const vaddr) { _hw_status_ctx->with_vrange([&](Byte_range_ptr const &vrange) {
_hw_status_page.construct(vaddr); _hw_status_page.construct(vrange);
}); });
} }

View File

@ -23,10 +23,15 @@
#include <types.h> #include <types.h>
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<MMIO_SIZE>
{ {
public: public:
@ -1137,7 +1142,7 @@ class Igd::Mmio : public Platform::Device::Mmio
private: private:
struct Timer_delayer : Genode::Mmio::Delayer struct Timer_delayer : Genode::Mmio<MMIO_SIZE>::Delayer
{ {
Timer::Connection _timer; Timer::Connection _timer;
Timer_delayer(Genode::Env & env) : _timer(env) { } Timer_delayer(Genode::Env & env) : _timer(env) { }
@ -1666,7 +1671,7 @@ class Igd::Mmio : public Platform::Device::Mmio
public: public:
Mmio(Platform::Device & device, Genode::Env & env) Mmio(Platform::Device & device, Genode::Env & env)
: Platform::Device::Mmio(device, {0}), _delayer(env) { } : Platform::Device::Mmio<MMIO_SIZE>(device, {0}), _delayer(env) { }
Delayer &delayer() { return _delayer; } Delayer &delayer() { return _delayer; }

View File

@ -284,15 +284,14 @@ class Platform::Resources : Noncopyable
{ {
private: private:
Env & _env; Env & _env;
Signal_context_capability const _irq_cap; Signal_context_capability const _irq_cap;
Platform::Connection _platform { _env }; Platform::Connection _platform { _env };
Reconstructible<Platform::Device> _device { _platform };
Reconstructible<Platform::Device> _device { _platform }; Reconstructible<Platform::Device::Irq> _irq { *_device };
Reconstructible<Platform::Device::Irq> _irq { *_device }; Reconstructible<Igd::Mmio> _mmio { *_device, _env };
Reconstructible<Igd::Mmio> _mmio { *_device, _env }; Reconstructible<Platform::Device::Mmio<0> > _gmadr { *_device, Platform::Device::Mmio<0>::Index(1) };
Reconstructible<Platform::Device::Mmio> _gmadr { *_device, Platform::Device::Mmio::Index(1) }; Reconstructible<Attached_dataspace> _gmadr_mem { _env.rm(), _gmadr->cap() };
Reconstructible<Attached_dataspace> _gmadr_mem { _env.rm(), _gmadr->cap() };
Region_map_client _rm_gttmm; Region_map_client _rm_gttmm;
Region_map_client _rm_gmadr; Region_map_client _rm_gmadr;
@ -384,13 +383,10 @@ class Platform::Resources : Noncopyable
__attribute__((warn_unused_result)) __attribute__((warn_unused_result))
bool with_gmadr(auto const offset, auto const &fn) bool with_gmadr(auto const offset, auto const &fn)
{ {
if (!_gmadr_mem.constructed()) if (!_gmadr.constructed() || !_gmadr_mem.constructed())
return false; return false;
auto const addr = reinterpret_cast<addr_t>(_gmadr_mem->local_addr<addr_t>()) fn({_gmadr_mem->local_addr<char>() + offset, _gmadr->size() - offset });
+ offset;
fn(addr);
return true; return true;
} }

View File

@ -45,10 +45,10 @@ class Igd::Ring_buffer
Index _head { }; Index _head { };
void with_dwords(auto const &fn) const { 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) { 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: public:

View File

@ -20,7 +20,7 @@
namespace I2c { struct Mmio; } namespace I2c { struct Mmio; }
struct I2c::Mmio: Platform::Device::Mmio struct I2c::Mmio: Platform::Device::Mmio<0x12>
{ {
struct Address : Mmio::Register<0x0, 16> { struct Address : Mmio::Register<0x0, 16> {
struct Adr : Mmio::Register<0x0, 16>::Bitfield<1, 7> {}; 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> {}; struct Data : Mmio::Register<0x10, 16> {};
Mmio(Platform::Device &device) : Platform::Device::Mmio { device } { } Mmio(Platform::Device &device) : Platform::Device::Mmio<SIZE> { device } { }
}; };
#endif /* _I2C_MMIO_H_ */ #endif /* _I2C_MMIO_H_ */

View File

@ -94,7 +94,7 @@ class Lan9118_base
{ } { }
}; };
Platform::Device::Mmio &_mmio; Platform::Device::Mmio<0> &_mmio;
Platform::Device::Irq &_irq; Platform::Device::Irq &_irq;
volatile uint32_t *_reg_base { _mmio.local_addr<uint32_t>() }; volatile uint32_t *_reg_base { _mmio.local_addr<uint32_t>() };
Timer::Connection _timer; Timer::Connection _timer;
@ -281,10 +281,10 @@ class Lan9118_base
*/ */
class Device_not_supported { }; class Device_not_supported { };
Lan9118_base(Platform::Device::Mmio &mmio, Lan9118_base(Platform::Device::Mmio<0> &mmio,
Platform::Device::Irq &irq, Platform::Device::Irq &irq,
Signal_context_capability irq_handler, Signal_context_capability irq_handler,
Env &env) Env &env)
: :
_mmio(mmio), _irq(irq), _timer(env) _mmio(mmio), _irq(irq), _timer(env)
{ {
@ -441,10 +441,10 @@ class Uplink_client : public Signal_handler<Uplink_client>,
public: public:
Uplink_client(Env &env, Uplink_client(Env &env,
Allocator &alloc, Allocator &alloc,
Platform::Device::Mmio &mmio, Platform::Device::Mmio<0> &mmio,
Platform::Device::Irq &irq) Platform::Device::Irq &irq)
: :
Signal_handler<Uplink_client> { env.ep(), *this, &Uplink_client::_handle_irq }, Signal_handler<Uplink_client> { env.ep(), *this, &Uplink_client::_handle_irq },
Lan9118_base { mmio, irq, *this, env }, Lan9118_base { mmio, irq, *this, env },

View File

@ -31,13 +31,13 @@ class Main
{ {
private: private:
Env &_env; Env &_env;
Heap _heap { _env.ram(), _env.rm() }; Heap _heap { _env.ram(), _env.rm() };
Platform::Connection _platform { _env }; Platform::Connection _platform { _env };
Platform::Device _device { _platform }; Platform::Device _device { _platform };
Platform::Device::Mmio _mmio { _device }; Platform::Device::Mmio<0> _mmio { _device };
Platform::Device::Irq _irq { _device }; Platform::Device::Irq _irq { _device };
Uplink_client _uplink_client { _env, _heap, _mmio, _irq }; Uplink_client _uplink_client { _env, _heap, _mmio, _irq };
public: public:

View File

@ -59,12 +59,13 @@ namespace Nvme {
struct Cqe; struct Cqe;
struct Sqe; template <size_t> struct Sqe;
struct Sqe_header;
struct Sqe_create_cq; struct Sqe_create_cq;
struct Sqe_create_sq; struct Sqe_create_sq;
struct Sqe_identify; struct Sqe_identify;
struct Sqe_get_feature; struct Sqe_get_feature;
struct Sqe_set_feature; template <size_t> struct Sqe_set_feature;
struct Sqe_io; struct Sqe_io;
struct Set_hmb; struct Set_hmb;
@ -165,7 +166,7 @@ namespace Nvme {
/* /*
* Identify command data * Identify command data
*/ */
struct Nvme::Identify_data : Genode::Mmio struct Nvme::Identify_data : Genode::Mmio<0x208>
{ {
enum { enum {
SN_OFFSET = 0x04, SN_LEN = 20, 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 Nn : Register<0x204, 32> { }; /* number of namespaces */
struct Vwc : Register<0x204, 8> { }; /* volatile write cache */ struct Vwc : Register<0x204, 8> { }; /* volatile write cache */
Identify_data(addr_t const base) Identify_data(Byte_range_ptr const &range) : Mmio(range)
: Genode::Mmio(base)
{ {
char const *p = (char const*)base; char const *p = Mmio::range().start;
sn = Sn(Util::extract_string(p, SN_OFFSET, SN_LEN+1)); sn = Sn(Util::extract_string(p, SN_OFFSET, SN_LEN+1));
mn = Mn(Util::extract_string(p, MN_OFFSET, MN_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 * 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 Nsze : Register<0x00, 64> { }; /* name space size */
struct Ncap : Register<0x08, 64> { }; /* name space capacity */ 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 */ struct Rp : Bitfield<24, 2> { }; /* relative performance */
}; };
Identify_ns_data(addr_t const base) Identify_ns_data(Byte_range_ptr const &range) : Mmio(range) { }
: Genode::Mmio(base)
{ }
}; };
/* /*
* Queue doorbell register * Queue doorbell register
*/ */
struct Nvme::Doorbell : public Genode::Mmio struct Nvme::Doorbell : public Genode::Mmio<0x8>
{ {
struct Sqtdbl : Register<0x00, 32> struct Sqtdbl : Register<0x00, 32>
{ {
@ -263,15 +261,14 @@ struct Nvme::Doorbell : public Genode::Mmio
struct Cqh : Bitfield< 0, 16> { }; /* submission queue tail */ struct Cqh : Bitfield< 0, 16> { }; /* submission queue tail */
}; };
Doorbell(addr_t const base) Doorbell(Byte_range_ptr const &range) : Mmio(range) { }
: Genode::Mmio(base) { }
}; };
/* /*
* Completion queue entry * Completion queue entry
*/ */
struct Nvme::Cqe : Genode::Mmio struct Nvme::Cqe : Genode::Mmio<0x10>
{ {
struct Dw0 : Register<0x00, 32> { }; /* command specific */ struct Dw0 : Register<0x00, 32> { }; /* command specific */
struct Dw1 : Register<0x04, 32> { }; /* reserved */ struct Dw1 : Register<0x04, 32> { }; /* reserved */
@ -288,7 +285,7 @@ struct Nvme::Cqe : Genode::Mmio
struct Dnr : Bitfield<15, 1> { }; /* do not retry */ 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) static uint32_t request_id(Nvme::Cqe const &b)
{ {
@ -324,46 +321,53 @@ struct Nvme::Cqe : Genode::Mmio
/* /*
* Submission queue entry base * Submission queue entry base
*/ */
struct Nvme::Sqe : Genode::Mmio template <size_t SIZE>
struct Nvme::Sqe : Genode::Mmio<SIZE>
{ {
struct Cdw0 : Register<0x00, 32> using Base = Genode::Mmio<SIZE>;
using Cdw0_base = Base::template Register<0x00, 32>;
struct Cdw0 : Cdw0_base
{ {
struct Opc : Bitfield< 0, 8> { }; /* opcode */ struct Opc : Cdw0_base::template Bitfield< 0, 8> { }; /* opcode */
struct Fuse : Bitfield< 9, 2> { }; /* fused operation */ struct Fuse : Cdw0_base::template Bitfield< 9, 2> { }; /* fused operation */
struct Psdt : Bitfield<14, 2> { }; /* PRP or SGL for data transfer */ struct Psdt : Cdw0_base::template Bitfield<14, 2> { }; /* PRP or SGL for data transfer */
struct Cid : Bitfield<16, 16> { }; /* command identifier */ struct Cid : Cdw0_base::template Bitfield<16, 16> { }; /* command identifier */
}; };
struct Nsid : Register<0x04, 32> { }; struct Nsid : Base::template Register<0x04, 32> { };
struct Mptr : Register<0x10, 64> { }; struct Mptr : Base::template Register<0x10, 64> { };
struct Prp1 : Register<0x18, 64> { }; struct Prp1 : Base::template Register<0x18, 64> { };
struct Prp2 : Register<0x20, 64> { }; struct Prp2 : Base::template Register<0x20, 64> { };
/* SGL not supported */ /* SGL not supported */
Sqe(addr_t const base) : Genode::Mmio(base) { } Sqe(Byte_range_ptr const &range) : Mmio<SIZE>(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 * Identify command
*/ */
struct Nvme::Sqe_identify : Nvme::Sqe struct Nvme::Sqe_identify : Nvme::Sqe<0x2c>
{ {
struct Cdw10 : Register<0x28, 32> struct Cdw10 : Register<0x28, 32>
{ {
struct Cns : Bitfield< 0, 8> { }; /* controller or namespace structure */ 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 * Get feature command
*/ */
struct Nvme::Sqe_get_feature : Nvme::Sqe struct Nvme::Sqe_get_feature : Nvme::Sqe<0x2c>
{ {
struct Cdw10 : Register<0x28, 32> 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 */ 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 * Set feature command
*/ */
struct Nvme::Sqe_set_feature : Nvme::Sqe template <size_t SIZE>
struct Nvme::Sqe_set_feature : Nvme::Sqe<SIZE>
{ {
struct Cdw10 : Register<0x28, 32> using Base = Genode::Mmio<SIZE>;
using Cdw10_base = Base::template Register<0x28, 32>;
struct Cdw10 : Cdw10_base
{ {
struct Fid : Bitfield< 0, 8> { }; /* feature identifier */ struct Fid : Cdw10_base::template Bitfield< 0, 8> { }; /* feature identifier */
struct Sv : Bitfield<31, 1> { }; /* save */ 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<SIZE>(range) { }
}; };
struct Hmb_de : Genode::Mmio struct Hmb_de : Genode::Mmio<0x10>
{ {
enum { SIZE = 16u }; enum { SIZE = 16u };
struct Badd : Register<0x00, 64> { }; struct Badd : Register<0x00, 64> { };
struct Bsize : Register<0x08, 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<Badd>(buffer); write<Badd>(buffer);
write<Bsize>(units); write<Bsize>(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> 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 */ 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) uint32_t const units, uint32_t const entries)
: :
Sqe_set_feature(base) Sqe_set_feature(range)
{ {
write<Sqe_set_feature::Cdw10::Fid>(Feature_fid::HMB); write<Sqe_set_feature::Cdw10::Fid>(Feature_fid::HMB);
write<Cdw11::Ehm>(1); write<Cdw11::Ehm>(1);
@ -452,7 +460,7 @@ struct Nvme::Set_hmb : Nvme::Sqe_set_feature
/* /*
* Create completion queue command * Create completion queue command
*/ */
struct Nvme::Sqe_create_cq : Nvme::Sqe struct Nvme::Sqe_create_cq : Nvme::Sqe<0x30>
{ {
struct Cdw10 : Register<0x28, 32> struct Cdw10 : Register<0x28, 32>
{ {
@ -467,14 +475,14 @@ struct Nvme::Sqe_create_cq : Nvme::Sqe
struct Iv : Bitfield<16, 16> { }; /* interrupt vector */ 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 * Create submission queue command
*/ */
struct Nvme::Sqe_create_sq : Nvme::Sqe struct Nvme::Sqe_create_sq : Nvme::Sqe<0x30>
{ {
struct Cdw10 : Register<0x28, 32> struct Cdw10 : Register<0x28, 32>
{ {
@ -489,14 +497,14 @@ struct Nvme::Sqe_create_sq : Nvme::Sqe
struct Cqid : Bitfield<16, 16> { }; /* completion queue identifier */ 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 * I/O command
*/ */
struct Nvme::Sqe_io : Nvme::Sqe struct Nvme::Sqe_io : Nvme::Sqe<0x34>
{ {
struct Slba_lower : Register<0x28, 32> { }; struct Slba_lower : Register<0x28, 32> { };
struct Slba_upper : Register<0x2c, 32> { }; struct Slba_upper : Register<0x2c, 32> { };
@ -507,7 +515,7 @@ struct Nvme::Sqe_io : Nvme::Sqe
struct Nlb : Bitfield< 0, 16> { }; 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; using Queue::Queue;
addr_t next() Byte_range_ptr next()
{ {
addr_t a = (addr_t)local_addr<void>() + (tail * SQE_LEN); char *a = local_addr<char>() + (tail * SQE_LEN);
Genode::memset((void*)a, 0, SQE_LEN); Genode::memset(a, 0, SQE_LEN);
tail = (tail + 1) % max_entries; tail = (tail + 1) % max_entries;
return a; return {a, size()};
} }
}; };
@ -558,7 +566,11 @@ struct Nvme::Cq : Nvme::Queue
using Queue::Queue; using Queue::Queue;
addr_t next() { return (addr_t)local_addr<void>() + (head * CQE_LEN); } Byte_range_ptr next()
{
off_t offset = head * CQE_LEN;
return {local_addr<char>() + offset, size() - offset};
}
void advance_head() void advance_head()
{ {
@ -574,10 +586,10 @@ struct Nvme::Cq : Nvme::Queue
* Controller * Controller
*/ */
class Nvme::Controller : Platform::Device, class Nvme::Controller : Platform::Device,
Platform::Device::Mmio, Platform::Device::Mmio<0x1010>,
Platform::Device::Irq Platform::Device::Irq
{ {
using Mmio = Genode::Mmio; using Mmio = Genode::Mmio<SIZE>;
public: public:
@ -974,15 +986,15 @@ class Nvme::Controller : Platform::Device,
* \return returns address of the next free entry or 0 if there is * \return returns address of the next free entry or 0 if there is
* no free entry * 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()); Sqe_header b(_admin_sq->next());
b.write<Nvme::Sqe::Cdw0::Opc>(opc); b.write<Nvme::Sqe_header::Cdw0::Opc>(opc);
b.write<Nvme::Sqe::Cdw0::Cid>(cid); b.write<Nvme::Sqe_header::Cdw0::Cid>(cid);
b.write<Nvme::Sqe::Nsid>(nsid); b.write<Nvme::Sqe_header::Nsid>(nsid);
return b.base(); return b.range();
} }
/** /**
@ -1068,7 +1080,7 @@ class Nvme::Controller : Platform::Device,
Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, NSLIST_CID)); Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, NSLIST_CID));
b.write<Nvme::Sqe::Prp1>(_nvme_nslist.dma_addr()); b.write<Nvme::Sqe_identify::Prp1>(_nvme_nslist.dma_addr());
b.write<Nvme::Sqe_identify::Cdw10::Cns>(Cns::NSLIST); b.write<Nvme::Sqe_identify::Cdw10::Cns>(Cns::NSLIST);
write<Admin_sdb::Sqt>(_admin_sq->tail); write<Admin_sdb::Sqt>(_admin_sq->tail);
@ -1106,7 +1118,7 @@ class Nvme::Controller : Platform::Device,
_nvme_query_ns[id].construct(_platform, IDENTIFY_LEN); _nvme_query_ns[id].construct(_platform, IDENTIFY_LEN);
Sqe_identify b(_admin_command(Opcode::IDENTIFY, ns[id], QUERYNS_CID)); Sqe_identify b(_admin_command(Opcode::IDENTIFY, ns[id], QUERYNS_CID));
b.write<Nvme::Sqe::Prp1>(_nvme_query_ns[id]->dma_addr()); b.write<Nvme::Sqe_identify::Prp1>(_nvme_query_ns[id]->dma_addr());
b.write<Nvme::Sqe_identify::Cdw10::Cns>(Cns::IDENTIFY_NS); b.write<Nvme::Sqe_identify::Cdw10::Cns>(Cns::IDENTIFY_NS);
write<Admin_sdb::Sqt>(_admin_sq->tail); write<Admin_sdb::Sqt>(_admin_sq->tail);
@ -1116,7 +1128,7 @@ class Nvme::Controller : Platform::Device,
throw Initialization_failed(); throw Initialization_failed();
} }
Identify_ns_data nsdata((addr_t)_nvme_query_ns[id]->local_addr<void>()); Identify_ns_data nsdata({_nvme_query_ns[id]->local_addr<char>(), _nvme_query_ns[id]->size()});
uint32_t const flbas = nsdata.read<Nvme::Identify_ns_data::Flbas::Formats>(); uint32_t const flbas = nsdata.read<Nvme::Identify_ns_data::Flbas::Formats>();
/* use array subscription, omit first entry */ /* use array subscription, omit first entry */
@ -1133,7 +1145,7 @@ class Nvme::Controller : Platform::Device,
void _identify() void _identify()
{ {
Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, IDENTIFY_CID)); Sqe_identify b(_admin_command(Opcode::IDENTIFY, 0, IDENTIFY_CID));
b.write<Nvme::Sqe::Prp1>(_nvme_identify.dma_addr()); b.write<Nvme::Sqe_identify::Prp1>(_nvme_identify.dma_addr());
b.write<Nvme::Sqe_identify::Cdw10::Cns>(Cns::IDENTIFY); b.write<Nvme::Sqe_identify::Cdw10::Cns>(Cns::IDENTIFY);
write<Admin_sdb::Sqt>(_admin_sq->tail); write<Admin_sdb::Sqt>(_admin_sq->tail);
@ -1143,7 +1155,8 @@ class Nvme::Controller : Platform::Device,
throw Initialization_failed(); throw Initialization_failed();
} }
_identify_data.construct((addr_t)_nvme_identify.local_addr<void>()); _identify_data.construct(
Byte_range_ptr(_nvme_identify.local_addr<char>(), _nvme_identify.size()));
/* store information */ /* store information */
_info.version = Genode::String<8>(read<Vs::Mjr>(), ".", _info.version = Genode::String<8>(read<Vs::Mjr>(), ".",
@ -1230,17 +1243,18 @@ class Nvme::Controller : Platform::Device,
_hmb_chunk_registry.construct(_hmb_alloc); _hmb_chunk_registry.construct(_hmb_alloc);
addr_t list_base = Reconstructible<Byte_range_ptr> list
(addr_t)_hmb_descr_list_buffer->local_addr<addr_t>(); {_hmb_descr_list_buffer->local_addr<char>(), _hmb_descr_list_buffer->size()};
for (uint32_t i = 0; i < num_entries; i++) { for (uint32_t i = 0; i < num_entries; i++) {
try { try {
Hmb_chunk *c = Hmb_chunk *c =
new (_hmb_alloc) Hmb_chunk(*_hmb_chunk_registry, new (_hmb_alloc) Hmb_chunk(*_hmb_chunk_registry,
_platform, HMB_CHUNK_SIZE); _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 */) { } catch (... /* intentional catch-all */) {
warning("could not allocate HMB chunk"); warning("could not allocate HMB chunk");
@ -1284,7 +1298,7 @@ class Nvme::Controller : Platform::Device,
Nvme::Cq &cq = *_cq[id]; Nvme::Cq &cq = *_cq[id];
Sqe_create_cq b(_admin_command(Opcode::CREATE_IO_CQ, 0, CREATE_IO_CQ_CID)); Sqe_create_cq b(_admin_command(Opcode::CREATE_IO_CQ, 0, CREATE_IO_CQ_CID));
b.write<Nvme::Sqe::Prp1>(cq.dma_addr()); b.write<Nvme::Sqe_create_cq::Prp1>(cq.dma_addr());
b.write<Nvme::Sqe_create_cq::Cdw10::Qid>(id); b.write<Nvme::Sqe_create_cq::Cdw10::Qid>(id);
b.write<Nvme::Sqe_create_cq::Cdw10::Qsize>(_max_io_entries_mask); b.write<Nvme::Sqe_create_cq::Cdw10::Qsize>(_max_io_entries_mask);
b.write<Nvme::Sqe_create_cq::Cdw11::Pc>(1); b.write<Nvme::Sqe_create_cq::Cdw11::Pc>(1);
@ -1314,7 +1328,7 @@ class Nvme::Controller : Platform::Device,
Nvme::Sq &sq = *_sq[id]; Nvme::Sq &sq = *_sq[id];
Sqe_create_sq b(_admin_command(Opcode::CREATE_IO_SQ, 0, CREATE_IO_SQ_CID)); Sqe_create_sq b(_admin_command(Opcode::CREATE_IO_SQ, 0, CREATE_IO_SQ_CID));
b.write<Nvme::Sqe::Prp1>(sq.dma_addr()); b.write<Nvme::Sqe_create_sq::Prp1>(sq.dma_addr());
b.write<Nvme::Sqe_create_sq::Cdw10::Qid>(id); b.write<Nvme::Sqe_create_sq::Cdw10::Qid>(id);
b.write<Nvme::Sqe_create_sq::Cdw10::Qsize>(_max_io_entries_mask); b.write<Nvme::Sqe_create_sq::Cdw10::Qsize>(_max_io_entries_mask);
b.write<Nvme::Sqe_create_sq::Cdw11::Pc>(1); b.write<Nvme::Sqe_create_sq::Cdw11::Pc>(1);
@ -1340,7 +1354,7 @@ class Nvme::Controller : Platform::Device,
Signal_context_capability irq_sigh) Signal_context_capability irq_sigh)
: :
Platform::Device(platform), Platform::Device(platform),
Platform::Device::Mmio((Platform::Device&)*this), Platform::Device::Mmio<SIZE>((Platform::Device&)*this),
Platform::Device::Irq((Platform::Device&)*this), Platform::Device::Irq((Platform::Device&)*this),
_env(env), _platform(platform), _delayer(delayer) _env(env), _platform(platform), _delayer(delayer)
{ {
@ -1419,14 +1433,14 @@ class Nvme::Controller : Platform::Device,
* *
* \return returns virtual address of the I/O command * \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]; Nvme::Sq &sq = *_sq[nsid];
Sqe e(sq.next()); Sqe_header e(sq.next());
e.write<Nvme::Sqe::Cdw0::Cid>(cid); e.write<Nvme::Sqe_header::Cdw0::Cid>(cid);
e.write<Nvme::Sqe::Nsid>(nsid); e.write<Nvme::Sqe_header::Nsid>(nsid);
return e.base(); return e.range();
} }
/** /**
@ -1755,7 +1769,7 @@ class Nvme::Driver : Genode::Noncopyable
** MMIO Controller ** ** MMIO Controller **
*********************/ *********************/
struct Timer_delayer : Genode::Mmio::Delayer, struct Timer_delayer : Genode::Mmio<0>::Delayer,
Timer::Connection Timer::Connection
{ {
Timer_delayer(Genode::Env &env) 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::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid));
Nvme::Opcode const op = write ? Nvme::Opcode::WRITE : Nvme::Opcode::READ; Nvme::Opcode const op = write ? Nvme::Opcode::WRITE : Nvme::Opcode::READ;
b.write<Nvme::Sqe::Cdw0::Opc>(op); b.write<Nvme::Sqe_io::Cdw0::Opc>(op);
b.write<Nvme::Sqe::Prp1>(request_pa); b.write<Nvme::Sqe_io::Prp1>(request_pa);
/* payload will fit into 2 mps chunks */ /* payload will fit into 2 mps chunks */
if (len > Nvme::MPS && !need_list) { if (len > Nvme::MPS && !need_list) {
b.write<Nvme::Sqe::Prp2>(request_pa + Nvme::MPS); b.write<Nvme::Sqe_io::Prp2>(request_pa + Nvme::MPS);
} else if (need_list) { } else if (need_list) {
/* get page to store list of mps chunks */ /* get page to store list of mps chunks */
@ -2018,7 +2032,7 @@ class Nvme::Driver : Genode::Noncopyable
pe[i] = npa; pe[i] = npa;
npa += Nvme::MPS; npa += Nvme::MPS;
} }
b.write<Nvme::Sqe::Prp2>(pa); b.write<Nvme::Sqe_io::Prp2>(pa);
} }
b.write<Nvme::Sqe_io::Slba_lower>(uint32_t(lba)); b.write<Nvme::Sqe_io::Slba_lower>(uint32_t(lba));
@ -2035,7 +2049,7 @@ class Nvme::Driver : Genode::Noncopyable
.id = id }; .id = id };
Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid));
b.write<Nvme::Sqe::Cdw0::Opc>(Nvme::Opcode::FLUSH); b.write<Nvme::Sqe_io::Cdw0::Opc>(Nvme::Opcode::FLUSH);
} }
void _submit_trim(Block::Request const request) 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; Block::sector_t const lba = request.operation.block_number;
Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid)); Nvme::Sqe_io b(_nvme_ctrlr.io_command(Nvme::IO_NSID, cid));
b.write<Nvme::Sqe::Cdw0::Opc>(Nvme::Opcode::WRITE_ZEROS); b.write<Nvme::Sqe_io::Cdw0::Opc>(Nvme::Opcode::WRITE_ZEROS);
b.write<Nvme::Sqe_io::Slba_lower>(uint32_t(lba)); b.write<Nvme::Sqe_io::Slba_lower>(uint32_t(lba));
b.write<Nvme::Sqe_io::Slba_upper>(uint32_t(lba >> 32u)); b.write<Nvme::Sqe_io::Slba_upper>(uint32_t(lba >> 32u));

View File

@ -52,8 +52,10 @@ struct Config_helper
Driver::Device const & _dev; Driver::Device const & _dev;
Driver::Device::Pci_config const & _cfg; Driver::Device::Pci_config const & _cfg;
Attached_io_mem_dataspace _io_mem { _env, _cfg.addr, 0x1000 }; static constexpr size_t IO_MEM_SIZE = 0x1000;
Config _config { (addr_t)_io_mem.local_addr<void>() };
Attached_io_mem_dataspace _io_mem { _env, _cfg.addr, IO_MEM_SIZE };
Config _config { {_io_mem.local_addr<char>(), IO_MEM_SIZE} };
Config_helper(Env & env, Config_helper(Env & env,
Driver::Device const & dev, Driver::Device const & dev,
@ -125,8 +127,8 @@ struct Config_helper
_config.write<Config::Command>(cmd); _config.write<Config::Command>(cmd);
/* apply different PCI quirks, bios handover etc. */ /* apply different PCI quirks, bios handover etc. */
Driver::pci_uhci_quirks(_env, _dev, _cfg, _config.base()); Driver::pci_uhci_quirks(_env, _dev, _cfg, _config.range());
Driver::pci_ehci_quirks(_env, _dev, _cfg, _config.base()); Driver::pci_ehci_quirks(_env, _dev, _cfg, _config.range());
Driver::pci_hd_audio_quirks(_cfg, _config); Driver::pci_hd_audio_quirks(_cfg, _config);
_config.write<Config::Command>(cmd_old); _config.write<Config::Command>(cmd_old);
@ -163,8 +165,10 @@ void Driver::pci_msi_enable(Env & env,
Irq_session::Info const info, Irq_session::Info const info,
Irq_session::Type type) Irq_session::Type type)
{ {
Attached_io_mem_dataspace io_mem { env, cfg_space, 0x1000 }; static constexpr size_t IO_MEM_SIZE = 0x1000;
Config config { (addr_t)io_mem.local_addr<void>() };
Attached_io_mem_dataspace io_mem { env, cfg_space, IO_MEM_SIZE };
Config config { {io_mem.local_addr<char>(), IO_MEM_SIZE} };
config.scan(); config.scan();
if (type == Irq_session::TYPE_MSIX && config.msi_x_cap.constructed()) { 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()}); unsigned idx = dc.io_mem_index({config.msi_x_cap->bar()});
Io_mem_session_client dsc(dc.io_mem(idx, range)); Io_mem_session_client dsc(dc.io_mem(idx, range));
Attached_dataspace msix_table_ds(env.rm(), dsc.dataspace()); Attached_dataspace msix_table_ds(env.rm(), dsc.dataspace());
addr_t msix_table_start = (addr_t)msix_table_ds.local_addr<void>() Byte_range_ptr msix_table = {
+ config.msi_x_cap->table_offset(); msix_table_ds.local_addr<char>() + 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 */ /* disable all msi-x table entries beside the first one */
unsigned slots = config.msi_x_cap->slots(); unsigned slots = config.msi_x_cap->slots();
for (unsigned i = 0; i < slots; i++) { for (unsigned i = 0; i < slots; i++) {
using Entry = Config::Msi_x_capability::Table_entry; 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) { if (!i) {
uint32_t lower = info.address & 0xfffffffc; uint32_t lower = info.address & 0xfffffffc;
uint32_t upper = sizeof(info.address) > 4 ? uint32_t upper = sizeof(info.address) > 4 ?

View File

@ -16,14 +16,14 @@
namespace Driver { namespace Driver {
static void pci_ehci_quirks(Env &, Device const &, 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, void Driver::pci_ehci_quirks(Env & env,
Device const & dev, Device const & dev,
Device::Pci_config const & cfg, Device::Pci_config const & cfg,
addr_t base) Pci::Config const & pci_config)
{ {
enum { EHCI_CLASS_CODE = 0xc0320 }; enum { EHCI_CLASS_CODE = 0xc0320 };
@ -31,7 +31,7 @@ void Driver::pci_ehci_quirks(Env & env,
return; return;
/* EHCI host controller register definitions */ /* EHCI host controller register definitions */
struct Ehci : Mmio struct Ehci : Mmio<0x44>
{ {
struct Capability_parameters : Register<0x8, 32> struct Capability_parameters : Register<0x8, 32>
{ {
@ -42,7 +42,7 @@ void Driver::pci_ehci_quirks(Env & env,
using Mmio::Mmio; using Mmio::Mmio;
}; };
struct Ehci_pci : Mmio struct Ehci_pci : Mmio<0x64>
{ {
struct Port_wake : Register<0x62, 16> {}; struct Port_wake : Register<0x62, 16> {};
@ -50,7 +50,7 @@ void Driver::pci_ehci_quirks(Env & env,
}; };
/* PCI extended capability for EHCI */ /* PCI extended capability for EHCI */
struct Cap : Mmio struct Cap : Mmio<0x8>
{ {
struct Pointer : Register<0x0, 16> struct Pointer : Register<0x0, 16>
{ {
@ -72,16 +72,18 @@ void Driver::pci_ehci_quirks(Env & env,
if (!bar.valid() || bar.number != 0) if (!bar.valid() || bar.number != 0)
return; return;
Ehci_pci pw(base); Ehci_pci pw(pci_config.range());
Attached_io_mem_dataspace iomem(env, range.start, 0x1000); static constexpr size_t IO_MEM_SIZE = 0x1000;
Ehci ehci((addr_t)iomem.local_addr<void>());
Attached_io_mem_dataspace iomem(env, range.start, IO_MEM_SIZE);
Ehci ehci({iomem.local_addr<char>(), IO_MEM_SIZE});
addr_t offset = addr_t offset =
ehci.read<Ehci::Capability_parameters::Extended_cap_pointer>(); ehci.read<Ehci::Capability_parameters::Extended_cap_pointer>();
/* iterate over EHCI extended capabilities */ /* iterate over EHCI extended capabilities */
while (offset) { while (offset) {
Cap cap(base + offset); Cap cap(pci_config.range_at(offset));
if (cap.read<Cap::Pointer::Id>() != Cap::Pointer::Id::SYNC) if (cap.read<Cap::Pointer::Id>() != Cap::Pointer::Id::SYNC)
break; break;

View File

@ -27,7 +27,7 @@ void Driver::pci_hd_audio_quirks(Device::Pci_config const & cfg, Pci::Config & c
return; return;
/* PCI configuration register for HDAUDIO */ /* PCI configuration register for HDAUDIO */
struct Hdaudio : Mmio struct Hdaudio : Mmio<0x7a>
{ {
struct Traffic_class_select : Register<0x44, 8> {}; 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<Pci::Config::Command::Fast_back_to_back_enable>(1); config.write<Pci::Config::Command::Fast_back_to_back_enable>(1);
Hdaudio audio(config.base()); Hdaudio audio(config.range());
audio.write<Hdaudio::Traffic_class_select>(0); audio.write<Hdaudio::Traffic_class_select>(0);
if (cfg.vendor_id == 0x8086) if (cfg.vendor_id == 0x8086)

View File

@ -91,7 +91,7 @@ void Driver::pci_intel_graphics_info(Device::Pci_config const & cfg,
return; return;
/* PCI configuration registers of host bridge */ /* 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_old_gmch_control : Register<0x52, 16> {};
struct Gen_gmch_control : Register<0x50, 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) if (cfg.bus_num || cfg.dev_num || cfg.func_num)
return; return;
Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000); static constexpr size_t IO_MEM_SIZE = 0x1000;
Host_bridge config((addr_t)io_mem.local_addr<void>());
Attached_io_mem_dataspace io_mem(env, cfg.addr, IO_MEM_SIZE);
Host_bridge config({io_mem.local_addr<char>(), IO_MEM_SIZE});
unsigned gen = pci_intel_graphics_generation(cfg.device_id); unsigned gen = pci_intel_graphics_generation(cfg.device_id);
uint16_t gmch = 0; uint16_t gmch = 0;

View File

@ -17,14 +17,14 @@
namespace Driver { namespace Driver {
static void pci_uhci_quirks(Env &, Device const &, 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, void Driver::pci_uhci_quirks(Env & env,
Device const & dev, Device const & dev,
Device::Pci_config const & cfg, Device::Pci_config const & cfg,
addr_t base) Pci::Config const & pci_config)
{ {
enum { UHCI_CLASS_CODE = 0xc0300 }; enum { UHCI_CLASS_CODE = 0xc0300 };
@ -32,7 +32,7 @@ void Driver::pci_uhci_quirks(Env & env,
return; return;
/* PCI configuration register for UHCI */ /* PCI configuration register for UHCI */
struct Uhci : Mmio struct Uhci : Mmio<0xc6>
{ {
struct Usb_legacy_support : Register<0xc0, 16> struct Usb_legacy_support : Register<0xc0, 16>
{ {
@ -56,7 +56,7 @@ void Driver::pci_uhci_quirks(Env & env,
if (!range.size) range = r; }); if (!range.size) range = r; });
Io_port_connection io_ports(env, range.addr, range.size); Io_port_connection io_ports(env, range.addr, range.size);
Uhci config(base); Uhci config(pci_config.range());
bool have_to_reset = false; bool have_to_reset = false;
uint16_t UHCI_CMD = range.addr; uint16_t UHCI_CMD = range.addr;

View File

@ -33,7 +33,7 @@ void Driver::pci_virtio_info(Device const & dev,
struct Virtio : Pci::Config 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 }; 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 Length : Register<0xc, 32> {};
struct Offset_factor : Register<0x10, 32> {}; struct Offset_factor : Register<0x10, 32> {};
using Pci::Config::Pci_capability::Pci_capability; using Pci_capability::Pci_capability;
bool valid() bool valid()
{ {
@ -100,18 +100,20 @@ void Driver::pci_virtio_info(Device const & dev,
uint16_t off = read<Capability_pointer>(); uint16_t off = read<Capability_pointer>();
while (off) { while (off) {
Capability cap(base() + off); Capability cap(Mmio::range_at(off));
if (cap.read<Pci_capability::Id>() == if (cap.read<Capability::Id>() ==
Pci_capability::Id::VENDOR && Capability::Id::VENDOR &&
cap.valid()) cap.valid())
capability(cap, dev, xml); capability(cap, dev, xml);
off = cap.read<Pci_capability::Pointer>(); off = cap.read<Capability::Pointer>();
} }
} }
}; };
Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000); static constexpr size_t IO_MEM_SIZE = 0x1000;
Virtio config((addr_t)io_mem.local_addr<void>());
Attached_io_mem_dataspace io_mem(env, cfg.addr, IO_MEM_SIZE);
Virtio config({io_mem.local_addr<char>(), IO_MEM_SIZE});
config.for_each_capability(dev, xml); config.for_each_capability(dev, xml);
} }

View File

@ -42,8 +42,8 @@ struct Ps2::Main
Device _device { _platform }; Device _device { _platform };
Device::Mmio _mmio_keyboard { _device, { 0 } }; Device::Mmio<0> _mmio_keyboard { _device, { 0 } };
Device::Mmio _mmio_mouse { _device, { 1 } }; Device::Mmio<0> _mmio_mouse { _device, { 1 } };
Device::Irq _irq_keyboard { _device, { 0 } }; Device::Irq _irq_keyboard { _device, { 0 } };
Device::Irq _irq_mouse { _device, { 1 } }; Device::Irq _irq_mouse { _device, { 1 } };

View File

@ -77,7 +77,7 @@ class Pl050
public: public:
_Channel(Platform::Device::Mmio &mmio) _Channel(Platform::Device::Mmio<0> &mmio)
: :
_reg_base(mmio.local_addr<Genode::uint32_t>()) _reg_base(mmio.local_addr<Genode::uint32_t>())
{ } { }
@ -119,8 +119,8 @@ class Pl050
public: public:
Pl050(Platform::Device::Mmio &keyboard_mmio, Pl050(Platform::Device::Mmio<0> &keyboard_mmio,
Platform::Device::Mmio &mouse_mmio) Platform::Device::Mmio<0> &mouse_mmio)
: :
_kbd(keyboard_mmio), _aux(mouse_mmio) _kbd(keyboard_mmio), _aux(mouse_mmio)
{ {

View File

@ -524,7 +524,7 @@ Driver::Driver(Env & env, Platform::Connection & platform)
: :
Driver_base(env.ram()), Driver_base(env.ram()),
Platform::Device(platform), Platform::Device(platform),
Platform::Device::Mmio(*static_cast<Platform::Device *>(this)), Platform::Device::Mmio<SIZE>(*static_cast<Platform::Device *>(this)),
_env(env), _env(env),
_platform(platform) _platform(platform)
{ {

View File

@ -27,9 +27,9 @@ namespace Sd_card { class Driver; }
class Sd_card::Driver : public Driver_base, class Sd_card::Driver : public Driver_base,
private Platform::Device, private Platform::Device,
private Platform::Device::Mmio private Platform::Device::Mmio<0x100>
{ {
using Mmio = Genode::Mmio; using Mmio = Genode::Mmio<SIZE>;
private: private:

View File

@ -142,7 +142,7 @@ Driver::Driver(Env &env, Platform::Connection & platform)
: :
Block::Driver(env.ram()), Block::Driver(env.ram()),
Platform::Device(platform), Platform::Device(platform),
Platform::Device::Mmio(*this, { 0 }), Platform::Device::Mmio<SIZE>(*this, { 0 }),
_platform(platform), _platform(platform),
_timer(env) _timer(env)
{ {

View File

@ -30,7 +30,7 @@ namespace Sd_card {
class Sd_card::Driver : public Block::Driver, class Sd_card::Driver : public Block::Driver,
private Platform::Device, private Platform::Device,
private Platform::Device::Mmio private Platform::Device::Mmio<0>
{ {
private: private:

View File

@ -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 Revision : Register<0xc0, 8> { };
struct Sector_count : Register<0xd4, 32> { }; struct Sector_count : Register<0xd4, 32> { };

View File

@ -27,7 +27,7 @@ namespace I2c
} }
class I2c::I2c : Platform::Device::Mmio class I2c::I2c : Platform::Device::Mmio<0x12>
{ {
private: private:
@ -112,7 +112,7 @@ class I2c::I2c : Platform::Device::Mmio
public: public:
I2c(Genode::Env & env, Platform::Device & dev) I2c(Genode::Env & env, Platform::Device & dev)
: Platform::Device::Mmio(dev, {0}), : Platform::Device::Mmio<SIZE>(dev, {0}),
_irq_handler(env, dev) _irq_handler(env, dev)
{ {
write<Control>(0); write<Control>(0);

View File

@ -34,7 +34,7 @@ using Genode::addr_t;
** USB Command Block/Status Wrapper implementation ** ** USB Command Block/Status Wrapper implementation **
*****************************************************/ *****************************************************/
struct Usb::Cbw : Genode::Mmio struct Usb::Cbw : Genode::Mmio<0xf>
{ {
enum { LENGTH = 31 }; enum { LENGTH = 31 };
@ -46,8 +46,8 @@ struct Usb::Cbw : Genode::Mmio
struct Lun : Register<0xd, 8> { }; /* logical unit number */ struct Lun : Register<0xd, 8> { }; /* logical unit number */
struct Cbl : Register<0xe, 8> { }; /* command buffer length */ struct Cbl : Register<0xe, 8> { }; /* command buffer length */
Cbw(addr_t addr, uint32_t t, uint32_t d, Cbw(Byte_range_ptr const &range, uint32_t t, uint32_t d,
uint8_t f, uint8_t l, uint8_t len) : Mmio(addr) uint8_t f, uint8_t l, uint8_t len) : Mmio(range)
{ {
write<Sig>(SIG); write<Sig>(SIG);
write<Tag>(t); write<Tag>(t);
@ -72,11 +72,11 @@ struct Usb::Cbw : Genode::Mmio
struct Test_unit_ready : Usb::Cbw, struct Test_unit_ready : Usb::Cbw,
Scsi::Test_unit_ready 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::LENGTH),
Scsi::Test_unit_ready(addr+15) Scsi::Test_unit_ready(Cbw::range_at(15))
{ if (verbose_scsi) dump(); } { if (verbose_scsi) dump(); }
void dump() void dump()
@ -90,11 +90,11 @@ struct Test_unit_ready : Usb::Cbw,
struct Request_sense : Usb::Cbw, Scsi::Request_sense 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), Usb::ENDPOINT_IN, lun, Scsi::Request_sense::LENGTH),
Scsi::Request_sense(addr+15) Scsi::Request_sense(Cbw::range_at(15))
{ if (verbose_scsi) dump(); } { if (verbose_scsi) dump(); }
void dump() void dump()
@ -108,10 +108,10 @@ struct Request_sense : Usb::Cbw, Scsi::Request_sense
struct Start_stop : Usb::Cbw, Scsi::Start_stop 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), Cbw(range, tag, 0, Usb::ENDPOINT_IN, lun, Scsi::Start_stop::LENGTH),
Scsi::Start_stop(addr+15) Scsi::Start_stop(Cbw::range_at(15))
{ if (verbose_scsi) dump(); } { if (verbose_scsi) dump(); }
void dump() void dump()
@ -125,11 +125,11 @@ struct Start_stop : Usb::Cbw, Scsi::Start_stop
struct Inquiry : Usb::Cbw, Scsi::Inquiry 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), Usb::ENDPOINT_IN, lun, Scsi::Inquiry::LENGTH),
Scsi::Inquiry(addr+15) Scsi::Inquiry(Cbw::range_at(15))
{ if (verbose_scsi) dump(); } { if (verbose_scsi) dump(); }
void dump() void dump()
@ -143,11 +143,11 @@ struct Inquiry : Usb::Cbw, Scsi::Inquiry
struct Read_capacity_10 : Usb::Cbw, Scsi::Read_capacity_10 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), 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(); } { if (verbose_scsi) dump(); }
void 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 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) 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), 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(); } { if (verbose_scsi) dump(); }
void dump() void dump()
@ -180,12 +180,12 @@ struct Read_10 : Usb::Cbw, Scsi::Read_10
struct Write_10 : Usb::Cbw, Scsi::Write_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) 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), 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(); } { if (verbose_scsi) dump(); }
void 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 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), 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(); } { if (verbose_scsi) dump(); }
void 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 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) 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), 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(); } { if (verbose_scsi) dump(); }
void dump() void dump()
@ -236,12 +236,12 @@ struct Read_16 : Usb::Cbw, Scsi::Read_16
struct Write_16 : Usb::Cbw, Scsi::Write_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) 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), 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(); } { if (verbose_scsi) dump(); }
void 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 }; enum { LENGTH = 13 };
@ -264,7 +264,7 @@ struct Usb::Csw : Genode::Mmio
enum { PASSED = 0, FAILED = 1, PHASE_ERROR = 2 }; enum { PASSED = 0, FAILED = 1, PHASE_ERROR = 2 };
struct Sts : Register<0xc, 8> { }; /* status */ 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<Sig>(); } uint32_t sig() const { return read<Sig>(); }
uint32_t tag() const { return read<Tag>(); } uint32_t tag() const { return read<Tag>(); }

View File

@ -238,14 +238,14 @@ struct Usb::Block_driver : Usb::Completion
} }
int const actual_size = p.transfer.actual_size; int const actual_size = p.transfer.actual_size;
char * const data = reinterpret_cast<char*>(iface.content(p)); Byte_range_ptr data {(char *)iface.content(p), p.size()};
using namespace Scsi; using namespace Scsi;
switch (actual_size) { switch (actual_size) {
case Inquiry_response::LENGTH: case Inquiry_response::LENGTH:
{ {
Inquiry_response r((addr_t)data); Inquiry_response r(data);
if (verbose_scsi) r.dump(); if (verbose_scsi) r.dump();
if (!r.sbc()) { if (!r.sbc()) {
@ -258,7 +258,7 @@ struct Usb::Block_driver : Usb::Completion
} }
case Capacity_response_10::LENGTH: case Capacity_response_10::LENGTH:
{ {
Capacity_response_10 r((addr_t)data); Capacity_response_10 r(data);
if (verbose_scsi) r.dump(); if (verbose_scsi) r.dump();
block_count = r.last_block() + 1; block_count = r.last_block() + 1;
@ -267,7 +267,7 @@ struct Usb::Block_driver : Usb::Completion
} }
case Capacity_response_16::LENGTH: case Capacity_response_16::LENGTH:
{ {
Capacity_response_16 r((addr_t)data); Capacity_response_16 r(data);
if (verbose_scsi) r.dump(); if (verbose_scsi) r.dump();
block_count = r.last_block() + 1; block_count = r.last_block() + 1;
@ -276,7 +276,7 @@ struct Usb::Block_driver : Usb::Completion
} }
case Request_sense_response::LENGTH: case Request_sense_response::LENGTH:
{ {
Request_sense_response r((addr_t)data); Request_sense_response r(data);
if (verbose_scsi) r.dump(); if (verbose_scsi) r.dump();
uint8_t const asc = r.read<Request_sense_response::Asc>(); uint8_t const asc = r.read<Request_sense_response::Asc>();
@ -322,7 +322,7 @@ struct Usb::Block_driver : Usb::Completion
} }
case Csw::LENGTH: case Csw::LENGTH:
{ {
Csw csw((addr_t)data); Csw csw(data);
uint32_t const sig = csw.sig(); uint32_t const sig = csw.sig();
if (sig != Csw::SIG) { if (sig != Csw::SIG) {
@ -528,6 +528,7 @@ struct Usb::Block_driver : Usb::Completion
*/ */
char cbw_buffer[Cbw::LENGTH]; 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 * We should probably execute the SCSI REPORT_LUNS command first
@ -537,7 +538,7 @@ struct Usb::Block_driver : Usb::Completion
*/ */
/* Scsi::Opcode::INQUIRY */ /* 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); cbw(cbw_buffer, init, true);
resp(Scsi::Inquiry_response::LENGTH, init, true); resp(Scsi::Inquiry_response::LENGTH, init, true);
@ -559,13 +560,13 @@ struct Usb::Block_driver : Usb::Completion
enum { MAX_RETRIES = 10 }; enum { MAX_RETRIES = 10 };
int retries; int retries;
for (retries = 0; retries < MAX_RETRIES; 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); cbw(cbw_buffer, init, true);
csw(init, true); csw(init, true);
if (!init.unit_ready) { 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); cbw(cbw_buffer, init, true);
resp(Scsi::Request_sense_response::LENGTH, 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) { } else if (init.start_stop) {
init.start_stop = false; 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); cbw(cbw_buffer, init, true);
csw(init, true); csw(init, true);
@ -609,7 +610,7 @@ struct Usb::Block_driver : Usb::Completion
*/ */
/* Scsi::Opcode::READ_CAPACITY_10 */ /* 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); cbw(cbw_buffer, init, true);
resp(Scsi::Capacity_response_10::LENGTH, 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) { 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; 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"); warning("This is not the actual size you are looking for");
do { do {
Csw csw((addr_t)iface.content(p)); Csw csw({(char *)iface.content(p), p.size()});
uint32_t const sig = csw.sig(); uint32_t const sig = csw.sig();
if (sig != Csw::SIG) { if (sig != Csw::SIG) {
@ -879,12 +880,13 @@ struct Usb::Block_driver : Usb::Completion
* before entering this function * before entering this function
*/ */
char cb[Cbw::LENGTH]; char cb[Cbw::LENGTH];
Byte_range_ptr cb_range {(char *)cb, Cbw::LENGTH};
if (read) { if (read) {
if (force_cmd_16) Read_16 r((addr_t)cb, t, active_lun, lba, c, _block_size); if (force_cmd_16) Read_16 r(cb_range, t, active_lun, lba, c, _block_size);
else Read_10 r((addr_t)cb, t, active_lun, (uint32_t)lba, c, _block_size); else Read_10 r(cb_range, t, active_lun, (uint32_t)lba, c, _block_size);
} else { } else {
if (force_cmd_16) Write_16 w((addr_t)cb, t, active_lun, lba, c, _block_size); if (force_cmd_16) Write_16 w(cb_range, t, active_lun, lba, c, _block_size);
else Write_10 w((addr_t)cb, t, active_lun, (uint32_t)lba, c, _block_size); else Write_10 w(cb_range, t, active_lun, (uint32_t)lba, c, _block_size);
} }
cbw(cb, *this); cbw(cb, *this);

View File

@ -84,7 +84,7 @@ namespace Scsi {
* SCSI command responses ** * SCSI command responses **
***************************/ ***************************/
struct Scsi::Inquiry_response : Genode::Mmio struct Scsi::Inquiry_response : Genode::Mmio<0x24>
{ {
/* /*
* Minimum response length is 36 bytes. * 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 Pid : Register_array<0x10, 8, 16, 8> { }; /* product identification */
struct Rev : Register_array<0x20, 8, 4, 8> { }; /* product revision level */ 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<Dt>() == 0x00; } bool sbc() const { return read<Dt>() == 0x00; }
bool removable() const { return read<Rm::Rmb>(); } bool removable() const { return read<Rm::Rmb>(); }
@ -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 }; enum { LENGTH = 18 };
@ -153,7 +153,7 @@ struct Scsi::Request_sense_response : Genode::Mmio
struct Fru : Register<0xe, 8> { }; /* field replaceable unit code */ struct Fru : Register<0xe, 8> { }; /* field replaceable unit code */
struct Sks : Register<0xf, 32> { }; /* sense key specific (3 byte) */ 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() 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 }; enum { LENGTH = 8 };
struct Lba : Register<0x0, 32> { }; struct Lba : Register<0x0, 32> { };
struct Bs : Register<0x4, 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<Lba>()); } uint32_t last_block() const { return be(read<Lba>()); }
uint32_t block_size() const { return be(read<Bs>()); } uint32_t block_size() const { return be(read<Bs>()); }
@ -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 }; enum { LENGTH = 32 };
struct Lba : Register<0x0, 64> { }; struct Lba : Register<0x0, 64> { };
struct Bs : Register<0x8, 32> { }; 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<Lba>()); } uint64_t last_block() const { return be(read<Lba>()); }
uint32_t block_size() const { return be(read<Bs>()); } uint32_t block_size() const { return be(read<Bs>()); }
@ -213,7 +213,7 @@ struct Scsi::Capacity_response_16 : Genode::Mmio
** CBD 6 byte commands ** ** CBD 6 byte commands **
*************************/ *************************/
struct Scsi::Cmd_6 : Genode::Mmio struct Scsi::Cmd_6 : Genode::Mmio<0x6>
{ {
enum { LENGTH = 6 }; enum { LENGTH = 6 };
struct Op : Register<0x0, 8> { }; /* SCSI command */ 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 Len : Register<0x4, 8> { }; /* transfer length */
struct Ctl : Register<0x5, 8> { }; /* controll */ 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() void dump()
{ {
@ -235,7 +235,7 @@ struct Scsi::Cmd_6 : Genode::Mmio
struct Scsi::Test_unit_ready : Cmd_6 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<Cmd_6::Op>(Opcode::TEST_UNIT_READY); write<Cmd_6::Op>(Opcode::TEST_UNIT_READY);
} }
@ -244,7 +244,7 @@ struct Scsi::Test_unit_ready : Cmd_6
struct Scsi::Request_sense : 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<Cmd_6::Op>(Opcode::REQUEST_SENSE); write<Cmd_6::Op>(Opcode::REQUEST_SENSE);
write<Cmd_6::Len>(Request_sense_response::LENGTH); write<Cmd_6::Len>(Request_sense_response::LENGTH);
@ -254,7 +254,7 @@ struct Scsi::Request_sense : Cmd_6
struct Scsi::Inquiry : Cmd_6 struct Scsi::Inquiry : Cmd_6
{ {
Inquiry(addr_t addr) : Cmd_6(addr) Inquiry(Byte_range_ptr const &range) : Cmd_6(range)
{ {
write<Cmd_6::Op>(Opcode::INQUIRY); write<Cmd_6::Op>(Opcode::INQUIRY);
write<Cmd_6::Len>(Inquiry_response::LENGTH); write<Cmd_6::Len>(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 }; enum { LENGTH = 6 };
struct Op : Register<0x0, 8> { }; /* SCSI command */ struct Op : Register<0x0, 8> { }; /* SCSI command */
@ -275,9 +275,9 @@ struct Scsi::Start_stop : Genode::Mmio
struct St : Bitfield<0, 1> { }; /* start */ struct St : Bitfield<0, 1> { }; /* start */
}; /* flags */ }; /* 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<Op>(Opcode::START_STOP); write<Op>(Opcode::START_STOP);
write<I::Immed>(1); write<I::Immed>(1);
@ -301,7 +301,7 @@ struct Scsi::Start_stop : Genode::Mmio
** CBD 10 byte commands ** ** CBD 10 byte commands **
**************************/ **************************/
struct Scsi::Cmd_10 : Genode::Mmio struct Scsi::Cmd_10 : Genode::Mmio<0xa>
{ {
enum { LENGTH = 10 }; enum { LENGTH = 10 };
struct Op : Register<0x0, 8> { }; /* SCSI command */ 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 Len : Register<0x7, 16> { }; /* transfer length */
struct Ctl : Register<0x9, 8> { }; /* controll */ 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() void dump()
{ {
@ -323,7 +323,7 @@ struct Scsi::Cmd_10 : Genode::Mmio
struct Scsi::Read_capacity_10 : Cmd_10 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<Cmd_10::Op>(Opcode::READ_CAPACITY_10); write<Cmd_10::Op>(Opcode::READ_CAPACITY_10);
} }
@ -332,7 +332,7 @@ struct Scsi::Read_capacity_10 : Cmd_10
struct Scsi::Io_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<Cmd_10::Lba>(be(lba)); write<Cmd_10::Lba>(be(lba));
write<Cmd_10::Len>(be(len)); write<Cmd_10::Len>(be(len));
@ -342,7 +342,7 @@ struct Scsi::Io_10 : Cmd_10
struct Scsi::Read_10 : Io_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<Cmd_10::Op>(Opcode::READ_10); write<Cmd_10::Op>(Opcode::READ_10);
} }
@ -351,7 +351,7 @@ struct Scsi::Read_10 : Io_10
struct Scsi::Write_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<Cmd_10::Op>(Opcode::WRITE_10); write<Cmd_10::Op>(Opcode::WRITE_10);
} }
@ -362,7 +362,7 @@ struct Scsi::Write_10 : Io_10
** CBD 16 long LBA byte commands ** ** CBD 16 long LBA byte commands **
***********************************/ ***********************************/
struct Scsi::Cmd_16 : Genode::Mmio struct Scsi::Cmd_16 : Genode::Mmio<0x10>
{ {
enum { LENGTH = 16 }; enum { LENGTH = 16 };
struct Op : Register<0x0, 8> { }; /* SCSI command */ 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 Len : Register<0xa, 32> { }; /* transfer length */
struct Ctl : Register<0xf, 8> { }; /* controll */ 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() void dump()
{ {
@ -384,7 +384,7 @@ struct Scsi::Cmd_16 : Genode::Mmio
struct Scsi::Read_capacity_16 : Cmd_16 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<Cmd_16::Op>(Opcode::READ_CAPACITY_16); write<Cmd_16::Op>(Opcode::READ_CAPACITY_16);
} }
@ -393,7 +393,7 @@ struct Scsi::Read_capacity_16 : Cmd_16
struct Scsi::Io_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<Cmd_16::Lba>(be(lba)); write<Cmd_16::Lba>(be(lba));
write<Cmd_16::Len>(be(len)); write<Cmd_16::Len>(be(len));
@ -403,7 +403,7 @@ struct Scsi::Io_16 : Cmd_16
struct Scsi::Read_16 : Io_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<Cmd_16::Op>(Opcode::READ_16); write<Cmd_16::Op>(Opcode::READ_16);
} }
@ -412,7 +412,7 @@ struct Scsi::Read_16 : Io_16
struct Scsi::Write_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<Cmd_16::Op>(Opcode::WRITE_16); write<Cmd_16::Op>(Opcode::WRITE_16);
} }

View File

@ -92,7 +92,7 @@ struct Virtdev_rom::Main
Sliced_heap _heap { _env.ram(), _env.rm() }; Sliced_heap _heap { _env.ram(), _env.rm() };
Virtdev_rom::Root _root { _env, _heap, _ds }; Virtdev_rom::Root _root { _env, _heap, _ds };
struct Device : public Attached_mmio struct Device : public Attached_mmio<0xc>
{ {
struct Magic : Register<0x000, 32> { }; struct Magic : Register<0x000, 32> { };
struct Id : Register<0x008, 32> { struct Id : Register<0x008, 32> {
@ -108,8 +108,8 @@ struct Virtdev_rom::Main
}; };
}; };
Device(Env &env, addr_t base, size_t size) Device(Env &env, Byte_range_ptr const &range)
: Attached_mmio(env, base, size, false) { } : Attached_mmio(env, range, false) { }
}; };
static char const *_name_for_id(unsigned id) 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) { for (size_t idx = 0; idx < NUM_VIRTIO_TRANSPORTS; ++idx) {
addr_t addr = BASE_ADDRESS + idx * DEVICE_SIZE; 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<Device::Magic>() != VIRTIO_MMIO_MAGIC) { if (device.read<Device::Magic>() != VIRTIO_MMIO_MAGIC) {
warning("Found non VirtIO MMIO device @ ", Hex(addr)); warning("Found non VirtIO MMIO device @ ", Hex(addr));

View File

@ -96,7 +96,7 @@ class Block::Ahdi : public Partition_table
{ {
bool any_partition_valid = false; bool any_partition_valid = false;
Root_sector const root = *sector.addr<Root_sector const *>(); Root_sector const root = *(Root_sector const *)sector.buffer().start;
for (unsigned i = 0; i < MAX_PARTITIONS; i++) for (unsigned i = 0; i < MAX_PARTITIONS; i++)
if (root.partitions[i].valid()) if (root.partitions[i].valid())
any_partition_valid = true; any_partition_valid = true;
@ -107,7 +107,7 @@ class Block::Ahdi : public Partition_table
template <typename FUNC> template <typename FUNC>
void _parse_ahdi(Sync_read const &sector, FUNC const &fn) void _parse_ahdi(Sync_read const &sector, FUNC const &fn)
{ {
Root_sector &root = *sector.addr<Root_sector *>(); Root_sector &root = *(Root_sector *)sector.buffer().start;
for (unsigned i = 0; i < MAX_PARTITIONS; i++) { for (unsigned i = 0; i < MAX_PARTITIONS; i++) {
Partition_record const &part = root.partitions[i]; Partition_record const &part = root.partitions[i];

View File

@ -63,11 +63,11 @@ class Block::Sync_read : Noncopyable
private: private:
Handler &_handler; Handler &_handler;
Allocator &_alloc; Allocator &_alloc;
size_t _size { 0 }; size_t _size { 0 };
void *_buffer { nullptr }; Constructible<Byte_range_ptr> _buffer { };
bool _success { false }; bool _success { false };
/* /*
* Noncopyable * Noncopyable
@ -100,7 +100,7 @@ class Block::Sync_read : Noncopyable
~Sync_read() ~Sync_read()
{ {
_alloc.free(_buffer, _size); _alloc.free(_buffer->start, _size);
} }
bool success() const { return _success; } bool success() const { return _success; }
@ -108,8 +108,8 @@ class Block::Sync_read : Noncopyable
void consume_read_result(Block_connection::Job &, off_t offset, void consume_read_result(Block_connection::Job &, off_t offset,
char const *src, size_t length) char const *src, size_t length)
{ {
_buffer = _alloc.alloc(length); _buffer.construct((char *)_alloc.alloc(length), length);
memcpy((char *)_buffer + offset, src, length); memcpy(_buffer->start + offset, src, length);
_size += length; _size += length;
} }
@ -126,8 +126,7 @@ class Block::Sync_read : Noncopyable
_success = success; _success = success;
} }
template <typename T> T addr() const { Byte_range_ptr const &buffer() const { return *_buffer; }
return reinterpret_cast<T>(_buffer); }
}; };

View File

@ -60,7 +60,7 @@ class Block::Gpt : public Block::Partition_table
/** /**
* DCE uuid struct * DCE uuid struct
*/ */
struct Uuid : Mmio struct Uuid : Mmio<16>
{ {
struct Time_low : Register<0, 32> { }; struct Time_low : Register<0, 32> { };
struct Time_mid : Register<4, 16> { }; 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> { }; struct Node : Register_array<10, 8, 6, 8> { };
Uuid() = delete; Uuid() = delete;
Uuid(addr_t base) : Mmio(base) { }; using Mmio::Mmio;
unsigned time_low() const { return read<Time_low>(); } unsigned time_low() const { return read<Time_low>(); }
@ -98,7 +98,7 @@ class Block::Gpt : public Block::Partition_table
/** /**
* GUID parition table header * GUID parition table header
*/ */
struct Gpt_hdr : Mmio struct Gpt_hdr : Mmio<92>
{ {
struct Sig : Register<0, 64> { }; /* identifies GUID Partition Table */ struct Sig : Register<0, 64> { }; /* identifies GUID Partition Table */
struct Revision : Register<8, 32> { }; /* GPT specification revision */ 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_start : Register<40, 64> { }; /* first LBA usable for partitions */
struct Part_lba_end : Register<48, 64> { }; /* last 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 Gpe_lba : Register<72, 64> { }; /* first LBA of GPE array */
struct Entries : Register<80, 32> { }; /* number of entries in 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 */ struct Gpe_crc : Register<88, 32> { }; /* CRC32 of GPE array */
Gpt_hdr() = delete; Gpt_hdr() = delete;
Gpt_hdr(addr_t base) : Mmio(base) { }; using Mmio::Mmio;
uint64_t part_lba_start() const { return read<Part_lba_start>(); } uint64_t part_lba_start() const { return read<Part_lba_start>(); }
uint64_t part_lba_end() const { return read<Part_lba_end>(); } uint64_t part_lba_end() const { return read<Part_lba_end>(); }
@ -190,7 +190,7 @@ class Block::Gpt : public Block::Partition_table
size_t length = entries() * entry_size(); size_t length = entries() * entry_size();
Sync_read gpe(handler, alloc, gpe_lba(), length / block_size); Sync_read gpe(handler, alloc, gpe_lba(), length / block_size);
if (!gpe.success() if (!gpe.success()
|| crc32(gpe.addr<addr_t>(), length) != read<Gpe_crc>()) || crc32((addr_t)gpe.buffer().start, length) != read<Gpe_crc>())
return false; return false;
if (check_primary) { if (check_primary) {
@ -199,7 +199,7 @@ class Block::Gpt : public Block::Partition_table
if (!backup_hdr.success()) if (!backup_hdr.success())
return false; return false;
Gpt_hdr backup(backup_hdr.addr<addr_t>()); Gpt_hdr backup(backup_hdr.buffer());
if (!backup.valid(handler, alloc, block_size, false)) if (!backup.valid(handler, alloc, block_size, false))
warning("Backup GPT header is corrupted"); warning("Backup GPT header is corrupted");
} }
@ -220,12 +220,12 @@ class Block::Gpt : public Block::Partition_table
/** /**
* GUID partition entry format * GUID partition entry format
*/ */
struct Gpt_entry : Mmio struct Gpt_entry : Mmio<56 + 36 * 2>
{ {
enum { NAME_LEN = 36 }; enum { NAME_LEN = 36 };
Uuid type() const { return Uuid(base()); } /* partition type GUID */ Uuid type() const { return Uuid(range()); } /* partition type GUID */
Uuid guid() const { return Uuid(base()+ Uuid::size()); } /* unique partition GUID */ Uuid guid() const { return Uuid(range_at(Uuid::size())); } /* unique partition GUID */
struct Lba_start : Register<32, 64> { }; /* start of partition */ struct Lba_start : Register<32, 64> { }; /* start of partition */
struct Lba_end : Register<40, 64> { }; /* end 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 */ struct Name : Register_array<56, 16, NAME_LEN, 16> { }; /* partition name in UNICODE-16 */
Gpt_entry() = delete; Gpt_entry() = delete;
Gpt_entry(addr_t base) : Mmio(base) { } using Mmio::Mmio;
uint64_t lba_start() const { return read<Lba_start>(); } uint64_t lba_start() const { return read<Lba_start>(); }
uint64_t lba_end() const { return read<Lba_end>(); } uint64_t lba_end() const { return read<Lba_end>(); }
@ -340,7 +340,7 @@ class Block::Gpt : public Block::Partition_table
uint64_t used = 0; uint64_t used = 0;
for (uint32_t i = 0; i < num; i++) { 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; } if (!e.valid()) { continue; }
@ -364,7 +364,7 @@ class Block::Gpt : public Block::Partition_table
gpt.entries() * gpt.entry_size() / _info.block_size); gpt.entries() * gpt.entry_size() / _info.block_size);
if (!entry_array.success()) if (!entry_array.success())
return false; return false;
Gpt_entry entries(entry_array.addr<addr_t>()); Gpt_entry entries(entry_array.buffer());
_gpt_part_lba_end = gpt.part_lba_end(); _gpt_part_lba_end = gpt.part_lba_end();
_gpt_total = (gpt.part_lba_end() - gpt.part_lba_start()) + 1; _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++) { 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()) if (!e.valid())
continue; continue;
@ -404,7 +404,7 @@ class Block::Gpt : public Block::Partition_table
if (!s.success()) if (!s.success())
return false; return false;
Gpt_hdr gpt_hdr(s.addr<addr_t>()); Gpt_hdr gpt_hdr(s.buffer());
if (!_parse_gpt(gpt_hdr)) if (!_parse_gpt(gpt_hdr))
return false; return false;

View File

@ -52,7 +52,7 @@ class Block::Mbr : public Partition_table
/** /**
* Partition table entry format * Partition table entry format
*/ */
struct Partition_record : Mmio struct Partition_record : Mmio<16>
{ {
struct Type : Register<4, 8> struct Type : Register<4, 8>
{ {
@ -66,8 +66,7 @@ class Block::Mbr : public Partition_table
Partition_record() = delete; Partition_record() = delete;
Partition_record(addr_t base) using Mmio::Mmio;
: Mmio(base) { }
bool valid() const { return read<Type>() != Type::INVALID; } bool valid() const { return read<Type>() != Type::INVALID; }
bool extended() const { return read<Type>() == Type::EXTENTED_CHS || bool extended() const { return read<Type>() == Type::EXTENTED_CHS ||
@ -83,7 +82,7 @@ class Block::Mbr : public Partition_table
/** /**
* Master/Extented boot record format * Master/Extented boot record format
*/ */
struct Boot_record : Mmio struct Boot_record : Mmio<512>
{ {
struct Magic : Register<510, 16> struct Magic : Register<510, 16>
{ {
@ -92,7 +91,7 @@ class Block::Mbr : public Partition_table
Boot_record() = delete; Boot_record() = delete;
Boot_record(addr_t base) : Mmio(base) { } using Mmio::Mmio;
bool valid() const bool valid() const
{ {
@ -100,9 +99,9 @@ class Block::Mbr : public Partition_table
return read<Magic>() == Magic::NUMBER; return read<Magic>() == 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 <typename FUNC> template <typename FUNC>
void _parse_extended(Partition_record const &record, FUNC const &f) const void _parse_extended(Partition_record const &record, FUNC const &f) const
{ {
Reconstructible<Partition_record const> r(record.base()); Reconstructible<Partition_record const> r(record.range());
unsigned lba = r->lba(); unsigned lba = r->lba();
unsigned last_lba = 0; unsigned last_lba = 0;
@ -124,7 +123,7 @@ class Block::Mbr : public Partition_table
if (!s.success()) if (!s.success())
return; return;
Boot_record const ebr(s.addr<addr_t>()); Boot_record const ebr(s.buffer());
if (!ebr.valid()) if (!ebr.valid())
return; return;
@ -188,7 +187,7 @@ class Block::Mbr : public Partition_table
return Parse_result::NO_MBR; return Parse_result::NO_MBR;
/* check for MBR */ /* check for MBR */
Boot_record const mbr(s.addr<addr_t>()); Boot_record const mbr(s.buffer());
if (!mbr.valid()) if (!mbr.valid())
return Parse_result::NO_MBR; return Parse_result::NO_MBR;

View File

@ -54,7 +54,7 @@ class Block::Partition_table : Interface, Noncopyable
enum { BYTES = 4096 }; enum { BYTES = 4096 };
Sync_read fs(_handler, _alloc, lba, BYTES / _info.block_size); Sync_read fs(_handler, _alloc, lba, BYTES / _info.block_size);
if (fs.success()) if (fs.success())
return Fs::probe(fs.addr<uint8_t*>(), BYTES); return Fs::probe((uint8_t *)fs.buffer().start, BYTES);
else else
return Fs::Type(); return Fs::Type();
} }

View File

@ -17,7 +17,7 @@
/* Genode includes */ /* Genode includes */
#include <os/attached_mmio.h> #include <os/attached_mmio.h>
class M4if : Genode::Attached_mmio class M4if : Genode::Attached_mmio<0x11c>
{ {
private: private:
@ -58,8 +58,8 @@ class M4if : Genode::Attached_mmio
public: public:
M4if(Genode::Env &env, Genode::addr_t base, Genode::size_t size) M4if(Genode::Env &env, Genode::Byte_range_ptr const &range)
: Genode::Attached_mmio(env, base, size) { } : Attached_mmio(env, range) { }
void set_region0(Genode::addr_t addr, Genode::size_t size) void set_region0(Genode::addr_t addr, Genode::size_t size)
{ {

View File

@ -55,7 +55,7 @@ class Main
KERNEL_OFFSET, Machine_type(MACHINE_QSB), KERNEL_OFFSET, Machine_type(MACHINE_QSB),
Board_revision(BOARD_QSB), Board_revision(BOARD_QSB),
_heap, _exception_handler }; _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() }; Serial_driver _serial { _env.ram(), _env.rm() };
Block_driver _block { _env, _config.xml(), _heap, _vm }; Block_driver _block { _env, _config.xml(), _heap, _vm };

View File

@ -26,7 +26,7 @@ class Mmio_big_endian_access
private: 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'
@ -34,8 +34,7 @@ class Mmio_big_endian_access
template <typename ACCESS_T> template <typename ACCESS_T>
inline void _write(off_t const offset, ACCESS_T const value) inline void _write(off_t const offset, ACCESS_T const value)
{ {
addr_t const dst = _base + offset; *(ACCESS_T volatile *)(_range.start + offset) = host_to_big_endian(value);
*(ACCESS_T volatile *)dst = host_to_big_endian(value);
} }
/** /**
@ -44,30 +43,38 @@ class Mmio_big_endian_access
template <typename ACCESS_T> template <typename ACCESS_T>
inline ACCESS_T _read(off_t const &offset) const inline ACCESS_T _read(off_t const &offset) const
{ {
addr_t const dst = _base + offset; return host_to_big_endian(*(ACCESS_T volatile *)(_range.start + offset));
ACCESS_T const value = *(ACCESS_T volatile *)dst;
return host_to_big_endian(value);
} }
public: 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 <size_t MMIO_SIZE>
struct Mmio : Mmio_big_endian_access, struct Mmio : Mmio_big_endian_access,
Register_set<Mmio_big_endian_access> Register_set<Mmio_big_endian_access, MMIO_SIZE>
{ {
Mmio(addr_t const base) static constexpr size_t SIZE = MMIO_SIZE;
Mmio(Byte_range_ptr const &range)
: :
Mmio_big_endian_access(base), Mmio_big_endian_access(range),
Register_set(*static_cast<Mmio_big_endian_access *>(this)) { } Register_set<Mmio_big_endian_access, SIZE>(*static_cast<Mmio_big_endian_access *>(this)) { }
}; };
struct Fdt_header : Mmio struct Fdt_header : Mmio<10*4>
{ {
struct Magic : Register<0x0, 32> {}; struct Magic : Register<0x0, 32> {};
struct Totalsize : Register<0x4, 32> {}; struct Totalsize : Register<0x4, 32> {};
@ -81,19 +88,15 @@ struct Fdt_header : Mmio
struct Size_dt_struct : Register<0x24, 32> {}; struct Size_dt_struct : Register<0x24, 32> {};
using Mmio::Mmio; 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 Address : Register<0, 64> {};
struct Size : Register<8, 64> {}; struct Size : Register<8, 64> {};
using Mmio::Mmio; using Mmio::Mmio;
enum { SIZE = 2*8 };
}; };
@ -106,35 +109,37 @@ enum Fdt_tokens {
}; };
struct Fdt_token : Mmio template <size_t SIZE>
struct Fdt_token_tpl : Mmio<SIZE>
{ {
struct Type : Register<0, 32> {}; using Base = Mmio<SIZE>;
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>(type); Base::template write<Type>(type);
} }
enum { SIZE = 4 };
}; };
struct Fdt_prop : Fdt_token using Fdt_token = Fdt_token_tpl<0x4>;
struct Fdt_prop : Fdt_token_tpl<Fdt_token::SIZE + 2*4>
{ {
struct Len : Register<4, 32> {}; struct Len : Register<4, 32> {};
struct Nameoff : Register<8, 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<Fdt_prop::Len>(len); write<Fdt_prop::Len>(len);
write<Fdt_prop::Nameoff>(name_offset); write<Fdt_prop::Nameoff>(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) 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; off += Fdt_token::SIZE;
_buffer.write(off, name.string(), name.length()); _buffer.write(off, name.string(), name.length());
off += (uint32_t)name.length(); off += (uint32_t)name.length();
off = align_addr(off, 2); off = align_addr(off, 2);
fn(); 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; off += Fdt_token::SIZE;
}; };
auto property = [&] (auto const & name, auto const & val) auto property = [&] (auto const & name, auto const & val)
{ {
_dict.add(name); _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)); _dict.offset(name));
off += Fdt_prop::SIZE; off += Fdt_prop::SIZE;
val.write(off, _buffer); 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; 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 Vmm::Fdt_generator::generate(Config const & config,
void * initrd_start, size_t initrd_size) void * initrd_start, size_t initrd_size)
{ {
Fdt_header header(_buffer.addr); Fdt_header header({(char *)_buffer.addr, _buffer.size});
header.write<Fdt_header::Magic>(FDT_MAGIC); header.write<Fdt_header::Magic>(FDT_MAGIC);
header.write<Fdt_header::Version>(FDT_VERSION); header.write<Fdt_header::Version>(FDT_VERSION);
header.write<Fdt_header::Last_comp_version>(FDT_COMP_VERSION); header.write<Fdt_header::Last_comp_version>(FDT_COMP_VERSION);
@ -382,7 +387,7 @@ void Vmm::Fdt_generator::generate(Config const & config,
uint32_t off = Fdt_header::SIZE; uint32_t off = Fdt_header::SIZE;
header.write<Fdt_header::Off_mem_rsvmap>(off); header.write<Fdt_header::Off_mem_rsvmap>(off);
Fdt_reserve_entry memory(_buffer.addr+off); Fdt_reserve_entry memory({(char *)_buffer.addr+off, _buffer.size-off});
memory.write<Fdt_reserve_entry::Address>(0); memory.write<Fdt_reserve_entry::Address>(0);
memory.write<Fdt_reserve_entry::Size>(0); memory.write<Fdt_reserve_entry::Size>(0);
@ -391,7 +396,7 @@ void Vmm::Fdt_generator::generate(Config const & config,
_generate_tree(off, config, initrd_start, initrd_size); _generate_tree(off, config, initrd_start, initrd_size);
header.write<Fdt_header::Size_dt_struct>(off-Fdt_header::SIZE-Fdt_reserve_entry::SIZE); header.write<Fdt_header::Size_dt_struct>((uint32_t)(off-Fdt_header::SIZE-Fdt_reserve_entry::SIZE));
header.write<Fdt_header::Off_dt_strings>(off); header.write<Fdt_header::Off_dt_strings>(off);
header.write<Fdt_header::Size_dt_strings>(_dict.length()); header.write<Fdt_header::Size_dt_strings>(_dict.length());

View File

@ -21,29 +21,34 @@ class Ram {
private: private:
Genode::addr_t const _base; using Byte_range_ptr = Genode::Byte_range_ptr;
Genode::size_t const _size; using addr_t = Genode::addr_t;
Genode::addr_t const _local; using size_t = Genode::size_t;
addr_t const _guest_base;
Byte_range_ptr const _local_range;
public: public:
Ram(Genode::addr_t const addr, Ram(addr_t guest_base, Byte_range_ptr const &local_range)
Genode::size_t const sz, : _guest_base(guest_base), _local_range(local_range.start, local_range.num_bytes) { }
Genode::addr_t const local)
: _base(addr), _size(sz), _local(local) { }
Genode::addr_t base() const { return _base; } size_t size() const { return _local_range.num_bytes; }
Genode::size_t size() const { return _size; } addr_t guest_base() const { return _guest_base; }
Genode::addr_t local() const { return _local; } 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 || addr_t guest_base = (addr_t)guest_range.start;
size == 0 || guest + size >= _base + _size) 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: ", 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};
} }
}; };

View File

@ -103,8 +103,7 @@ class Vmm::Virtio_block_request
template <typename T> template <typename T>
T * _desc_addr(Descriptor const & desc) const { T * _desc_addr(Descriptor const & desc) const {
return (T*) _ram.local_address((addr_t)desc.address(), return (T*) _ram.to_local_range({(char *)desc.address(), desc.length()}).start; }
desc.length()); }
Index _request_idx; Index _request_idx;
Descriptor _request { _array.get(_request_idx) }; Descriptor _request { _array.get(_request_idx) };

View File

@ -34,11 +34,11 @@ class Vmm::Virtio_console : public Virtio_device<Virtio_split_queue, 2>
{ {
Genode::Mutex::Guard guard(_mutex); 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; 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; return length;
}; };
@ -52,10 +52,10 @@ class Vmm::Virtio_console : public Virtio_device<Virtio_split_queue, 2>
{ {
if (idx != TX) return; if (idx != TX) return;
auto write = [&] (addr_t data, size_t size) auto write = [&] (Byte_range_ptr const &data)
{ {
_terminal.write((void *)data, size); _terminal.write((void *)data.start, data.num_bytes);
return size; return data.num_bytes;
}; };
if (_queue[TX]->notify(write)) if (_queue[TX]->notify(write))

View File

@ -73,21 +73,24 @@ class Vmm::Virtio_split_queue
using Descriptor_index = Index<MAX_SIZE_LOG2>; using Descriptor_index = Index<MAX_SIZE_LOG2>;
struct Queue_base : Mmio template <size_t SIZE>
struct Queue_base : Mmio<SIZE>
{ {
using Base = Mmio<SIZE>;
uint16_t const max; uint16_t const max;
Queue_base(addr_t base, uint16_t max) Queue_base(Byte_range_ptr const &range, uint16_t max)
: Mmio(base), max(max) {} : Base(range), max(max) {}
struct Flags : Register<0x0, 16> { }; struct Flags : Base::template Register<0x0, 16> { };
struct Idx : Register<0x2, 16> { }; struct Idx : Base::template Register<0x2, 16> { };
Ring_index current() { return read<Idx>(); } Ring_index current() { return Base::template read<Idx>(); }
}; };
struct Avail_queue : Queue_base struct Avail_queue : Queue_base<0x4 + MAX_SIZE * 2>
{ {
using Queue_base::Queue_base; using Queue_base::Queue_base;
@ -105,7 +108,7 @@ class Vmm::Virtio_split_queue
} _avail; } _avail;
struct Used_queue : Queue_base struct Used_queue : Queue_base<0x4 + MAX_SIZE * 8>
{ {
using Queue_base::Queue_base; using Queue_base::Queue_base;
@ -129,7 +132,7 @@ class Vmm::Virtio_split_queue
} _used; } _used;
struct Descriptor : Mmio struct Descriptor : Mmio<0x10>
{ {
using Mmio::Mmio; using Mmio::Mmio;
@ -154,19 +157,24 @@ class Vmm::Virtio_split_queue
struct Descriptor_array struct Descriptor_array
{ {
size_t const elem_size { 16 }; size_t const elem_size { 16 };
unsigned const max; unsigned const max;
addr_t const start; Byte_range_ptr const guest_range;
Byte_range_ptr const local_range;
Descriptor_array(Ram & ram, addr_t base, unsigned const max) Descriptor_array(Ram & ram, addr_t base, unsigned const max)
: :
max(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) Descriptor get(Descriptor_index idx)
{ {
if (idx.idx() >= max) error("Descriptor_index out of bounds"); 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; } _descriptors;
@ -182,8 +190,8 @@ class Vmm::Virtio_split_queue
uint16_t const queue_num, uint16_t const queue_num,
Ram & ram) Ram & ram)
: :
_avail(ram.local_address(driver_area, 6+2*queue_num), queue_num), _avail(ram.to_local_range({(char *)driver_area, 6+2*(size_t)queue_num}), queue_num),
_used(ram.local_address(device_area, 6+8*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), _descriptors(ram, descriptor_area, queue_num),
_ram(ram) { } _ram(ram) { }
@ -205,8 +213,7 @@ class Vmm::Virtio_split_queue
if (!address || !size) { break; } if (!address || !size) { break; }
try { try {
addr_t data = _ram.local_address((addr_t)address, size); size_t consumed = func(_ram.to_local_range({(char *)address, size}));
size_t consumed = func(data, size);
if (!consumed) { break; } if (!consumed) { break; }
_used.add(_cur_idx, id, consumed); _used.add(_cur_idx, id, consumed);
written = true; written = true;

View File

@ -44,7 +44,7 @@ void Vmm::Virtio_gpu_queue::notify(Virtio_gpu_device & dev)
void Vmm::Virtio_gpu_control_request::_get_display_info() void Vmm::Virtio_gpu_control_request::_get_display_info()
{ {
Framebuffer::Mode mode = _device.resize(); 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); memset((void*)dir.base(), 0, Display_info_response::SIZE);
dir.write<Control_header::Type>(Control_header::Type::OK_DISPLAY_INFO); dir.write<Control_header::Type>(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() void Vmm::Virtio_gpu_control_request::_resource_create_2d()
{ {
Resource_create_2d c2d { _desc_addr(0) }; Resource_create_2d c2d { _desc_range(0) };
Control_header response { _desc_addr(1) }; Control_header response { _desc_range(1) };
if (c2d.read<Resource_create_2d::Format>() != if (c2d.read<Resource_create_2d::Format>() !=
Resource_create_2d::Format::B8G8R8X8) { Resource_create_2d::Format::B8G8R8X8) {
@ -90,8 +90,8 @@ void Vmm::Virtio_gpu_control_request::_resource_delete()
using Resource = Virtio_gpu_device::Resource; using Resource = Virtio_gpu_device::Resource;
using Scanout = Resource::Scanout; using Scanout = Resource::Scanout;
Resource_unref rur { _desc_addr(0) }; Resource_unref rur { _desc_range(0) };
Control_header response { _desc_addr(1) }; Control_header response { _desc_range(1) };
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID); response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID);
uint32_t id = rur.read<Resource_unref::Resource_id>(); uint32_t id = rur.read<Resource_unref::Resource_id>();
@ -113,9 +113,9 @@ void Vmm::Virtio_gpu_control_request::_resource_attach_backing()
using Resource = Virtio_gpu_device::Resource; using Resource = Virtio_gpu_device::Resource;
using Entry = Resource_attach_backing::Memory_entry; using Entry = Resource_attach_backing::Memory_entry;
Resource_attach_backing rab { _desc_addr(0) }; Resource_attach_backing rab { _desc_range(0) };
addr_t entry_base { _desc_addr(1) }; Byte_range_ptr entry_range { _desc_range(1) };
Control_header response { _desc_addr(2) }; Control_header response { _desc_range(2) };
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID); response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID);
uint32_t id = rab.read<Resource_attach_backing::Resource_id>(); uint32_t id = rab.read<Resource_attach_backing::Resource_id>();
@ -127,10 +127,11 @@ void Vmm::Virtio_gpu_control_request::_resource_attach_backing()
try { try {
for (unsigned i = 0; i < nr; i++) { 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<Entry::Length>(); size_t sz = entry.read<Entry::Length>();
addr_t off = _device._ram.local_address((addr_t)entry.read<Entry::Address>(), sz) addr_t off = (addr_t)_device._ram.to_local_range({(char *)entry.read<Entry::Address>(), sz}).start
- _device._ram.local(); - _device._ram.local_base();
res.attach(off, sz); res.attach(off, sz);
} }
response.write<Control_header::Type>(Control_header::Type::OK_NO_DATA); response.write<Control_header::Type>(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() void Vmm::Virtio_gpu_control_request::_set_scanout()
{ {
Set_scanout scr { _desc_addr(0) }; Set_scanout scr { _desc_range(0) };
Control_header response { _desc_addr(1) }; Control_header response { _desc_range(1) };
uint32_t id = scr.read<Set_scanout::Resource_id>(); uint32_t id = scr.read<Set_scanout::Resource_id>();
uint32_t sid = scr.read<Set_scanout::Scanout_id>(); uint32_t sid = scr.read<Set_scanout::Scanout_id>();
@ -177,8 +178,8 @@ void Vmm::Virtio_gpu_control_request::_set_scanout()
void Vmm::Virtio_gpu_control_request::_resource_flush() void Vmm::Virtio_gpu_control_request::_resource_flush()
{ {
Resource_flush rf { _desc_addr(0) }; Resource_flush rf { _desc_range(0) };
Control_header response { _desc_addr(1) }; Control_header response { _desc_range(1) };
uint32_t id = rf.read<Resource_flush::Resource_id>(); uint32_t id = rf.read<Resource_flush::Resource_id>();
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID); response.write<Control_header::Type>(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() void Vmm::Virtio_gpu_control_request::_transfer_to_host_2d()
{ {
Transfer_to_host_2d tth { _desc_addr(0) }; Transfer_to_host_2d tth { _desc_range(0) };
Control_header response { _desc_addr(1) }; Control_header response { _desc_range(1) };
uint32_t id = tth.read<Transfer_to_host_2d::Resource_id>(); uint32_t id = tth.read<Transfer_to_host_2d::Resource_id>();
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID); response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_RESOURCE_ID);

View File

@ -56,11 +56,12 @@ class Vmm::Virtio_gpu_control_request
using Descriptor = Virtio_gpu_queue::Descriptor; using Descriptor = Virtio_gpu_queue::Descriptor;
using Descriptor_array = Virtio_gpu_queue::Descriptor_array; using Descriptor_array = Virtio_gpu_queue::Descriptor_array;
struct Control_header : Mmio template <size_t SIZE>
struct Control_header_tpl : Mmio<SIZE>
{ {
enum { SIZE = 24 }; using Base = Mmio<SIZE>;
struct Type : Register<0, 32> struct Type : Base::template Register<0, 32>
{ {
enum Commands { enum Commands {
/* 2D commands */ /* 2D commands */
@ -95,17 +96,17 @@ class Vmm::Virtio_gpu_control_request
ERR_INVALID_PARAMETER, ERR_INVALID_PARAMETER,
}; };
}; };
struct Flags : Register<0x4, 32> {}; struct Flags : Base::template Register<0x4, 32> {};
struct Fence_id : Register<0x8, 64> {}; struct Fence_id : Base::template Register<0x8, 64> {};
struct Ctx_id : Register<0x10, 32> {}; struct Ctx_id : Base::template Register<0x10, 32> {};
using Mmio::Mmio; using Base::Mmio;
}; };
struct Display_info_response : Control_header using Control_header = Control_header_tpl<24>;
{
enum { SIZE = Control_header::SIZE + 24*16 };
struct Display_info_response : Control_header_tpl<Control_header::SIZE + 24*16>
{
struct X : Register<0x18, 32> {}; struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {}; struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {}; struct Width : Register<0x20, 32> {};
@ -113,13 +114,11 @@ class Vmm::Virtio_gpu_control_request
struct Enabled : Register<0x28, 32> {}; struct Enabled : Register<0x28, 32> {};
struct Flags : Register<0x2c, 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<Control_header::SIZE + 16>
{ {
enum { SIZE = Control_header::SIZE + 16 };
struct Resource_id : Register<0x18, 32> {}; struct Resource_id : Register<0x18, 32> {};
struct Format : Register<0x1c, 32> struct Format : Register<0x1c, 32>
@ -139,42 +138,34 @@ class Vmm::Virtio_gpu_control_request
struct Width : Register<0x20, 32> {}; struct Width : Register<0x20, 32> {};
struct Height : Register<0x24, 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<Control_header::SIZE + 8>
{ {
enum { SIZE = Control_header::SIZE + 8 };
struct Resource_id : Register<0x18, 32> {}; 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<Control_header::SIZE + 8>
{ {
enum { SIZE = Control_header::SIZE + 8 };
struct Resource_id : Register<0x18, 32> {}; struct Resource_id : Register<0x18, 32> {};
struct Nr_entries : Register<0x1c, 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 Address : Register<0x0, 64> {};
struct Length : Register<0x8, 32> {}; struct Length : Register<0x8, 32> {};
using Mmio::Mmio; 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<Control_header::SIZE + 24>
{ {
enum { SIZE = Control_header::SIZE + 24 };
struct X : Register<0x18, 32> {}; struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {}; struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {}; struct Width : Register<0x20, 32> {};
@ -182,26 +173,22 @@ class Vmm::Virtio_gpu_control_request
struct Scanout_id : Register<0x28, 32> {}; struct Scanout_id : Register<0x28, 32> {};
struct Resource_id : Register<0x2c, 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<Control_header::SIZE + 24>
{ {
enum { SIZE = Control_header::SIZE + 24 };
struct X : Register<0x18, 32> {}; struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {}; struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {}; struct Width : Register<0x20, 32> {};
struct Height : Register<0x24, 32> {}; struct Height : Register<0x24, 32> {};
struct Resource_id : Register<0x28, 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<Control_header::SIZE + 32>
{ {
enum { SIZE = Control_header::SIZE + 32 };
struct X : Register<0x18, 32> {}; struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {}; struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {}; struct Width : Register<0x20, 32> {};
@ -209,7 +196,7 @@ class Vmm::Virtio_gpu_control_request
struct Offset : Register<0x28, 64> {}; struct Offset : Register<0x28, 64> {};
struct Resource_id : Register<0x30, 32> {}; struct Resource_id : Register<0x30, 32> {};
using Control_header::Control_header; using Control_header_tpl::Control_header_tpl;
}; };
Descriptor_array & _array; Descriptor_array & _array;
@ -232,14 +219,14 @@ class Vmm::Virtio_gpu_control_request
return _array.get(idx); return _array.get(idx);
} }
addr_t _desc_addr(unsigned i) Byte_range_ptr _desc_range(unsigned i)
{ {
Descriptor d = _desc(i); Descriptor d = _desc(i);
/* we only support 32-bit ram addresses by now */ /* 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 _get_display_info();
void _resource_create_2d(); void _resource_create_2d();

View File

@ -67,10 +67,8 @@ class Vmm::Virtio_input_device : public Virtio_device<Virtio_split_queue, 2>
Cpu::Signal_handler<Virtio_input_device> _handler; Cpu::Signal_handler<Virtio_input_device> _handler;
struct Virtio_input_event : Mmio struct Virtio_input_event : Mmio<8>
{ {
enum { SIZE = 8 };
struct Type : Register<0, 16> {}; struct Type : Register<0, 16> {};
struct Code : Register<2, 16> {}; struct Code : Register<2, 16> {};
struct Value : Register<4, 32> {}; struct Value : Register<4, 32> {};
@ -213,20 +211,20 @@ class Vmm::Virtio_input_device : public Virtio_device<Virtio_split_queue, 2>
if (!_queue[0].constructed()) if (!_queue[0].constructed())
return; return;
bool irq = _queue[0]->notify([&] (addr_t addr, size_t size) { bool irq = _queue[0]->notify([&] (Byte_range_ptr const &data) {
if (size < Virtio_input_event::SIZE) { if (data.num_bytes < Virtio_input_event::SIZE) {
warning("wrong virtioqueue packet size for input ", size); warning("wrong virtioqueue packet size for input ", data.num_bytes);
return 0UL; return 0UL;
} }
Virtio_input_event vie(addr); Virtio_input_event vie(data);
if (_state == IN_MOTION) { if (_state == IN_MOTION) {
vie.write<Virtio_input_event::Type>(Linux_evdev::EV_ABS); vie.write<Virtio_input_event::Type>(Linux_evdev::EV_ABS);
vie.write<Virtio_input_event::Code>(Linux_evdev::ABS_Y); vie.write<Virtio_input_event::Code>(Linux_evdev::ABS_Y);
vie.write<Virtio_input_event::Value>(_motion_y); vie.write<Virtio_input_event::Value>(_motion_y);
_state = SYNC; _state = SYNC;
return size; return data.num_bytes;
} }
if (_state == SYNC) { if (_state == SYNC) {
@ -234,7 +232,7 @@ class Vmm::Virtio_input_device : public Virtio_device<Virtio_split_queue, 2>
vie.write<Virtio_input_event::Code>(0); vie.write<Virtio_input_event::Code>(0);
vie.write<Virtio_input_event::Value>(0); vie.write<Virtio_input_event::Value>(0);
_state = READY; _state = READY;
return size; return data.num_bytes;
} }
if (_num_events == _idx_events) { if (_num_events == _idx_events) {
@ -269,7 +267,7 @@ class Vmm::Virtio_input_device : public Virtio_device<Virtio_split_queue, 2>
_motion_y = y; _motion_y = y;
_state = IN_MOTION; _state = IN_MOTION;
}); });
return size; return data.num_bytes;
}); });
if (irq) _buffer_notification(); if (irq) _buffer_notification();

View File

@ -51,21 +51,21 @@ class Vmm::Virtio_net : public Virtio_device<Virtio_split_queue, 2>
void _rx() void _rx()
{ {
/* 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()) if (!_nic.rx()->packet_avail() || !_nic.rx()->ready_to_ack())
return 0ul; return 0ul;
Nic::Packet_descriptor const rx_packet = _nic.rx()->get_packet(); 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), _nic.rx()->packet_content(rx_packet),
sz - NIC_HEADER_SIZE); sz - NIC_HEADER_SIZE);
_nic.rx()->acknowledge_packet(rx_packet); _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; return sz;
}; };
@ -79,22 +79,22 @@ class Vmm::Virtio_net : public Virtio_device<Virtio_split_queue, 2>
void _tx() 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; 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; Nic::Packet_descriptor tx_packet;
try { 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) { catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
return 0ul; } return 0ul; }
Genode::memcpy(_nic.tx()->packet_content(tx_packet), Genode::memcpy(_nic.tx()->packet_content(tx_packet),
(void *)data, size); (void *)body.start, body.num_bytes);
_nic.tx()->submit_packet(tx_packet); _nic.tx()->submit_packet(tx_packet);
return size; return body.num_bytes;
}; };
if (!_queue[TX].constructed()) return; if (!_queue[TX].constructed()) return;

Some files were not shown because too many files have changed in this diff Show More