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)
{
struct Src : Genode::Mmio
struct Src : Genode::Mmio<0x84>
{
struct A7_cr0 : Register<0x4, 32>
{
@ -232,7 +232,7 @@ void Board::Cpu::wake_up_all_cpus(void * const ip)
struct Gpr3 : Register<0x7c, 32> {}; /* ep core 1 */
struct Gpr4 : Register<0x80, 32> {}; /* ep core 1 */
Src(void * const entry) : Genode::Mmio(SRC_MMIO_BASE)
Src(void * const entry) : Mmio({(char *)SRC_MMIO_BASE, Mmio::SIZE})
{
write<Gpr3>((Gpr3::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
* an interrupt
*/
struct System_control : Genode::Mmio
struct System_control : Genode::Mmio<0x38>
{
struct Flagsset : Register<0x30, 32> { };
struct Flagsclr : Register<0x34, 32> { };
System_control(void * const ip) : Mmio(SYSTEM_CONTROL_MMIO_BASE)
System_control(void * const ip) : Mmio({(char *)SYSTEM_CONTROL_MMIO_BASE, Mmio::SIZE})
{
write<Flagsclr>(~0UL);
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>
{
@ -72,7 +72,7 @@ struct Scu : Genode::Mmio
struct Cpu3_way : Bitfield<12, 4> { };
};
Scu() : Genode::Mmio(Board::Cpu_mmio::SCU_MMIO_BASE) { }
Scu() : Mmio({(char *)Board::Cpu_mmio::SCU_MMIO_BASE, Mmio::SIZE}) { }
void invalidate()
{

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
Hw::Pic::Pic()
:
Genode::Mmio(Board::IRQ_CONTROLLER_BASE)
Mmio({(char *)Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE})
{
for (unsigned i = 0; i < NR_OF_IRQ; i++) {
write<Intsec::Nonsecure>(!Board::secure_irq(i), i);

View File

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

View File

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

View File

@ -35,7 +35,7 @@ enum {
Board::Timer::Timer(unsigned cpu_id)
:
Mmio(Platform::mmio_to_virt(Board::Cpu_mmio::GLOBAL_TIMER_MMIO_BASE))
Mmio({(char *)Platform::mmio_to_virt(Board::Cpu_mmio::GLOBAL_TIMER_MMIO_BASE), Mmio::SIZE})
{
enum { PRESCALER = Board::CORTEX_A9_GLOBAL_TIMER_DIV - 1 };

View File

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

View File

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

View File

@ -28,7 +28,7 @@ unsigned Timer::interrupt_id() const { return Board::EPIT_1_IRQ; }
Board::Timer::Timer(unsigned)
:
Mmio(Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE))
Mmio({(char *)Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE), Mmio::SIZE})
{
init();
}

View File

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

View File

@ -18,4 +18,4 @@
using namespace Core;
Hw::Pic::Pic() : Mmio(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE)) { }
Hw::Pic::Pic() : Mmio({(char *)Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE), Mmio::SIZE}) { }

View File

@ -23,7 +23,7 @@ using Board::Pic;
Pic::Gich::Gich()
:
Genode::Mmio(Core::Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_VT_CTRL_BASE))
Mmio({(char *)Core::Platform::mmio_to_virt(Board::Cpu_mmio::IRQ_CONTROLLER_VT_CTRL_BASE), Mmio::SIZE})
{ }

View File

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

View File

@ -17,7 +17,7 @@
Board::Pic::Pic(Global_interrupt_controller &)
:
_plic(Core::Platform::mmio_to_virt(Board::PLIC_BASE))
_plic({(char *)Core::Platform::mmio_to_virt(Board::PLIC_BASE), Board::PLIC_SIZE})
{
/* enable external interrupts */
enum { SEIE = 0x200 };

View File

@ -35,14 +35,14 @@ class Genode::Fpu_context
*/
char _fxsave_area[527];
struct Context : Mmio
struct Context : Mmio<512>
{
struct Fcw : Register<0, 16> { };
struct Mxcsr : Register<24, 32> { };
Context(addr_t const base) : Mmio(base)
Context(addr_t const base) : Mmio({(char *)base, Mmio::SIZE})
{
memset((void *)base, 0, 512);
memset((void *)base, 0, Mmio::SIZE);
write<Fcw>(0x37f); /* mask exceptions SysV ABI */
write<Mxcsr>(0x1f80);
}

View File

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

View File

@ -17,6 +17,7 @@
/* Genode includes */
#include <util/mmio.h>
#include <hw/spec/x86_64/x86_64.h>
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:
@ -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:

View File

@ -55,7 +55,7 @@ uint32_t Board::Timer::pit_calc_timer_freq(void)
Board::Timer::Timer(unsigned)
:
Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()))
Mmio({(char *)Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()), Mmio::SIZE})
{
init();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -59,20 +59,20 @@ struct Hw::Apic_madt
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 Paddr : Register <0x04, 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 }; };
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; };
};
@ -81,7 +81,7 @@ struct Hw::Apic_madt
/* ACPI spec 5.2.9 and ACPI GAS 5.2.3.2 */
struct Hw::Acpi_fadt : Genode::Mmio
struct Hw::Acpi_fadt : Genode::Mmio<276>
{
enum Addressspace { IO = 0x1 };
@ -174,7 +174,7 @@ struct Hw::Acpi_fadt : Genode::Mmio
asm volatile ("outl %0, %w1" : : "a"(val), "Nd"(port));
}
Acpi_fadt(Acpi_generic const * a) : Mmio(Genode::addr_t(a)) { }
Acpi_fadt(Acpi_generic const * a) : Mmio({(char *)a, Mmio::SIZE}) { }
addr_t facs() const
{
@ -346,7 +346,7 @@ struct Hw::Acpi_fadt : Genode::Mmio
};
struct Hw::Acpi_facs : Genode::Mmio
struct Hw::Acpi_facs : Genode::Mmio<64>
{
struct Length : Register < 0x04, 32> { };
struct Fw_wake_vector : Register < 0x0c, 32> { };
@ -362,7 +362,7 @@ struct Hw::Acpi_facs : Genode::Mmio
write<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 {
MMIO_IOAPIC_BASE = 0xfec00000,
MMIO_IOAPIC_SIZE = 0x1000,
LAPIC_SIZE = 0xe34,
};
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
*/
class Genode::Imx_uart: Mmio
class Genode::Imx_uart: Mmio<0xa2>
{
/**
* Control register 1
@ -246,7 +246,7 @@ class Genode::Imx_uart: Mmio
*
* \param base device MMIO base
*/
Imx_uart(addr_t base, uint32_t, uint32_t) : Mmio(base)
Imx_uart(addr_t base, uint32_t, uint32_t) : Mmio({(char*)base, Mmio::SIZE})
{
init();
}

View File

@ -17,13 +17,13 @@
/* Genode includes */
#include <util/mmio.h>
namespace Genode { class Pl011_uart; }
namespace Genode { class Pl011_uart; }
/**
* Driver base for the PrimeCell UART PL011 Revision r1p3
*/
class Genode::Pl011_uart : Mmio
class Genode::Pl011_uart : Mmio<0x3a>
{
protected:
@ -132,7 +132,7 @@ class Genode::Pl011_uart : Mmio
Genode::Pl011_uart::Pl011_uart(addr_t const base, uint32_t const clock,
uint32_t const baud_rate) : Mmio(base)
uint32_t const baud_rate) : Mmio({(char *)base, Mmio::SIZE})
{
write<Uartcr>(Uartcr::Uarten::bits(1) |
Uartcr::Txe::bits(1) |

View File

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

View File

@ -15,12 +15,14 @@
#define _INCLUDE__UTIL__MMIO_H_
/* Genode includes */
#include <base/log.h>
#include <util/string.h>
#include <util/register_set.h>
namespace Genode {
class Mmio_plain_access;
class Mmio;
template <size_t> class Mmio;
}
/**
@ -32,27 +34,24 @@ class Genode::Mmio_plain_access
private:
addr_t const _base;
Byte_range_ptr const _range;
/**
* Write '_ACCESS_T' typed 'value' to MMIO base + 'offset'
* Write 'ACCESS_T' typed 'value' to MMIO base + 'offset'
*/
template <typename ACCESS_T>
inline void _write(off_t const offset, ACCESS_T const value)
{
addr_t const dst = _base + offset;
*(ACCESS_T volatile *)dst = value;
*(ACCESS_T volatile *)(_range.start + offset) = value;
}
/**
* Read '_ACCESS_T' typed from MMIO base + 'offset'
* Read 'ACCESS_T' typed from MMIO base + 'offset'
*/
template <typename ACCESS_T>
inline ACCESS_T _read(off_t const &offset) const
{
addr_t const dst = _base + offset;
ACCESS_T const value = *(ACCESS_T volatile *)dst;
return value;
return *(ACCESS_T volatile *)(_range.start + offset);
}
public:
@ -62,9 +61,16 @@ class Genode::Mmio_plain_access
*
* \param base base address of targeted MMIO region
*/
Mmio_plain_access(addr_t const base) : _base(base) { }
Mmio_plain_access(Byte_range_ptr const &range) : _range(range.start, range.num_bytes) { }
addr_t base() const { return _base; }
Byte_range_ptr range_at(off_t offset) const
{
return {_range.start + offset, _range.num_bytes - offset};
}
Byte_range_ptr range() const { return range_at(0); }
addr_t base() const { return (addr_t)range().start; }
};
@ -73,17 +79,28 @@ class Genode::Mmio_plain_access
*
* For further details refer to the documentation of the 'Register_set' class.
*/
struct Genode::Mmio : Mmio_plain_access, Register_set<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
*
* \param base base address of targeted MMIO region
* \param range byte range of targeted MMIO region
*/
Mmio(addr_t const base)
Mmio(Byte_range_ptr const &range)
:
Mmio_plain_access(base),
Register_set(*static_cast<Mmio_plain_access *>(this)) { }
Mmio_plain_access(range),
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_ */

View File

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

View File

@ -58,9 +58,9 @@ struct Cpu_state : Register<16>
/**
* 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>
{
@ -129,7 +129,7 @@ struct Test_mmio : public Mmio
struct Simple_array_1 : Register_array<0x0, 32, 2, 32> { };
struct Simple_array_2 : Register_array<0x2, 16, 4, 16> { };
struct Simple_array_2 : Register_array<0x2, 16, 3, 16> { };
struct Strict_reg : Register<0x0, 32, true>
{

View File

@ -27,7 +27,7 @@ using namespace Genode;
Timer::Time_source::Time_source(Env &env)
:
Attached_mmio(env, EPIT_2_MMIO_BASE, EPIT_2_MMIO_SIZE),
Attached_mmio(env, {(char *)EPIT_2_MMIO_BASE, EPIT_2_MMIO_SIZE}),
Signalled_time_source(env),
_timer_irq(env, unsigned(EPIT_2_IRQ))
{

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@
#include <base/attached_io_mem_dataspace.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
* generic work when inheriting from it.
*/
template <Genode::size_t SIZE>
class Genode::Attached_mmio : public Attached_io_mem_dataspace,
public Mmio
public Mmio<SIZE>
{
public:
@ -49,10 +50,9 @@ class Genode::Attached_mmio : public Attached_io_mem_dataspace,
* \throw Out_of_caps
* \throw Region_map::Region_conflict
*/
Attached_mmio(Env &env, addr_t base, size_t size,
bool write_combined = false)
: Attached_io_mem_dataspace(env, base, size, write_combined),
Mmio((addr_t)local_addr<void>()) { }
Attached_mmio(Env &env, Byte_range_ptr const &range, bool write_combined = false)
: Attached_io_mem_dataspace(env, (addr_t)range.start, range.num_bytes, write_combined),
Mmio<SIZE>({local_addr<char>(), range.num_bytes}) { }
};
#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>
{
@ -82,7 +82,7 @@ struct Pci::Config : Genode::Mmio
struct Multi_function : Bitfield<7,1> {};
};
struct Base_address : Mmio
struct Base_address : Mmio<0x8>
{
struct Bar_32bit : Register<0, 32>
{
@ -126,7 +126,7 @@ struct Pci::Config : Genode::Mmio
return _conf_value;
}
Base_address(Genode::addr_t base) : Mmio(base) { }
Base_address(Genode::Byte_range_ptr const &range) : Mmio(range) { }
bool valid() { return _conf() != 0; }
@ -202,7 +202,8 @@ struct Pci::Config : Genode::Mmio
** PCI Capabilities **
**********************/
struct Pci_capability : Genode::Mmio
template <Genode::size_t SIZE>
struct Pci_capability : Genode::Mmio<SIZE>
{
struct Id : Register<0,8>
{
@ -223,11 +224,17 @@ struct Pci::Config : Genode::Mmio
struct Pointer : Register<1,8> {};
using Genode::Mmio::Mmio;
using Mmio<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> {};
@ -279,7 +286,7 @@ struct Pci::Config : Genode::Mmio
};
struct Msi_capability : Pci_capability
struct Msi_capability : Pci_capability<0xe>
{
struct Control : Register<0x2, 16>
{
@ -315,7 +322,7 @@ struct Pci::Config : Genode::Mmio
};
struct Msi_x_capability : Pci_capability
struct Msi_x_capability : Pci_capability<0xc>
{
struct Control : Register<0x2, 16>
{
@ -337,7 +344,7 @@ struct Pci::Config : Genode::Mmio
struct Offset : Bitfield<3, 29> {};
};
struct Table_entry : Genode::Mmio
struct Table_entry : Genode::Mmio<0x10>
{
enum { SIZE = 16 };
@ -349,7 +356,7 @@ struct Pci::Config : Genode::Mmio
struct Mask : Bitfield <0, 1> { };
};
using Genode::Mmio::Mmio;
using Mmio::Mmio;
};
using Pci_capability::Pci_capability;
@ -372,7 +379,7 @@ struct Pci::Config : Genode::Mmio
};
struct Pci_express_capability : Pci_capability
struct Pci_express_capability : Pci_capability<0x3c>
{
struct Capabilities : Register<0x2, 16> {};
@ -484,7 +491,8 @@ struct Pci::Config : Genode::Mmio
enum { PCI_E_EXTENDED_CAPS_OFFSET = 0x100U };
struct Pci_express_extended_capability : Genode::Mmio
template<Genode::size_t SIZE>
struct Pci_express_extended_capability : Genode::Mmio<SIZE>
{
struct Id : Register<0x0, 16>
{
@ -504,11 +512,17 @@ struct Pci::Config : Genode::Mmio
struct Offset : Bitfield<4, 12> {};
};
using Genode::Mmio::Mmio;
using Mmio<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 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<Advanced_error_reporting_capability> adv_err_cap {};
Base_address bar0 { base() + BASE_ADDRESS_0 };
Base_address bar1 { base() + BASE_ADDRESS_0 + 0x4 };
Base_address bar0 { Mmio::range_at(BASE_ADDRESS_0) };
Base_address bar1 { Mmio::range_at(BASE_ADDRESS_0 + 0x4) };
void clear_errors() {
if (adv_err_cap.constructed()) adv_err_cap->clear(); }
@ -562,21 +576,22 @@ struct Pci::Config : Genode::Mmio
uint16_t off = read<Capability_pointer>();
while (off) {
Pci_capability cap(base() + off);
switch(cap.read<Pci_capability::Id>()) {
case Pci_capability::Id::POWER_MANAGEMENT:
power_cap.construct(base()+off); break;
case Pci_capability::Id::MSI:
msi_cap.construct(base()+off); break;
case Pci_capability::Id::MSI_X:
msi_x_cap.construct(base()+off); break;
case Pci_capability::Id::PCI_E:
pci_e_cap.construct(base()+off); break;
using Capability_header = Pci_capability_header;
Capability_header cap(Mmio::range_at(off));
switch(cap.read<Capability_header::Id>()) {
case Capability_header::Id::POWER_MANAGEMENT:
power_cap.construct(Mmio::range_at(off)); break;
case Capability_header::Id::MSI:
msi_cap.construct(Mmio::range_at(off)); break;
case Capability_header::Id::MSI_X:
msi_x_cap.construct(Mmio::range_at(off)); break;
case Capability_header::Id::PCI_E:
pci_e_cap.construct(Mmio::range_at(off)); break;
default:
/* ignore unhandled capability */ ;
}
off = cap.read<Pci_capability::Pointer>();
off = cap.read<Capability_header::Pointer>();
}
if (!pci_e_cap.constructed())
@ -584,21 +599,22 @@ struct Pci::Config : Genode::Mmio
off = PCI_E_EXTENDED_CAPS_OFFSET;
while (off) {
Pci_express_extended_capability cap(base() + off);
switch (cap.read<Pci_express_extended_capability::Id>()) {
case Pci_express_extended_capability::Id::INVALID:
using Capability_header = Pci_express_extended_capability_header;
Capability_header cap(Mmio::range_at(off));
switch (cap.read<Capability_header::Id>()) {
case Capability_header::Id::INVALID:
return;
case Pci_express_extended_capability::Id::ADVANCED_ERROR_REPORTING:
adv_err_cap.construct(base() + off); break;
case Capability_header::Id::ADVANCED_ERROR_REPORTING:
adv_err_cap.construct(Mmio::range_at(off)); break;
default:
/* ignore unhandled extended capability */ ;
}
off = cap.read<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() {
return read<Vendor>() != Vendor::INVALID; }
@ -612,13 +628,12 @@ struct Pci::Config : Genode::Mmio
template <typename MEM_FN, typename IO_FN>
void for_each_bar(MEM_FN const & memory, IO_FN const & io)
{
Genode::addr_t const reg_addr = base() + BASE_ADDRESS_0;
Genode::size_t const reg_cnt =
(read<Header_type::Type>()) ? BASE_ADDRESS_COUNT_TYPE_1
: BASE_ADDRESS_COUNT_TYPE_0;
for (unsigned i = 0; i < reg_cnt; i++) {
Base_address reg0(reg_addr + i*0x4);
Base_address reg0 { Mmio::range_at(BASE_ADDRESS_0 + i*0x4) };
if (!reg0.valid())
continue;
if (reg0.memory()) {
@ -634,7 +649,7 @@ struct Pci::Config : Genode::Mmio
if (idx > 5 || (idx > 1 && bridge()))
return;
Base_address bar { base() + BASE_ADDRESS_0 + idx*0x4 };
Base_address bar { Mmio::range_at(BASE_ADDRESS_0 + idx*0x4) };
bar.set(addr);
}
@ -660,10 +675,10 @@ struct Pci::Config_type0 : Pci::Config
using Pci::Config::Config;
Base_address bar2 { base() + BASE_ADDRESS_0 + 0x8 };
Base_address bar3 { base() + BASE_ADDRESS_0 + 0xc };
Base_address bar4 { base() + BASE_ADDRESS_0 + 0x10 };
Base_address bar5 { base() + BASE_ADDRESS_0 + 0x14 };
Base_address bar2 { Mmio::range_at(BASE_ADDRESS_0 + 0x8 ) };
Base_address bar3 { Mmio::range_at(BASE_ADDRESS_0 + 0xc ) };
Base_address bar4 { Mmio::range_at(BASE_ADDRESS_0 + 0x10) };
Base_address bar5 { Mmio::range_at(BASE_ADDRESS_0 + 0x14) };
struct Subsystem_vendor : Register<0x2c, 16> { };
struct Subsystem_device : Register<0x2e, 16> { };

View File

@ -28,7 +28,7 @@ class Platform::Device : Interface, Noncopyable
{
public:
struct Mmio;
template <size_t> struct Mmio;
struct Irq;
struct Io_port_range;
@ -38,8 +38,6 @@ class Platform::Device : Interface, Noncopyable
typedef Device_interface::Range Range;
friend class Mmio;
::Platform::Connection &_platform;
Capability<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:
@ -108,7 +107,7 @@ class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio
Mmio(Device &device, Index index)
:
Attached_dataspace(device._rm(), _ds_cap(device, index.value)),
Genode::Mmio(_local_addr())
Genode::Mmio<SIZE>({(char *)_local_addr(), size()})
{ }
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:
@ -102,7 +102,7 @@ class Virtio::Device : Platform::Device::Mmio
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) {
throw Invalid_device(); }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,9 +25,11 @@
namespace Igd {
using Genode::Byte_range_ptr;
struct Context_status_qword;
struct Common_context_regs;
template <size_t> struct Common_context_regs;
struct Generation;
@ -84,27 +86,30 @@ struct Igd::Context_status_qword : Genode::Register<64>
};
struct Igd::Common_context_regs : public Genode::Mmio
template <Genode::size_t SIZE>
struct Igd::Common_context_regs : public Genode::Mmio<SIZE>
{
using Base = Genode::Mmio<SIZE>;
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>
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>
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>
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.
*/
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:
@ -360,7 +365,7 @@ class Igd::Execlist_context : public Igd::Common_context_regs
public:
Execlist_context(addr_t const base) : Common_context_regs(base) { }
Execlist_context(Byte_range_ptr const &range) : Common_context_regs(range) { }
void setup(addr_t const ring_buffer_start,
size_t const ring_buffer_length,
@ -461,7 +466,7 @@ class Igd::Execlist_context : public Igd::Common_context_regs
template <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:
@ -596,7 +601,7 @@ class Igd::Ppgtt_context : public Igd::Common_context_regs
public:
Ppgtt_context(addr_t const base) : Common_context_regs(base) { }
Ppgtt_context(Byte_range_ptr const &range) : Common_context_regs(range) { }
void setup(uint64_t const plm4_addr)
{
@ -678,7 +683,7 @@ class Igd::Urb_atomic_context
/*
* IHD-OS-BDW-Vol 2d-11.15 p. 199
*/
class Igd::Hardware_status_page : public Igd::Common_context_regs
class Igd::Hardware_status_page : public Igd::Common_context_regs<0x32*4 + 4>
{
public:
@ -708,8 +713,8 @@ class Igd::Hardware_status_page : public Igd::Common_context_regs
struct Context_status_dwords : Common_register_array_64<16, CONTEXT_STATUS_REGISTERS> { };
struct Last_written_status_offset : Common_register<31> { };
Hardware_status_page(addr_t base)
: Common_context_regs(base)
Hardware_status_page(Byte_range_ptr const &range)
: Common_context_regs(range)
{
semaphore(0);
}
@ -784,14 +789,14 @@ class Igd::Hardware_status_page : public Igd::Common_context_regs
/*
* IHD-OS-BDW-Vol 2d-11.15 p. 303
*/
class Igd::Pphardware_status_page : public Igd::Common_context_regs
class Igd::Pphardware_status_page : public Igd::Common_context_regs<4 * 4 + 4>
{
public:
struct Ring_head_ptr_storage : Common_register<4> { };
Pphardware_status_page(addr_t base)
: Common_context_regs(base) { }
Pphardware_status_page(Byte_range_ptr const &range)
: Common_context_regs(range) { }
};
@ -848,11 +853,11 @@ class Igd::Rcs_context
public:
Rcs_context(addr_t const map_base)
Rcs_context(Byte_range_ptr const &map_range)
:
_hw_status_page (map_base),
_execlist_context(map_base + HW_STATUS_PAGE_SIZE),
_ppgtt_context (map_base + HW_STATUS_PAGE_SIZE)
_hw_status_page (map_range),
_execlist_context({map_range.start + HW_STATUS_PAGE_SIZE, map_range.num_bytes - HW_STATUS_PAGE_SIZE}),
_ppgtt_context ({map_range.start + HW_STATUS_PAGE_SIZE, map_range.num_bytes - HW_STATUS_PAGE_SIZE})
{ }
void setup(addr_t const ring_buffer_start,

View File

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

View File

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

View File

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

View File

@ -45,10 +45,10 @@ class Igd::Ring_buffer
Index _head { };
void with_dwords(auto const &fn) const {
_memory.with_vaddr([&](auto vaddr) { fn((uint32_t *)vaddr); }); }
_memory.with_vrange([&](Byte_range_ptr const &vrange) { fn((uint32_t *)vrange.start); }); }
void with_dwords(auto const &fn) {
_memory.with_vaddr([&](auto vaddr) { fn((uint32_t *)vaddr); }); }
_memory.with_vrange([&](Byte_range_ptr const &vrange) { fn((uint32_t *)vrange.start); }); }
public:

View File

@ -20,7 +20,7 @@
namespace I2c { struct Mmio; }
struct I2c::Mmio: Platform::Device::Mmio
struct I2c::Mmio: Platform::Device::Mmio<0x12>
{
struct Address : Mmio::Register<0x0, 16> {
struct Adr : Mmio::Register<0x0, 16>::Bitfield<1, 7> {};
@ -49,7 +49,7 @@ struct I2c::Mmio: Platform::Device::Mmio
struct Data : Mmio::Register<0x10, 16> {};
Mmio(Platform::Device &device) : Platform::Device::Mmio { device } { }
Mmio(Platform::Device &device) : Platform::Device::Mmio<SIZE> { device } { }
};
#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;
volatile uint32_t *_reg_base { _mmio.local_addr<uint32_t>() };
Timer::Connection _timer;
@ -281,10 +281,10 @@ class Lan9118_base
*/
class Device_not_supported { };
Lan9118_base(Platform::Device::Mmio &mmio,
Platform::Device::Irq &irq,
Signal_context_capability irq_handler,
Env &env)
Lan9118_base(Platform::Device::Mmio<0> &mmio,
Platform::Device::Irq &irq,
Signal_context_capability irq_handler,
Env &env)
:
_mmio(mmio), _irq(irq), _timer(env)
{
@ -441,10 +441,10 @@ class Uplink_client : public Signal_handler<Uplink_client>,
public:
Uplink_client(Env &env,
Allocator &alloc,
Platform::Device::Mmio &mmio,
Platform::Device::Irq &irq)
Uplink_client(Env &env,
Allocator &alloc,
Platform::Device::Mmio<0> &mmio,
Platform::Device::Irq &irq)
:
Signal_handler<Uplink_client> { env.ep(), *this, &Uplink_client::_handle_irq },
Lan9118_base { mmio, irq, *this, env },

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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 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:
@ -112,7 +112,7 @@ class I2c::I2c : Platform::Device::Mmio
public:
I2c(Genode::Env & env, Platform::Device & dev)
: Platform::Device::Mmio(dev, {0}),
: Platform::Device::Mmio<SIZE>(dev, {0}),
_irq_handler(env, dev)
{
write<Control>(0);

View File

@ -34,7 +34,7 @@ using Genode::addr_t;
** USB Command Block/Status Wrapper implementation **
*****************************************************/
struct Usb::Cbw : Genode::Mmio
struct Usb::Cbw : Genode::Mmio<0xf>
{
enum { LENGTH = 31 };
@ -46,8 +46,8 @@ struct Usb::Cbw : Genode::Mmio
struct Lun : Register<0xd, 8> { }; /* logical unit number */
struct Cbl : Register<0xe, 8> { }; /* command buffer length */
Cbw(addr_t addr, uint32_t t, uint32_t d,
uint8_t f, uint8_t l, uint8_t len) : Mmio(addr)
Cbw(Byte_range_ptr const &range, uint32_t t, uint32_t d,
uint8_t f, uint8_t l, uint8_t len) : Mmio(range)
{
write<Sig>(SIG);
write<Tag>(t);
@ -72,11 +72,11 @@ struct Usb::Cbw : Genode::Mmio
struct Test_unit_ready : Usb::Cbw,
Scsi::Test_unit_ready
{
Test_unit_ready(addr_t addr, uint32_t tag, uint8_t lun)
Test_unit_ready(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun)
:
Cbw(addr, tag, 0, Usb::ENDPOINT_IN, lun,
Cbw(range, tag, 0, Usb::ENDPOINT_IN, lun,
Scsi::Test_unit_ready::LENGTH),
Scsi::Test_unit_ready(addr+15)
Scsi::Test_unit_ready(Cbw::range_at(15))
{ if (verbose_scsi) dump(); }
void dump()
@ -90,11 +90,11 @@ struct Test_unit_ready : Usb::Cbw,
struct Request_sense : Usb::Cbw, Scsi::Request_sense
{
Request_sense(addr_t addr, uint32_t tag, uint8_t lun)
Request_sense(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun)
:
Cbw(addr, tag, Scsi::Request_sense_response::LENGTH,
Cbw(range, tag, Scsi::Request_sense_response::LENGTH,
Usb::ENDPOINT_IN, lun, Scsi::Request_sense::LENGTH),
Scsi::Request_sense(addr+15)
Scsi::Request_sense(Cbw::range_at(15))
{ if (verbose_scsi) dump(); }
void dump()
@ -108,10 +108,10 @@ struct Request_sense : Usb::Cbw, Scsi::Request_sense
struct Start_stop : Usb::Cbw, Scsi::Start_stop
{
Start_stop(addr_t addr, uint32_t tag, uint8_t lun)
Start_stop(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun)
:
Cbw(addr, tag, 0, Usb::ENDPOINT_IN, lun, Scsi::Start_stop::LENGTH),
Scsi::Start_stop(addr+15)
Cbw(range, tag, 0, Usb::ENDPOINT_IN, lun, Scsi::Start_stop::LENGTH),
Scsi::Start_stop(Cbw::range_at(15))
{ if (verbose_scsi) dump(); }
void dump()
@ -125,11 +125,11 @@ struct Start_stop : Usb::Cbw, Scsi::Start_stop
struct Inquiry : Usb::Cbw, Scsi::Inquiry
{
Inquiry(addr_t addr, uint32_t tag, uint8_t lun)
Inquiry(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun)
:
Cbw(addr, tag, Scsi::Inquiry_response::LENGTH,
Cbw(range, tag, Scsi::Inquiry_response::LENGTH,
Usb::ENDPOINT_IN, lun, Scsi::Inquiry::LENGTH),
Scsi::Inquiry(addr+15)
Scsi::Inquiry(Cbw::range_at(15))
{ if (verbose_scsi) dump(); }
void dump()
@ -143,11 +143,11 @@ struct Inquiry : Usb::Cbw, Scsi::Inquiry
struct Read_capacity_10 : Usb::Cbw, Scsi::Read_capacity_10
{
Read_capacity_10(addr_t addr, uint32_t tag, uint8_t lun)
Read_capacity_10(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun)
:
Cbw(addr, tag, Scsi::Capacity_response_10::LENGTH,
Cbw(range, tag, Scsi::Capacity_response_10::LENGTH,
Usb::ENDPOINT_IN, lun, Scsi::Read_capacity_10::LENGTH),
Scsi::Read_capacity_10(addr+15)
Scsi::Read_capacity_10(Cbw::range_at(15))
{ if (verbose_scsi) dump(); }
void dump()
@ -161,12 +161,12 @@ struct Read_capacity_10 : Usb::Cbw, Scsi::Read_capacity_10
struct Read_10 : Usb::Cbw, Scsi::Read_10
{
Read_10(addr_t addr, uint32_t tag, uint8_t lun,
Read_10(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun,
uint32_t lba, uint16_t len, uint32_t block_size)
:
Cbw(addr, tag, len * block_size,
Cbw(range, tag, len * block_size,
Usb::ENDPOINT_IN, lun, Scsi::Read_10::LENGTH),
Scsi::Read_10(addr+15, lba, len)
Scsi::Read_10(Cbw::range_at(15), lba, len)
{ if (verbose_scsi) dump(); }
void dump()
@ -180,12 +180,12 @@ struct Read_10 : Usb::Cbw, Scsi::Read_10
struct Write_10 : Usb::Cbw, Scsi::Write_10
{
Write_10(addr_t addr, uint32_t tag, uint8_t lun,
Write_10(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun,
uint32_t lba, uint16_t len, uint32_t block_size)
:
Cbw(addr, tag, len * block_size,
Cbw(range, tag, len * block_size,
Usb::ENDPOINT_OUT, lun, Scsi::Write_10::LENGTH),
Scsi::Write_10(addr+15, lba, len)
Scsi::Write_10(Cbw::range_at(15), lba, len)
{ if (verbose_scsi) dump(); }
void dump()
@ -199,11 +199,11 @@ struct Write_10 : Usb::Cbw, Scsi::Write_10
struct Read_capacity_16 : Usb::Cbw, Scsi::Read_capacity_16
{
Read_capacity_16(addr_t addr, uint32_t tag, uint8_t lun)
Read_capacity_16(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun)
:
Cbw(addr, tag, Scsi::Capacity_response_16::LENGTH,
Cbw(range, tag, Scsi::Capacity_response_16::LENGTH,
Usb::ENDPOINT_IN, lun, Scsi::Read_capacity_16::LENGTH),
Scsi::Read_capacity_16(addr+15)
Scsi::Read_capacity_16(Cbw::range_at(15))
{ if (verbose_scsi) dump(); }
void dump()
@ -217,12 +217,12 @@ struct Read_capacity_16 : Usb::Cbw, Scsi::Read_capacity_16
struct Read_16 : Usb::Cbw, Scsi::Read_16
{
Read_16(addr_t addr, uint32_t tag, uint8_t lun,
Read_16(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun,
uint64_t lba, uint32_t len, uint32_t block_size)
:
Cbw(addr, tag, len * block_size,
Cbw(range, tag, len * block_size,
Usb::ENDPOINT_IN, lun, Scsi::Read_16::LENGTH),
Scsi::Read_16(addr+15, lba, len)
Scsi::Read_16(Cbw::range_at(15), (uint32_t)lba, (uint16_t)len)
{ if (verbose_scsi) dump(); }
void dump()
@ -236,12 +236,12 @@ struct Read_16 : Usb::Cbw, Scsi::Read_16
struct Write_16 : Usb::Cbw, Scsi::Write_16
{
Write_16(addr_t addr, uint32_t tag, uint8_t lun,
Write_16(Genode::Byte_range_ptr const &range, uint32_t tag, uint8_t lun,
uint64_t lba, uint32_t len, uint32_t block_size)
:
Cbw(addr, tag, len * block_size,
Cbw(range, tag, len * block_size,
Usb::ENDPOINT_OUT, lun, Scsi::Write_16::LENGTH),
Scsi::Write_16(addr+15, lba, len)
Scsi::Write_16(Cbw::range_at(15), (uint32_t)lba, (uint16_t)len)
{ if (verbose_scsi) dump(); }
void dump()
@ -253,7 +253,7 @@ struct Write_16 : Usb::Cbw, Scsi::Write_16
};
struct Usb::Csw : Genode::Mmio
struct Usb::Csw : Genode::Mmio<0xd>
{
enum { LENGTH = 13 };
@ -264,7 +264,7 @@ struct Usb::Csw : Genode::Mmio
enum { PASSED = 0, FAILED = 1, PHASE_ERROR = 2 };
struct Sts : Register<0xc, 8> { }; /* status */
Csw(addr_t addr) : Mmio(addr) { }
Csw(Genode::Byte_range_ptr const &range) : Mmio(range) { }
uint32_t sig() const { return read<Sig>(); }
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;
char * const data = reinterpret_cast<char*>(iface.content(p));
Byte_range_ptr data {(char *)iface.content(p), p.size()};
using namespace Scsi;
switch (actual_size) {
case Inquiry_response::LENGTH:
{
Inquiry_response r((addr_t)data);
Inquiry_response r(data);
if (verbose_scsi) r.dump();
if (!r.sbc()) {
@ -258,7 +258,7 @@ struct Usb::Block_driver : Usb::Completion
}
case Capacity_response_10::LENGTH:
{
Capacity_response_10 r((addr_t)data);
Capacity_response_10 r(data);
if (verbose_scsi) r.dump();
block_count = r.last_block() + 1;
@ -267,7 +267,7 @@ struct Usb::Block_driver : Usb::Completion
}
case Capacity_response_16::LENGTH:
{
Capacity_response_16 r((addr_t)data);
Capacity_response_16 r(data);
if (verbose_scsi) r.dump();
block_count = r.last_block() + 1;
@ -276,7 +276,7 @@ struct Usb::Block_driver : Usb::Completion
}
case Request_sense_response::LENGTH:
{
Request_sense_response r((addr_t)data);
Request_sense_response r(data);
if (verbose_scsi) r.dump();
uint8_t const asc = r.read<Request_sense_response::Asc>();
@ -322,7 +322,7 @@ struct Usb::Block_driver : Usb::Completion
}
case Csw::LENGTH:
{
Csw csw((addr_t)data);
Csw csw(data);
uint32_t const sig = csw.sig();
if (sig != Csw::SIG) {
@ -528,6 +528,7 @@ struct Usb::Block_driver : Usb::Completion
*/
char cbw_buffer[Cbw::LENGTH];
Byte_range_ptr cbw_buf_range {(char *)cbw_buffer, Cbw::LENGTH};
/*
* We should probably execute the SCSI REPORT_LUNS command first
@ -537,7 +538,7 @@ struct Usb::Block_driver : Usb::Completion
*/
/* Scsi::Opcode::INQUIRY */
Inquiry inq((addr_t)cbw_buffer, INQ_TAG, active_lun);
Inquiry inq(cbw_buf_range, INQ_TAG, active_lun);
cbw(cbw_buffer, init, true);
resp(Scsi::Inquiry_response::LENGTH, init, true);
@ -559,13 +560,13 @@ struct Usb::Block_driver : Usb::Completion
enum { MAX_RETRIES = 10 };
int retries;
for (retries = 0; retries < MAX_RETRIES; retries++) {
Test_unit_ready unit_ready((addr_t)cbw_buffer, RDY_TAG, active_lun);
Test_unit_ready unit_ready(cbw_buf_range, RDY_TAG, active_lun);
cbw(cbw_buffer, init, true);
csw(init, true);
if (!init.unit_ready) {
Request_sense sense((addr_t)cbw_buffer, REQ_TAG, active_lun);
Request_sense sense(cbw_buf_range, REQ_TAG, active_lun);
cbw(cbw_buffer, init, true);
resp(Scsi::Request_sense_response::LENGTH, init, true);
@ -582,7 +583,7 @@ struct Usb::Block_driver : Usb::Completion
} else if (init.start_stop) {
init.start_stop = false;
Start_stop start_stop((addr_t)cbw_buffer, SS_TAG, active_lun);
Start_stop start_stop(cbw_buf_range, SS_TAG, active_lun);
cbw(cbw_buffer, init, true);
csw(init, true);
@ -609,7 +610,7 @@ struct Usb::Block_driver : Usb::Completion
*/
/* Scsi::Opcode::READ_CAPACITY_10 */
Read_capacity_10 read_cap((addr_t)cbw_buffer, CAP_TAG, active_lun);
Read_capacity_10 read_cap(cbw_buf_range, CAP_TAG, active_lun);
cbw(cbw_buffer, init, true);
resp(Scsi::Capacity_response_10::LENGTH, init, true);
@ -626,7 +627,7 @@ struct Usb::Block_driver : Usb::Completion
*/
if (init.block_count > ~(uint32_t)0U) {
Read_capacity_16 read_cap((addr_t)cbw_buffer, CAP_TAG, active_lun);
Read_capacity_16 read_cap(cbw_buf_range, CAP_TAG, active_lun);
init.read_capacity = false;
@ -779,7 +780,7 @@ struct Usb::Block_driver : Usb::Completion
warning("This is not the actual size you are looking for");
do {
Csw csw((addr_t)iface.content(p));
Csw csw({(char *)iface.content(p), p.size()});
uint32_t const sig = csw.sig();
if (sig != Csw::SIG) {
@ -879,12 +880,13 @@ struct Usb::Block_driver : Usb::Completion
* before entering this function
*/
char cb[Cbw::LENGTH];
Byte_range_ptr cb_range {(char *)cb, Cbw::LENGTH};
if (read) {
if (force_cmd_16) Read_16 r((addr_t)cb, t, active_lun, lba, c, _block_size);
else Read_10 r((addr_t)cb, t, active_lun, (uint32_t)lba, c, _block_size);
if (force_cmd_16) Read_16 r(cb_range, t, active_lun, lba, c, _block_size);
else Read_10 r(cb_range, t, active_lun, (uint32_t)lba, c, _block_size);
} else {
if (force_cmd_16) Write_16 w((addr_t)cb, t, active_lun, lba, c, _block_size);
else Write_10 w((addr_t)cb, t, active_lun, (uint32_t)lba, c, _block_size);
if (force_cmd_16) Write_16 w(cb_range, t, active_lun, lba, c, _block_size);
else Write_10 w(cb_range, t, active_lun, (uint32_t)lba, c, _block_size);
}
cbw(cb, *this);

View File

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

View File

@ -92,7 +92,7 @@ struct Virtdev_rom::Main
Sliced_heap _heap { _env.ram(), _env.rm() };
Virtdev_rom::Root _root { _env, _heap, _ds };
struct Device : public Attached_mmio
struct Device : public Attached_mmio<0xc>
{
struct Magic : Register<0x000, 32> { };
struct Id : Register<0x008, 32> {
@ -108,8 +108,8 @@ struct Virtdev_rom::Main
};
};
Device(Env &env, addr_t base, size_t size)
: Attached_mmio(env, base, size, false) { }
Device(Env &env, Byte_range_ptr const &range)
: Attached_mmio(env, range, false) { }
};
static char const *_name_for_id(unsigned id)
@ -138,7 +138,7 @@ struct Virtdev_rom::Main
for (size_t idx = 0; idx < NUM_VIRTIO_TRANSPORTS; ++idx) {
addr_t addr = BASE_ADDRESS + idx * DEVICE_SIZE;
Device device { _env, BASE_ADDRESS + idx * DEVICE_SIZE, DEVICE_SIZE };
Device device { _env, {(char *)(BASE_ADDRESS + idx * DEVICE_SIZE), DEVICE_SIZE} };
if (device.read<Device::Magic>() != VIRTIO_MMIO_MAGIC) {
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;
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++)
if (root.partitions[i].valid())
any_partition_valid = true;
@ -107,7 +107,7 @@ class Block::Ahdi : public Partition_table
template <typename FUNC>
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++) {
Partition_record const &part = root.partitions[i];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -55,7 +55,7 @@ class Main
KERNEL_OFFSET, Machine_type(MACHINE_QSB),
Board_revision(BOARD_QSB),
_heap, _exception_handler };
M4if _m4if { _env, Imx53::M4IF_BASE, Imx53::M4IF_SIZE };
M4if _m4if { _env, {(char *)Imx53::M4IF_BASE, Imx53::M4IF_SIZE} };
Serial_driver _serial { _env.ram(), _env.rm() };
Block_driver _block { _env, _config.xml(), _heap, _vm };

View File

@ -26,7 +26,7 @@ class Mmio_big_endian_access
private:
addr_t const _base;
Byte_range_ptr const _range;
/**
* Write '_ACCESS_T' typed 'value' to MMIO base + 'offset'
@ -34,8 +34,7 @@ class Mmio_big_endian_access
template <typename ACCESS_T>
inline void _write(off_t const offset, ACCESS_T const value)
{
addr_t const dst = _base + offset;
*(ACCESS_T volatile *)dst = host_to_big_endian(value);
*(ACCESS_T volatile *)(_range.start + offset) = host_to_big_endian(value);
}
/**
@ -44,30 +43,38 @@ class Mmio_big_endian_access
template <typename ACCESS_T>
inline ACCESS_T _read(off_t const &offset) const
{
addr_t const dst = _base + offset;
ACCESS_T const value = *(ACCESS_T volatile *)dst;
return host_to_big_endian(value);
return host_to_big_endian(*(ACCESS_T volatile *)(_range.start + offset));
}
public:
Mmio_big_endian_access(addr_t const base) : _base(base) { }
Mmio_big_endian_access(Byte_range_ptr const &range) : _range(range.start, range.num_bytes) { }
addr_t base() const { return _base; }
Byte_range_ptr range_at(off_t offset) const
{
return {_range.start + offset, _range.num_bytes - offset};
}
Byte_range_ptr range() const { return range_at(0); }
addr_t base() const { return (addr_t)range().start; }
};
template <size_t MMIO_SIZE>
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),
Register_set(*static_cast<Mmio_big_endian_access *>(this)) { }
Mmio_big_endian_access(range),
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 Totalsize : Register<0x4, 32> {};
@ -81,19 +88,15 @@ struct Fdt_header : Mmio
struct Size_dt_struct : Register<0x24, 32> {};
using Mmio::Mmio;
enum { SIZE = 10*4 };
};
struct Fdt_reserve_entry : Mmio
struct Fdt_reserve_entry : Mmio<2*8>
{
struct Address : Register<0, 64> {};
struct Size : Register<8, 64> {};
using Mmio::Mmio;
enum { SIZE = 2*8 };
};
@ -106,35 +109,37 @@ enum Fdt_tokens {
};
struct Fdt_token : Mmio
template <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 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::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)
{
Fdt_token start(_buffer.addr+off, FDT_BEGIN_NODE);
Fdt_token start({(char *)_buffer.addr+off, _buffer.size-off}, FDT_BEGIN_NODE);
off += Fdt_token::SIZE;
_buffer.write(off, name.string(), name.length());
off += (uint32_t)name.length();
off = align_addr(off, 2);
fn();
Fdt_token end(_buffer.addr+off, FDT_END_NODE);
Fdt_token end({(char *)_buffer.addr+off, _buffer.size-off}, FDT_END_NODE);
off += Fdt_token::SIZE;
};
auto property = [&] (auto const & name, auto const & val)
{
_dict.add(name);
Fdt_prop prop(_buffer.addr+off, (uint32_t)val.length(),
Fdt_prop prop({(char *)_buffer.addr+off, _buffer.size-off}, (uint32_t)val.length(),
_dict.offset(name));
off += Fdt_prop::SIZE;
val.write(off, _buffer);
@ -366,7 +371,7 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config,
});
});
Fdt_token end(_buffer.addr+off, FDT_END);
Fdt_token end({(char *)_buffer.addr+off, _buffer.size-off}, FDT_END);
off += Fdt_token::SIZE;
}
@ -374,7 +379,7 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config,
void Vmm::Fdt_generator::generate(Config const & config,
void * initrd_start, size_t initrd_size)
{
Fdt_header header(_buffer.addr);
Fdt_header header({(char *)_buffer.addr, _buffer.size});
header.write<Fdt_header::Magic>(FDT_MAGIC);
header.write<Fdt_header::Version>(FDT_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;
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::Size>(0);
@ -391,7 +396,7 @@ void Vmm::Fdt_generator::generate(Config const & config,
_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::Size_dt_strings>(_dict.length());

View File

@ -21,29 +21,34 @@ class Ram {
private:
Genode::addr_t const _base;
Genode::size_t const _size;
Genode::addr_t const _local;
using Byte_range_ptr = Genode::Byte_range_ptr;
using addr_t = Genode::addr_t;
using size_t = Genode::size_t;
addr_t const _guest_base;
Byte_range_ptr const _local_range;
public:
Ram(Genode::addr_t const addr,
Genode::size_t const sz,
Genode::addr_t const local)
: _base(addr), _size(sz), _local(local) { }
Ram(addr_t guest_base, Byte_range_ptr const &local_range)
: _guest_base(guest_base), _local_range(local_range.start, local_range.num_bytes) { }
Genode::addr_t base() const { return _base; }
Genode::size_t size() const { return _size; }
Genode::addr_t local() const { return _local; }
size_t size() const { return _local_range.num_bytes; }
addr_t guest_base() const { return _guest_base; }
addr_t local_base() const { return (addr_t)_local_range.start; }
Genode::addr_t local_address(Genode::addr_t guest, Genode::size_t size)
Byte_range_ptr to_local_range(Byte_range_ptr const &guest_range)
{
if (guest < _base || guest >= _base + _size ||
size == 0 || guest + size >= _base + _size)
addr_t guest_base = (addr_t)guest_range.start;
if (guest_base < _guest_base ||
guest_base >= _guest_base + _local_range.num_bytes ||
guest_range.num_bytes == 0 ||
guest_base + guest_range.num_bytes >= _guest_base + _local_range.num_bytes)
throw Vmm::Exception("Invalid guest physical address: ",
Genode::Hex(guest), " size: ", Genode::Hex(size));
Genode::Hex(guest_base), " size: ", Genode::Hex(guest_range.num_bytes));
return _local + (guest - _base);
Genode::off_t offset = guest_base - _guest_base;
return {_local_range.start + offset, guest_range.num_bytes};
}
};

View File

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

View File

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

View File

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

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()
{
Framebuffer::Mode mode = _device.resize();
Display_info_response dir { _desc_addr(1) };
Display_info_response dir { _desc_range(1) };
memset((void*)dir.base(), 0, Display_info_response::SIZE);
dir.write<Control_header::Type>(Control_header::Type::OK_DISPLAY_INFO);
@ -59,8 +59,8 @@ void Vmm::Virtio_gpu_control_request::_get_display_info()
void Vmm::Virtio_gpu_control_request::_resource_create_2d()
{
Resource_create_2d c2d { _desc_addr(0) };
Control_header response { _desc_addr(1) };
Resource_create_2d c2d { _desc_range(0) };
Control_header response { _desc_range(1) };
if (c2d.read<Resource_create_2d::Format>() !=
Resource_create_2d::Format::B8G8R8X8) {
@ -90,8 +90,8 @@ void Vmm::Virtio_gpu_control_request::_resource_delete()
using Resource = Virtio_gpu_device::Resource;
using Scanout = Resource::Scanout;
Resource_unref rur { _desc_addr(0) };
Control_header response { _desc_addr(1) };
Resource_unref rur { _desc_range(0) };
Control_header response { _desc_range(1) };
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_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 Entry = Resource_attach_backing::Memory_entry;
Resource_attach_backing rab { _desc_addr(0) };
addr_t entry_base { _desc_addr(1) };
Control_header response { _desc_addr(2) };
Resource_attach_backing rab { _desc_range(0) };
Byte_range_ptr entry_range { _desc_range(1) };
Control_header response { _desc_range(2) };
response.write<Control_header::Type>(Control_header::Type::ERR_INVALID_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 {
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>();
addr_t off = _device._ram.local_address((addr_t)entry.read<Entry::Address>(), sz)
- _device._ram.local();
addr_t off = (addr_t)_device._ram.to_local_range({(char *)entry.read<Entry::Address>(), sz}).start
- _device._ram.local_base();
res.attach(off, sz);
}
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()
{
Set_scanout scr { _desc_addr(0) };
Control_header response { _desc_addr(1) };
Set_scanout scr { _desc_range(0) };
Control_header response { _desc_range(1) };
uint32_t id = scr.read<Set_scanout::Resource_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()
{
Resource_flush rf { _desc_addr(0) };
Control_header response { _desc_addr(1) };
Resource_flush rf { _desc_range(0) };
Control_header response { _desc_range(1) };
uint32_t id = rf.read<Resource_flush::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()
{
Transfer_to_host_2d tth { _desc_addr(0) };
Control_header response { _desc_addr(1) };
Transfer_to_host_2d tth { _desc_range(0) };
Control_header response { _desc_range(1) };
uint32_t id = tth.read<Transfer_to_host_2d::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_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 {
/* 2D commands */
@ -95,17 +96,17 @@ class Vmm::Virtio_gpu_control_request
ERR_INVALID_PARAMETER,
};
};
struct Flags : Register<0x4, 32> {};
struct Fence_id : Register<0x8, 64> {};
struct Ctx_id : Register<0x10, 32> {};
struct Flags : Base::template Register<0x4, 32> {};
struct Fence_id : Base::template Register<0x8, 64> {};
struct Ctx_id : Base::template Register<0x10, 32> {};
using Mmio::Mmio;
using Base::Mmio;
};
struct Display_info_response : Control_header
{
enum { SIZE = Control_header::SIZE + 24*16 };
using Control_header = Control_header_tpl<24>;
struct Display_info_response : Control_header_tpl<Control_header::SIZE + 24*16>
{
struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {};
@ -113,13 +114,11 @@ class Vmm::Virtio_gpu_control_request
struct Enabled : Register<0x28, 32> {};
struct Flags : Register<0x2c, 32> {};
using Control_header::Control_header;
using Control_header_tpl::Control_header_tpl;
};
struct Resource_create_2d : Control_header
struct Resource_create_2d : Control_header_tpl<Control_header::SIZE + 16>
{
enum { SIZE = Control_header::SIZE + 16 };
struct Resource_id : Register<0x18, 32> {};
struct Format : Register<0x1c, 32>
@ -139,42 +138,34 @@ class Vmm::Virtio_gpu_control_request
struct Width : Register<0x20, 32> {};
struct Height : Register<0x24, 32> {};
using Control_header::Control_header;
using Control_header_tpl::Control_header_tpl;
};
struct Resource_unref : Control_header
struct Resource_unref : Control_header_tpl<Control_header::SIZE + 8>
{
enum { SIZE = Control_header::SIZE + 8 };
struct Resource_id : Register<0x18, 32> {};
using Control_header::Control_header;
using Control_header_tpl::Control_header_tpl;
};
struct Resource_attach_backing : Control_header
struct Resource_attach_backing : Control_header_tpl<Control_header::SIZE + 8>
{
enum { SIZE = Control_header::SIZE + 8 };
struct Resource_id : Register<0x18, 32> {};
struct Nr_entries : Register<0x1c, 32> {};
struct Memory_entry : Mmio
struct Memory_entry : Mmio<16>
{
enum { SIZE = 16 };
struct Address : Register<0x0, 64> {};
struct Length : Register<0x8, 32> {};
using Mmio::Mmio;
};
using Control_header::Control_header;
using Control_header_tpl::Control_header_tpl;
};
struct Set_scanout : Control_header
struct Set_scanout : Control_header_tpl<Control_header::SIZE + 24>
{
enum { SIZE = Control_header::SIZE + 24 };
struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {};
@ -182,26 +173,22 @@ class Vmm::Virtio_gpu_control_request
struct Scanout_id : Register<0x28, 32> {};
struct Resource_id : Register<0x2c, 32> {};
using Control_header::Control_header;
using Control_header_tpl::Control_header_tpl;
};
struct Resource_flush : Control_header
struct Resource_flush : Control_header_tpl<Control_header::SIZE + 24>
{
enum { SIZE = Control_header::SIZE + 24 };
struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {};
struct Height : Register<0x24, 32> {};
struct Resource_id : Register<0x28, 32> {};
using Control_header::Control_header;
using Control_header_tpl::Control_header_tpl;
};
struct Transfer_to_host_2d :Control_header
struct Transfer_to_host_2d :Control_header_tpl<Control_header::SIZE + 32>
{
enum { SIZE = Control_header::SIZE + 32 };
struct X : Register<0x18, 32> {};
struct Y : Register<0x1c, 32> {};
struct Width : Register<0x20, 32> {};
@ -209,7 +196,7 @@ class Vmm::Virtio_gpu_control_request
struct Offset : Register<0x28, 64> {};
struct Resource_id : Register<0x30, 32> {};
using Control_header::Control_header;
using Control_header_tpl::Control_header_tpl;
};
Descriptor_array & _array;
@ -232,14 +219,14 @@ class Vmm::Virtio_gpu_control_request
return _array.get(idx);
}
addr_t _desc_addr(unsigned i)
Byte_range_ptr _desc_range(unsigned i)
{
Descriptor d = _desc(i);
/* we only support 32-bit ram addresses by now */
return _ram.local_address((addr_t)d.address(), d.length());
return _ram.to_local_range({(char *)d.address(), d.length()});
}
Control_header _ctrl_hdr { _desc_addr(0) };
Control_header _ctrl_hdr { _desc_range(0) };
void _get_display_info();
void _resource_create_2d();

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

View File

@ -51,21 +51,21 @@ class Vmm::Virtio_net : public Virtio_device<Virtio_split_queue, 2>
void _rx()
{
/* RX */
auto recv = [&] (addr_t data, size_t size)
auto recv = [&] (Byte_range_ptr const &data)
{
if (!_nic.rx()->packet_avail() || !_nic.rx()->ready_to_ack())
return 0ul;
Nic::Packet_descriptor const rx_packet = _nic.rx()->get_packet();
size_t sz = Genode::min(size, rx_packet.size() + NIC_HEADER_SIZE);
size_t sz = Genode::min(data.num_bytes, rx_packet.size() + NIC_HEADER_SIZE);
Genode::memcpy((void *)(data + NIC_HEADER_SIZE),
Genode::memcpy((void *)(data.start + NIC_HEADER_SIZE),
_nic.rx()->packet_content(rx_packet),
sz - NIC_HEADER_SIZE);
_nic.rx()->acknowledge_packet(rx_packet);
Genode::memset((void*)data, 0, NIC_HEADER_SIZE);
Genode::memset((void*)data.start, 0, NIC_HEADER_SIZE);
return sz;
};
@ -79,22 +79,22 @@ class Vmm::Virtio_net : public Virtio_device<Virtio_split_queue, 2>
void _tx()
{
auto send = [&] (addr_t data, size_t size)
auto send = [&] (Byte_range_ptr const &data)
{
if (!_nic.tx()->ready_to_submit()) return 0lu;
data += NIC_HEADER_SIZE; size -= NIC_HEADER_SIZE;
Byte_range_ptr body {data.start + NIC_HEADER_SIZE, data.num_bytes - NIC_HEADER_SIZE};
Nic::Packet_descriptor tx_packet;
try {
tx_packet = _nic.tx()->alloc_packet(size); }
tx_packet = _nic.tx()->alloc_packet(body.num_bytes); }
catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
return 0ul; }
Genode::memcpy(_nic.tx()->packet_content(tx_packet),
(void *)data, size);
(void *)body.start, body.num_bytes);
_nic.tx()->submit_packet(tx_packet);
return size;
return body.num_bytes;
};
if (!_queue[TX].constructed()) return;

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