diff --git a/repos/os/src/server/vmm/address_space.cc b/repos/os/src/server/vmm/address_space.cc index 2c866b03df..4034759ba3 100644 --- a/repos/os/src/server/vmm/address_space.cc +++ b/repos/os/src/server/vmm/address_space.cc @@ -17,7 +17,7 @@ using Vmm::Address_range; Address_range::Address_range(Genode::uint64_t start, Genode::uint64_t size) -: start(start), size(size) { } +: _start(start), _size(size) { } Address_range & Address_range::find(Address_range & bus_addr) @@ -26,7 +26,7 @@ Address_range & Address_range::find(Address_range & bus_addr) return *this; Address_range * ar = - Avl_node::child(bus_addr.start > start); + Avl_node::child(bus_addr._start > _start); if (!ar) throw Not_found(bus_addr); return ar->find(bus_addr); } diff --git a/repos/os/src/server/vmm/address_space.h b/repos/os/src/server/vmm/address_space.h index 4be408d893..5a9c33c7a6 100644 --- a/repos/os/src/server/vmm/address_space.h +++ b/repos/os/src/server/vmm/address_space.h @@ -18,44 +18,57 @@ #include namespace Vmm { + using namespace Genode; + struct Address_range; - class Address_space; + class Address_space; } -struct Vmm::Address_range : Genode::Avl_node +class Vmm::Address_range : private Genode::Avl_node { - Genode::uint64_t const start; - Genode::uint64_t const size; + private: - Address_range(Genode::uint64_t start, - Genode::uint64_t size); + uint64_t const _start; + uint64_t const _size; - Genode::uint64_t end() const { return start + size; } + friend class Avl_node; + friend class Avl_tree; + friend class Address_space; - bool match(Address_range & other) const { - return other.start >= start && other.end() <= end(); } + public: - Address_range & find(Address_range & bus_addr); + Address_range(uint64_t start, + uint64_t size); + virtual ~Address_range() {} - struct Not_found : Exception - { - Not_found(Address_range & access) - : Exception("Could not find ", access) {} - }; + uint64_t start() const { return _start; } + uint64_t size() const { return _size; } + uint64_t end() const { return _start + _size; } - void print(Genode::Output & out) const - { - Genode::print(out, "address=", Genode::Hex(start), - " width=", Genode::Hex(size)); - } + bool match(Address_range & other) const { + return other._start >= _start && other.end() <= end(); } - /************************ - ** Avl_node interface ** - ************************/ + Address_range & find(Address_range & bus_addr); - bool higher(Address_range * range) { - return range->start > start; } + struct Not_found : Exception + { + Not_found(Address_range & access) + : Exception("Could not find ", access) {} + }; + + void print(Genode::Output & out) const + { + Genode::print(out, "address=", Hex(_start), + " width=", Hex(_size)); + } + + /************************ + ** Avl_node interface ** + ************************/ + + bool higher(Address_range * range) { + return range->_start > _start; } }; @@ -63,7 +76,7 @@ class Vmm::Address_space { private: - Genode::Avl_tree _tree; + Avl_tree _tree {}; public: diff --git a/repos/os/src/server/vmm/config.h b/repos/os/src/server/vmm/config.h index 5cea0b9b90..ac1ef8c670 100644 --- a/repos/os/src/server/vmm/config.h +++ b/repos/os/src/server/vmm/config.h @@ -36,22 +36,32 @@ class Vmm::Config using Name = String<128>; using Arguments = String<512>; - struct Virtio_device : List_model::Element + class Virtio_device : public List_model::Element { - enum Type { INVALID, CONSOLE, NET, BLOCK, GPU, INPUT }; + private: - enum { MMIO_SIZE = 0x200 }; + Config & _config; - Config & _config; + /** + * Noncopyable + */ + Virtio_device(Virtio_device const &); + Virtio_device &operator = (Virtio_device const &); - Virtio_device(Name & name, Type type, Config & config); - ~Virtio_device(); + public: - Name const name; - Type const type; - void * const mmio_start; - size_t const mmio_size; - unsigned const irq; + enum Type { INVALID, CONSOLE, NET, BLOCK, GPU, INPUT }; + + enum { MMIO_SIZE = 0x200 }; + + Virtio_device(Name & name, Type type, Config & config); + ~Virtio_device(); + + Name const name; + Type const type; + void * const mmio_start; + size_t const mmio_size; + unsigned const irq; }; private: @@ -60,8 +70,13 @@ class Vmm::Config { Bit_allocator _alloc {}; - unsigned alloc() { - return VIRTIO_IRQ_START + _alloc.alloc(); } + unsigned alloc() + { + /* we assume that the max number of IRQs does fit unsigned */ + static_assert(VIRTIO_IRQ_COUNT < ~0U); + return VIRTIO_IRQ_START + (unsigned)_alloc.alloc(); + } + void free(unsigned irq) { _alloc.free(VIRTIO_IRQ_START+irq); } }; @@ -77,7 +92,7 @@ class Vmm::Config unsigned _gic_version { 0 }; Arguments _bootargs { }; - List_model _model; + List_model _model {}; struct Virtio_device_update_policy : List_model::Update_policy diff --git a/repos/os/src/server/vmm/cpu_base.cc b/repos/os/src/server/vmm/cpu_base.cc index 8b51d608b7..c1dd528d51 100644 --- a/repos/os/src/server/vmm/cpu_base.cc +++ b/repos/os/src/server/vmm/cpu_base.cc @@ -190,7 +190,7 @@ Cpu_base::Cpu_base(Vm & vm, Genode::Env & env, Genode::Heap & heap, Genode::Entrypoint & ep, - short const id) + unsigned id) : _vcpu_id(id), _vm(vm), _vm_session(vm_session), diff --git a/repos/os/src/server/vmm/cpu_base.h b/repos/os/src/server/vmm/cpu_base.h index 6cadc181c7..49656f80a9 100644 --- a/repos/os/src/server/vmm/cpu_base.h +++ b/repos/os/src/server/vmm/cpu_base.h @@ -35,11 +35,11 @@ class Vmm::Cpu_base struct State : Genode::Vm_state { - Genode::uint64_t reg(unsigned idx) const; - void reg(unsigned idx, Genode::uint64_t v); + addr_t reg(addr_t idx) const; + void reg(addr_t idx, addr_t v); }; - struct Esr : Genode::Register<32> + struct Esr : Genode::Register { struct Ec : Bitfield<26, 6> { @@ -62,7 +62,7 @@ class Vmm::Cpu_base Genode::Env & env, Genode::Heap & heap, Genode::Entrypoint & ep, - short const cpu_id); + unsigned cpu_id); unsigned cpu_id() const; void run(); @@ -118,14 +118,23 @@ class Vmm::Cpu_base protected: - class System_register : public Genode::Avl_node + class System_register : protected Genode::Avl_node { private: - const Esr::access_t _encoding; - const char *_name; - const bool _writeable; - Genode::uint64_t _value; + const Esr::access_t _encoding; + const char * _name; + const bool _writeable; + uint64_t _value; + + friend class Avl_node; + friend class Avl_tree; + + /* + * Noncopyable + */ + System_register(System_register const &); + System_register &operator = (System_register const &); public: @@ -169,8 +178,10 @@ class Vmm::Cpu_base : System_register(0, crn, op1, crm, op2, name, writeable, v, tree) {} - const char * name() const { return _name; } - const bool writeable() const { return _writeable; } + virtual ~System_register() {} + + const char * name() const { return _name; } + bool writeable() const { return _writeable; } System_register * find_by_encoding(Iss::access_t e) { @@ -196,7 +207,7 @@ class Vmm::Cpu_base return (r->_encoding > _encoding); } }; - short _vcpu_id; + unsigned _vcpu_id; bool _active { true }; Vm & _vm; Genode::Vm_connection & _vm_session; @@ -205,7 +216,7 @@ class Vmm::Cpu_base Genode::Vm_connection::Exit_config _exit_config { }; Genode::Vm_connection::Vcpu _vm_vcpu; State & _state; - Genode::Avl_tree _reg_tree; + Genode::Avl_tree _reg_tree {}; /*********************** diff --git a/repos/os/src/server/vmm/fdt.cc b/repos/os/src/server/vmm/fdt.cc index eb2f916e2e..b95009386f 100644 --- a/repos/os/src/server/vmm/fdt.cc +++ b/repos/os/src/server/vmm/fdt.cc @@ -275,12 +275,12 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config, node(Name("timer"), [&] () { property(Name("compatible"), - ::Array("arm,armv8-timer", "arm,armv7-timer")); + ::Array("arm,armv8-timer", "arm,armv7-timer")); property(Name("interrupts"), - ::Array(GIC_PPI, 0xd, IRQ_TYPE_LEVEL_HIGH, - GIC_PPI, 0xe, IRQ_TYPE_LEVEL_HIGH, - GIC_PPI, 0xb, IRQ_TYPE_LEVEL_HIGH, - GIC_PPI, 0xa, IRQ_TYPE_LEVEL_HIGH)); + ::Array(GIC_PPI, 0xd, IRQ_TYPE_LEVEL_HIGH, + GIC_PPI, 0xe, IRQ_TYPE_LEVEL_HIGH, + GIC_PPI, 0xb, IRQ_TYPE_LEVEL_HIGH, + GIC_PPI, 0xa, IRQ_TYPE_LEVEL_HIGH)); }); node(Name("gic"), [&] () @@ -289,16 +289,16 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config, property(Name("phandle"), Value(GIC)); property(Name("compatible"), (gicv2) ? Name("arm,gic-400") : Name("arm,gic-v3")); - property(Name("ranges"), ::Array()); - property(Name("interrupt-controller"), ::Array()); + property(Name("ranges"), ::Array()); + property(Name("interrupt-controller"), ::Array()); property(Name("#address-cells"), Value(2)); property(Name("#redistributor-regions"), Value(1)); property(Name("#interrupt-cells"), Value(3)); property(Name("#size-cells"), Value(2)); property(Name("reg"), - ::Array(0, GICD_MMIO_START, 0, GICD_MMIO_SIZE, - 0, (gicv2) ? GICC_MMIO_START : GICR_MMIO_START, - 0, (gicv2) ? GICC_MMIO_SIZE : GICR_MMIO_SIZE)); + ::Array(0, GICD_MMIO_START, 0, GICD_MMIO_SIZE, + 0, (gicv2) ? GICC_MMIO_START : GICR_MMIO_START, + 0, (gicv2) ? GICC_MMIO_SIZE : GICR_MMIO_SIZE)); }); node(Name("clocks"), [&] () @@ -320,19 +320,20 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config, node(Name("pl011"), [&] () { property(Name("compatible"), - ::Array("arm,pl011", "arm,primecell")); + ::Array("arm,pl011", "arm,primecell")); property(Name("interrupts"), ::Array(GIC_SPI, PL011_IRQ-32, IRQ_TYPE_LEVEL_HIGH)); - property(Name("reg"), ::Array(0, PL011_MMIO_START, - 0, PL011_MMIO_SIZE)); + property(Name("reg"), ::Array(0, PL011_MMIO_START, + 0, PL011_MMIO_SIZE)); property(Name("clock-names"), - ::Array("uartclk", "apb_pclk")); - property(Name("clocks"), ::Array(CLK, CLK)); + ::Array("uartclk", "apb_pclk")); + property(Name("clocks"), ::Array(CLK, CLK)); }); node(Name("memory"), [&] () { - property(Name("reg"), ::Array(0, RAM_START, 0, config.ram_size())); + property(Name("reg"), ::Array(0, RAM_START, 0, + (uint32_t)config.ram_size())); property(Name("device_type"), Name("memory")); }); @@ -347,19 +348,20 @@ void Vmm::Fdt_generator::_generate_tree(uint32_t & off, Config const & config, /* we're sure that the initrd start address is wide below 4GB */ uint32_t start = (uint32_t)((addr_t)initrd_start & 0xffffffff); property(Name("linux,initrd-start"), Value(start)); - property(Name("linux,initrd-end"), Value(start+initrd_size)); + property(Name("linux,initrd-end"), Value(start+(uint32_t)initrd_size)); }); config.for_each_virtio_device([&] (Config::Virtio_device const & dev) { node(Name("virtio@", dev.mmio_start), [&] () { property(Name("interrupts"), - ::Array(GIC_SPI, dev.irq-32, IRQ_TYPE_EDGE_RISING)); + ::Array(GIC_SPI, dev.irq-32U, + IRQ_TYPE_EDGE_RISING)); property(Name("compatible"), Name("virtio,mmio")); - property(Name("dma-coherent"), ::Array()); + property(Name("dma-coherent"), ::Array()); property(Name("reg"), - ::Array(0, (uint32_t)((addr_t)dev.mmio_start & 0xffffffff), - 0, (uint32_t)dev.mmio_size)); + ::Array(0U, (uint32_t)((addr_t)dev.mmio_start & 0xffffffff), + 0U, (uint32_t)dev.mmio_size)); }); }); }); diff --git a/repos/os/src/server/vmm/gic.cc b/repos/os/src/server/vmm/gic.cc index e3a9a465b0..7517ff1a3f 100644 --- a/repos/os/src/server/vmm/gic.cc +++ b/repos/os/src/server/vmm/gic.cc @@ -205,10 +205,9 @@ Gic::Gicd_banked::Gicd_banked(Cpu_base & cpu, Gic & gic, Mmio_bus & bus) if (gic.version() >= 3) { _rdist.construct(GICR_MMIO_START + - (cpu.cpu_id()*0x20000), 0x20000, + (cpu.cpu_id()*0x20000), 0x20000, bus, cpu.cpu_id(), (_gic._cpu_cnt-1) == cpu.cpu_id()); - bus.add(*_rdist); } } @@ -219,10 +218,9 @@ Register Gic::Irq_reg::read(Address_range & access, Cpu & cpu) Register ret = 0; - Register bits_per_irq = size * 8 / irq_count; - for (unsigned i = (access.start * 8) / bits_per_irq; - i < ((access.start+access.size) * 8) / bits_per_irq; i++) - ret |= read(cpu.gic().irq(i)) << ((i % (32/bits_per_irq) * bits_per_irq)); + for_range(access, [&] (unsigned i, Register bits_per_irq) { + ret |= read(cpu.gic().irq((unsigned)i)) + << ((i % (32/bits_per_irq) * bits_per_irq)); }); return ret; } @@ -231,12 +229,10 @@ void Gic::Irq_reg::write(Address_range & access, Cpu & cpu, Register value) { Genode::Mutex::Guard guard(big_gic_lock()); - Register bits_per_irq = size * 8 / irq_count; - Register irq_value_mask = (1<> ((i % (32/bits_per_irq))*bits_per_irq)) - & irq_value_mask); + for_range(access, [&] (unsigned i, Register bits_per_irq) { + write(cpu.gic().irq((unsigned)i), + (value >> ((i % (32/bits_per_irq))*bits_per_irq)) + & ((1<= 0x20) { Irq_reg::write(access, cpu, value); } + if (access.start() >= 0x20) { Irq_reg::write(access, cpu, value); } } @@ -294,33 +292,15 @@ Gic::Gic(const char * const name, unsigned cpus, unsigned version, Genode::Vm_connection & vm, - Mmio_bus & bus, - Genode::Env & env) -: Mmio_device(name, addr, size), _cpu_cnt(cpus), _version(version) + Space & bus, + Genode::Env &) +: + Mmio_device(name, addr, size, bus), + _cpu_cnt(cpus), + _version(version) { - add(_ctrl); - add(_typer); - add(_iidr); - add(_igroupr); - add(_isenabler); - add(_csenabler); - add(_ispendr); - add(_icpendr); - add(_isactiver); - add(_icactiver); - add(_ipriorityr); - add(_itargetr); - add(_icfgr); - add(_irouter); - add(_sgir); - - for (unsigned i = 0; i < (sizeof(Dummy::regs) / sizeof(Mmio_register)); i++) - add(_reg_container.regs[i]); - for (unsigned i = 0; i < MAX_SPI; i++) _spi[i].construct(i+MAX_SGI+MAX_PPI, Irq::SPI, _pending_list); - bus.add(*this); - if (version < 3) vm.attach_pic(GICC_MMIO_START); } diff --git a/repos/os/src/server/vmm/gic.h b/repos/os/src/server/vmm/gic.h index 44f06ba17c..a514aea9f5 100644 --- a/repos/os/src/server/vmm/gic.h +++ b/repos/os/src/server/vmm/gic.h @@ -50,10 +50,12 @@ class Vmm::Gic : public Vmm::Mmio_device Irq * highest_enabled(unsigned cpu_id = ~0U); }; - struct Irq_handler { + struct Irq_handler + { virtual void eoi() {}; virtual void enabled() {}; virtual void disabled() {}; + virtual ~Irq_handler() {}; }; enum Type { SGI, PPI, SPI }; @@ -101,8 +103,8 @@ class Vmm::Gic : public Vmm::Mmio_device { unsigned const irq_count; - virtual Register read(Irq & irq) { return 0; } - virtual void write(Irq & irq, Register reg) { } + virtual Register read(Irq &) { return 0; } + virtual void write(Irq &, Register) { } Register read(Address_range & access, Cpu&) override; void write(Address_range & access, Cpu&, Register value) override; @@ -111,9 +113,21 @@ class Vmm::Gic : public Vmm::Mmio_device Mmio_register::Type type, Genode::uint64_t start, unsigned bits_per_irq, - unsigned irq_count) - : Mmio_register(name, type, start, bits_per_irq*irq_count/8), + unsigned irq_count, + Space & device) + : Mmio_register(name, type, start, bits_per_irq*irq_count/8, device), irq_count(irq_count) {} + + template + void for_range(Address_range & access, FN const & fn) + { + Register bits_per_irq = size() * 8 / irq_count; + for (Register i = (access.start() * 8) / bits_per_irq; + i < ((access.start()+access.size()) * 8) / bits_per_irq; i++) { + static_assert(MAX_IRQ < ~0U); + if (i < MAX_IRQ) fn((unsigned)i, bits_per_irq); + } + } }; class Gicd_banked @@ -132,120 +146,140 @@ class Vmm::Gic : public Vmm::Mmio_device Gic & _gic; Genode::Constructible _sgi[MAX_SGI]; Genode::Constructible _ppi[MAX_PPI]; - Irq::List _pending_list; + Irq::List _pending_list {}; struct Redistributor : Mmio_device, Genode::Interface { unsigned cpu_id; bool last; Mmio_register gicr_ctlr { "GICR_CTLR", Mmio_register::RO, - 0x0, 4, 0b10010 }; + 0x0, 4, registers(), 0b10010 }; Mmio_register gicr_typer { "GICR_TYPER", Mmio_register::RO, - 0x8, 8, + 0x8, 8, registers(), (Genode::uint64_t)cpu_id<<32 | cpu_id<<8 | (last ? 1<<4 : 0) }; Mmio_register gicr_waker { "GICR_WAKER", Mmio_register::RO, - 0x14, 4, 0 }; + 0x14, 4, registers(), 0 }; Mmio_register gicr_pidr2 { "GICR_PIDR2", Mmio_register::RO, - 0xffe8, 4, (3<<4) }; + 0xffe8, 4, registers(), (3<<4) }; Mmio_register gicr_igroupr0 { "GICR_IGROUPR0", Mmio_register::RO, - 0x10080, 4, 0 }; + 0x10080, 4, registers(), 0 }; struct Gicr_isenabler0 : Irq_reg { - Register read(Irq & irq) { return irq.enabled(); } - void write(Irq & irq, Register v) { if (v) irq.enable(); } + Register read(Irq & irq) override { + return irq.enabled(); } - Gicr_isenabler0() - : Irq_reg("GICR_ISENABLER0", Mmio_register::RW, 0x10100, 1, 32) {} - } gicr_isenabler0; + void write(Irq & irq, Register v) override { + if (v) irq.enable(); } + + Gicr_isenabler0(Space & device) + : Irq_reg("GICR_ISENABLER0", Mmio_register::RW, + 0x10100, 1, 32, device) {} + } gicr_isenabler0 { registers() }; struct Gicr_icenabler0 : Irq_reg { - Register read(Irq & irq) { return irq.enabled(); } - void write(Irq & irq, Register v) { if (v) irq.disable(); } + Register read(Irq & irq) override { + return irq.enabled(); } - Gicr_icenabler0() - : Irq_reg("GICR_ICENABLER0", Mmio_register::RW, 0x10180, 1, 32) {} - } gicr_icenabler0; + void write(Irq & irq, Register v) override { + if (v) irq.disable(); } + + Gicr_icenabler0(Space & device) + : Irq_reg("GICR_ICENABLER0", Mmio_register::RW, + 0x10180, 1, 32, device) {} + } gicr_icenabler0 { registers() }; struct Gicr_ispendr0 : Irq_reg { - Register read(Irq & irq) { return irq.pending(); } - void write(Irq & irq, Register v) { if (v) irq.assert(); } + Register read(Irq & irq) override { + return irq.pending(); } - Gicr_ispendr0() - : Irq_reg("GICR_ISPENDR0", Mmio_register::RW, 0x10200, 1, 32) {} - } gicr_ispendr0; + void write(Irq & irq, Register v) override { + if (v) irq.assert(); } + + Gicr_ispendr0(Space & device) + : Irq_reg("GICR_ISPENDR0", Mmio_register::RW, + 0x10200, 1, 32, device) {} + } gicr_ispendr0 { registers() }; struct Gicr_icpendr0 : Irq_reg { - Register read(Irq & irq) { return irq.pending(); } - void write(Irq & irq, Register v) { if (v) irq.deassert(); } + Register read(Irq & irq) override { + return irq.pending(); } - Gicr_icpendr0() - : Irq_reg("GICR_ICPENDR0", Mmio_register::RW, 0x10280, 1, 32) {} - } gicr_icpendr0; + void write(Irq & irq, Register v) override { + if (v) irq.deassert(); } + + Gicr_icpendr0(Space & device) + : Irq_reg("GICR_ICPENDR0", Mmio_register::RW, + 0x10280, 1, 32, device) {} + } gicr_icpendr0 { registers() }; struct Gicr_isactiver0 : Irq_reg { - Register read(Irq & irq) { return irq.active(); } - void write(Irq & irq, Register v) { if (v) irq.activate(); } + Register read(Irq & irq) override { + return irq.active(); } - Gicr_isactiver0() - : Irq_reg("GICR_ISACTIVER0", Mmio_register::RW, 0x10300, 1, 32) {} - } gicr_isactiver0; + void write(Irq & irq, Register v) override { + if (v) irq.activate(); } + + Gicr_isactiver0(Space & device) + : Irq_reg("GICR_ISACTIVER0", Mmio_register::RW, + 0x10300, 1, 32, device) {} + } gicr_isactiver0 { registers() }; struct Gicr_icactiver0 : Irq_reg { - Register read(Irq & irq) { return irq.active(); } - void write(Irq & irq, Register v) { if (v) irq.deactivate(); } + Register read(Irq & irq) override { + return irq.active(); } - Gicr_icactiver0() - : Irq_reg("GICR_ICACTIVER0", Mmio_register::RW, 0x10380, 1, 32) {} - } gicr_icactiver0; + void write(Irq & irq, Register v) override { + if (v) irq.deactivate(); } + + Gicr_icactiver0(Space & device) + : Irq_reg("GICR_ICACTIVER0", Mmio_register::RW, + 0x10380, 1, 32, device) {} + } gicr_icactiver0 { registers() }; struct Gicr_ipriorityr : Irq_reg { - Register read(Irq & irq) { return irq.priority(); } - void write(Irq & irq, Register v) { irq.priority(v); } + Register read(Irq & irq) override { + return irq.priority(); } - Gicr_ipriorityr() - : Irq_reg("GICR_IPRIORITYR", Mmio_register::RW, 0x10400, 8, 32) {} - } gicr_ipriorityr; + void write(Irq & irq, Register v) override { + irq.priority((uint8_t)v); } + + Gicr_ipriorityr(Space & device) + : Irq_reg("GICR_IPRIORITYR", Mmio_register::RW, + 0x10400, 8, 32, device) {} + } gicr_ipriorityr { registers() }; struct Gicr_icfgr : Irq_reg { - Register read(Irq & irq) { return irq.level() ? 0 : 1; } - void write(Irq & irq, Register v) { irq.level(!v); } + Register read(Irq & irq) override { + return irq.level() ? 0 : 1; } + void write(Irq & irq, Register v) override { + irq.level(!v); } - Gicr_icfgr() - : Irq_reg("GICR_ICFGR", Mmio_register::RW, 0x10c00, 8, 32) {} - } gicr_icfgr; + Gicr_icfgr(Space & device) + : Irq_reg("GICR_ICFGR", Mmio_register::RW, + 0x10c00, 8, 32, device) {} + } gicr_icfgr { registers() }; Redistributor(const Genode::uint64_t addr, const Genode::uint64_t size, + Space & bus, unsigned cpu_id, bool last) - : Mmio_device("GICR", addr, size), cpu_id(cpu_id), last(last) - { - add(gicr_ctlr); - add(gicr_typer); - add(gicr_waker); - add(gicr_pidr2); - add(gicr_igroupr0); - add(gicr_isenabler0); - add(gicr_icenabler0); - add(gicr_ispendr0); - add(gicr_icpendr0); - add(gicr_isactiver0); - add(gicr_icactiver0); - add(gicr_ipriorityr); - add(gicr_icfgr); - } + : + Mmio_device("GICR", addr, size, bus), + cpu_id(cpu_id), + last(last) { } }; - Genode::Constructible _rdist; + Genode::Constructible _rdist {}; }; unsigned version(); @@ -256,7 +290,7 @@ class Vmm::Gic : public Vmm::Mmio_device unsigned cpus, unsigned version, Genode::Vm_connection & vm, - Mmio_bus & bus, + Space & bus, Genode::Env & env); private: @@ -264,167 +298,221 @@ class Vmm::Gic : public Vmm::Mmio_device friend struct Gicd_banked; Genode::Constructible _spi[MAX_SPI]; - Irq::List _pending_list; + Irq::List _pending_list {}; unsigned _cpu_cnt; unsigned _version; - struct Gicd_ctlr : Genode::Register<32>, Mmio_register + struct Gicd_ctlr : Mmio_register { - struct Enable : Bitfield<0, 1> {}; - struct Disable : Bitfield<6, 1> {}; + struct Reg : Genode::Register<32> + { + struct Enable : Bitfield<0, 1> {}; + struct Disable : Bitfield<6, 1> {}; + }; void write(Address_range & access, Cpu & cpu, Mmio_register::Register value) override { - access_t v = value; - Disable::set(v, 0); + Reg::access_t v = (Reg::access_t)value; + Reg::Disable::set(v, 0); Mmio_register::write(access, cpu, v); } - Gicd_ctlr() - : Mmio_register("GICD_CTLR", Mmio_register::RW, 0, 4, 0) {} - } _ctrl; + Gicd_ctlr(Space & device) + : Mmio_register("GICD_CTLR", Mmio_register::RW, 0, 4, device, 0) {} + } _ctrl { registers() }; - struct Gicd_typer : Genode::Register<32>, Mmio_register + struct Gicd_typer : Mmio_register { - struct It_lines_number : Bitfield<0, 5> {}; - struct Cpu_number : Bitfield<5, 3> {}; - struct Id_bits : Bitfield<19, 5> {}; + struct Reg : Genode::Register<32> + { + struct It_lines_number : Bitfield<0, 5> {}; + struct Cpu_number : Bitfield<5, 3> {}; + struct Id_bits : Bitfield<19, 5> {}; + }; - Gicd_typer(unsigned cpus) - : Mmio_register("GICD_TYPER", Mmio_register::RO, 0x4, 4, - It_lines_number::bits(31) | - Cpu_number::bits(cpus-1) | Id_bits::bits(9)) {} - } _typer { _cpu_cnt }; + Gicd_typer(Space & device, unsigned cpus) + : Mmio_register("GICD_TYPER", Mmio_register::RO, 0x4, 4, device, + Reg::It_lines_number::bits(31) | + Reg::Cpu_number::bits(cpus-1) | + Reg::Id_bits::bits(9)) {} + } _typer { registers(), _cpu_cnt }; - struct Gicd_iidr : Genode::Register<32>, Mmio_register + struct Gicd_iidr : Mmio_register { - struct Implementer : Bitfield<0, 12> {}; - struct Revision : Bitfield<12, 4> {}; - struct Variant : Bitfield<16, 4> {}; - struct Product_id : Bitfield<24, 8> {}; + struct Reg : Genode::Register<32> + { + struct Implementer : Bitfield<0, 12> {}; + struct Revision : Bitfield<12, 4> {}; + struct Variant : Bitfield<16, 4> {}; + struct Product_id : Bitfield<24, 8> {}; + }; - Gicd_iidr() - : Mmio_register("GICD_IIDR", Mmio_register::RO, 0x8, 4, 0x123) {} - } _iidr; + Gicd_iidr(Space & device) + : Mmio_register("GICD_IIDR", Mmio_register::RO, 0x8, 4, + device, 0x123) {} + } _iidr { registers() }; struct Gicd_igroupr : Irq_reg { - Gicd_igroupr() - : Irq_reg("GICD_IGROUPR", Mmio_register::RW, 0x80, 1, 1024) {} - } _igroupr; + Gicd_igroupr(Space & device) + : Irq_reg("GICD_IGROUPR", Mmio_register::RW, 0x80, 1, + 1024, device) {} + } _igroupr { registers() }; struct Gicd_isenabler : Irq_reg { - Register read(Irq & irq) { return irq.enabled(); } - void write(Irq & irq, Register v) { if (v) irq.enable(); } + Register read(Irq & irq) override { + return irq.enabled(); } - Gicd_isenabler() - : Irq_reg("GICD_ISENABLER", Mmio_register::RW, 0x100, 1, 1024) {} - } _isenabler; + void write(Irq & irq, Register v) override { + if (v) irq.enable(); } + + Gicd_isenabler(Space & device) + : Irq_reg("GICD_ISENABLER", Mmio_register::RW, 0x100, 1, + 1024, device) {} + } _isenabler { registers() }; struct Gicd_icenabler : Irq_reg { - Register read(Irq & irq) { return irq.enabled(); } - void write(Irq & irq, Register v) { if (v) irq.disable(); } + Register read(Irq & irq) override { + return irq.enabled(); } - Gicd_icenabler() - : Irq_reg("GICD_ICENABLER", Mmio_register::RW, 0x180, 1, 1024) {} - } _csenabler; + void write(Irq & irq, Register v) override { + if (v) irq.disable(); } + + Gicd_icenabler(Space & device) + : Irq_reg("GICD_ICENABLER", Mmio_register::RW, 0x180, 1, + 1024, device) {} + } _csenabler { registers() }; struct Gicd_ispendr : Irq_reg { - Register read(Irq & irq) { return irq.pending(); } - void write(Irq & irq, Register v) { if (v) irq.assert(); } + Register read(Irq & irq) override { + return irq.pending(); } - Gicd_ispendr() - : Irq_reg("GICD_ISPENDR", Mmio_register::RW, 0x200, 1, 1024) {} - } _ispendr; + void write(Irq & irq, Register v) override { + if (v) irq.assert(); } + + Gicd_ispendr(Space & device) + : Irq_reg("GICD_ISPENDR", Mmio_register::RW, 0x200, 1, + 1024, device) {} + } _ispendr { registers() }; struct Gicd_icpendr : Irq_reg { - Register read(Irq & irq) { return irq.pending(); } - void write(Irq & irq, Register v) { if (v) irq.deassert(); } + Register read(Irq & irq) override { + return irq.pending(); } - Gicd_icpendr() - : Irq_reg("GICD_ICPENDR", Mmio_register::RW, 0x280, 1, 1024) {} - } _icpendr; + void write(Irq & irq, Register v) override { + if (v) irq.deassert(); } + + Gicd_icpendr(Space & device) + : Irq_reg("GICD_ICPENDR", Mmio_register::RW, 0x280, 1, + 1024, device) {} + } _icpendr { registers() }; struct Gicd_isactiver : Irq_reg { - Register read(Irq & irq) { return irq.active(); } - void write(Irq & irq, Register v) { if (v) irq.activate(); } + Register read(Irq & irq) override { + return irq.active(); } - Gicd_isactiver() - : Irq_reg("GICD_ISACTIVER", Mmio_register::RW, 0x300, 1, 1024) {} - } _isactiver; + void write(Irq & irq, Register v) override { + if (v) irq.activate(); } + + Gicd_isactiver(Space & device) + : Irq_reg("GICD_ISACTIVER", Mmio_register::RW, 0x300, 1, + 1024, device) {} + } _isactiver { registers() }; struct Gicd_icactiver : Irq_reg { - Register read(Irq & irq) { return irq.active(); } - void write(Irq & irq, Register v) { if (v) irq.deactivate(); } + Register read(Irq & irq) override { + return irq.active(); } - Gicd_icactiver() - : Irq_reg("GICD_ICACTIVER", Mmio_register::RW, 0x380, 1, 1024) {} - } _icactiver; + void write(Irq & irq, Register v) override { + if (v) irq.deactivate(); } + + Gicd_icactiver(Space & device) + : Irq_reg("GICD_ICACTIVER", Mmio_register::RW, 0x380, 1, + 1024, device) {} + } _icactiver { registers() }; struct Gicd_ipriorityr : Irq_reg { - Register read(Irq & irq) { return irq.priority(); } - void write(Irq & irq, Register v) { irq.priority(v); } + Register read(Irq & irq) override { + return irq.priority(); } - Gicd_ipriorityr() - : Irq_reg("GICD_IPRIORITYR", Mmio_register::RW, 0x400, 8, 1024) {} - } _ipriorityr; + void write(Irq & irq, Register v) override { + irq.priority((uint8_t)v); } + + Gicd_ipriorityr(Space & device) + : Irq_reg("GICD_IPRIORITYR", Mmio_register::RW, 0x400, 8, + 1024, device) {} + } _ipriorityr { registers() }; struct Gicd_itargetr : Irq_reg { - Register read(Irq & irq) { return irq.target(); } - void write(Irq & irq, Register v) { irq.target(v); } + Register read(Irq & irq) override { + return irq.target(); } + + void write(Irq & irq, Register v) override { + irq.target((uint8_t)v); } Register read(Address_range & access, Cpu&) override; void write(Address_range & access, Cpu&, Register value) override; - Gicd_itargetr() - : Irq_reg("GICD_ITARGETSR", Mmio_register::RW, 0x800, 8, 1024) {} - } _itargetr; + Gicd_itargetr(Space & device) + : Irq_reg("GICD_ITARGETSR", Mmio_register::RW, 0x800, 8, + 1024, device) {} + } _itargetr { registers() }; struct Gicd_icfgr : Irq_reg { - Register read(Irq & irq) { return irq.level() ? 0 : 2; } - void write(Irq & irq, Register v) { irq.level(!v); } + Register read(Irq & irq) override { + return irq.level() ? 0 : 2; } - Gicd_icfgr() - : Irq_reg("GICD_ICFGR", Mmio_register::RW, 0xc00, 2, 1024) {} - } _icfgr; + void write(Irq & irq, Register v) override { + irq.level(!v); } - struct Gicd_sgir : Genode::Register<32>, Mmio_register + Gicd_icfgr(Space & device) + : Irq_reg("GICD_ICFGR", Mmio_register::RW, 0xc00, 2, + 1024, device) {} + } _icfgr { registers() }; + + struct Gicd_sgir : Mmio_register { - struct Int_id : Bitfield<0, 4> {}; - struct Target_list : Bitfield<16, 8> {}; - struct Target_filter : Bitfield<24, 2> { - enum Target_type { LIST, ALL, MYSELF, INVALID }; + struct Reg : Genode::Register<32> + { + struct Int_id : Bitfield<0, 4> {}; + struct Target_list : Bitfield<16, 8> {}; + struct Target_filter : Bitfield<24, 2> { + enum Target_type { LIST, ALL, MYSELF, INVALID }; + }; }; void write(Address_range & access, Cpu & cpu, Mmio_register::Register value) override; - Gicd_sgir() - : Mmio_register("GICD_SGIR", Mmio_register::WO, 0xf00, 4, 0) {} - } _sgir; + Gicd_sgir(Space & device) + : Mmio_register("GICD_SGIR", Mmio_register::WO, 0xf00, 4, + device, 0) {} + } _sgir { registers() }; struct Gicd_irouter : Irq_reg { - Register read(Irq &) { return 0x0; } /* FIXME affinity routing support */ + Register read(Irq &) override { + return 0x0; } /* FIXME affinity routing support */ - void write(Irq & i, Register v) { + void write(Irq & i, Register v) override { if (v) Genode::error("Affinity routing not supported ", i.number()); } - Gicd_irouter() - : Irq_reg("GICD_IROUTER", Mmio_register::RW, 0x6100, 64, 1024) {} - } _irouter; + Gicd_irouter(Space & device) + : Irq_reg("GICD_IROUTER", Mmio_register::RW, 0x6100, 64, + 1024, device) {} + } _irouter { registers() }; /** * FIXME: missing registers: @@ -436,22 +524,14 @@ class Vmm::Gic : public Vmm::Mmio_device * GICD identification registers 0xfd0... */ - /** - * Dummy container for holding array of noncopyable objects - * Workaround for gcc bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70395 - */ - struct Dummy { - Mmio_register regs[8]; - } _reg_container { .regs = { - { "GICD_PIDR4", Mmio_register::RO, 0xffd0, 4, 0x0 }, - { "GICD_PIDR5", Mmio_register::RO, 0xffd4, 4, 0x0 }, - { "GICD_PIDR6", Mmio_register::RO, 0xffd8, 4, 0x0 }, - { "GICD_PIDR7", Mmio_register::RO, 0xffdc, 4, 0x0 }, - { "GICD_PIDR0", Mmio_register::RO, 0xffe0, 4, 0x492 }, - { "GICD_PIDR1", Mmio_register::RO, 0xffe4, 4, 0xb0 }, - { "GICD_PIDR2", Mmio_register::RO, 0xffe8, 4, (_version<<4) | 0xb }, - { "GICD_PIDR3", Mmio_register::RO, 0xffec, 4, 0x44 } - }}; + Mmio_register _pidr0 { "GICD_PIDR0", Mmio_register::RO, 0xffe0, 4, registers(), 0x492 }; + Mmio_register _pidr1 { "GICD_PIDR1", Mmio_register::RO, 0xffe4, 4, registers(), 0xb0 }; + Mmio_register _pidr2 { "GICD_PIDR2", Mmio_register::RO, 0xffe8, 4, registers(), (_version<<4) | 0xb }; + Mmio_register _pidr3 { "GICD_PIDR3", Mmio_register::RO, 0xffec, 4, registers(), 0x44 }; + Mmio_register _pidr4 { "GICD_PIDR4", Mmio_register::RO, 0xffd0, 4, registers(), 0x0 }; + Mmio_register _pidr5 { "GICD_PIDR5", Mmio_register::RO, 0xffd4, 4, registers(), 0x0 }; + Mmio_register _pidr6 { "GICD_PIDR6", Mmio_register::RO, 0xffd8, 4, registers(), 0x0 }; + Mmio_register _pidr7 { "GICD_PIDR7", Mmio_register::RO, 0xffdc, 4, registers(), 0x0 }; }; #endif /* _SRC__SERVER__VMM__GIC_H_ */ diff --git a/repos/os/src/server/vmm/mmio.cc b/repos/os/src/server/vmm/mmio.cc index 14f625f5d6..dd3cf8570c 100644 --- a/repos/os/src/server/vmm/mmio.cc +++ b/repos/os/src/server/vmm/mmio.cc @@ -16,7 +16,7 @@ using namespace Vmm; -Mmio_register::Register Mmio_register::read(Address_range & access, Cpu & cpu) +Mmio_register::Register Mmio_register::read(Address_range & access, Cpu &) { if (_type == WO) throw Exception("Invalid read access to register ", @@ -24,17 +24,17 @@ Mmio_register::Register Mmio_register::read(Address_range & access, Cpu & cpu) using namespace Genode; - switch (access.size) { - case 1: return *(uint8_t*) ((addr_t)&_value + access.start); - case 2: return *(uint16_t*) ((addr_t)&_value + access.start); - case 4: return *(uint32_t*) ((addr_t)&_value + access.start); + switch (access.size()) { + case 1: return *(uint8_t*) ((addr_t)&_value + access.start()); + case 2: return *(uint16_t*) ((addr_t)&_value + access.start()); + case 4: return *(uint32_t*) ((addr_t)&_value + access.start()); case 8: return _value; default: return 0; } } -void Mmio_register::write(Address_range & access, Cpu & cpu, Register value) +void Mmio_register::write(Address_range & access, Cpu &, Register value) { if (_type == RO) throw Exception("Invalid write access to register ", @@ -42,10 +42,13 @@ void Mmio_register::write(Address_range & access, Cpu & cpu, Register value) using namespace Genode; - switch (access.size) { - case 1: *((uint8_t*) ((addr_t)&_value + access.start)) = value; - case 2: *((uint16_t*) ((addr_t)&_value + access.start)) = value; - case 4: *((uint32_t*) ((addr_t)&_value + access.start)) = value; + switch (access.size()) { + case 1: *((uint8_t*) ((addr_t)&_value + access.start())) = (uint8_t) value; + break; + case 2: *((uint16_t*) ((addr_t)&_value + access.start())) = (uint16_t)value; + break; + case 4: *((uint32_t*) ((addr_t)&_value + access.start())) = (uint32_t)value; + break; case 8: _value = value; } } @@ -60,7 +63,7 @@ void Mmio_register::set(Register value) { _value = value; } Mmio_device::Register Mmio_device::read(Address_range & access, Cpu & cpu) { Mmio_register & reg = _registers.get(access); - Address_range ar(access.start - reg.start, access.size); + Address_range ar(access.start() - reg.start(), access.size()); return reg.read(ar, cpu); } @@ -68,7 +71,7 @@ Mmio_device::Register Mmio_device::read(Address_range & access, Cpu & cpu) void Mmio_device::write(Address_range & access, Cpu & cpu, Register value) { Mmio_register & reg = _registers.get(access); - Address_range ar(access.start - reg.start, access.size); + Address_range ar(access.start() - reg.start(), access.size()); reg.write(ar, cpu, value); } @@ -94,27 +97,30 @@ void Vmm::Mmio_bus::handle_memory_access(Vmm::Cpu & cpu) static bool valid(access_t v) { return Valid::get(v) && !Sign_extend::get(v); } - static bool write(access_t v) { return Write::get(v); } - static unsigned r(access_t v) { return Register::get(v); } + static bool write(access_t v) { return Write::get(v); } + static addr_t r(access_t v) { return Register::get(v); } }; - if (!Iss::valid(state.esr_el2)) + Iss::access_t iss = state.esr_el2; + + if (!Iss::valid(iss)) throw Exception("Mmio_bus: unknown ESR=", Genode::Hex(state.esr_el2)); - bool wr = Iss::Write::get(state.esr_el2); - unsigned idx = Iss::Register::get(state.esr_el2); + bool wr = Iss::Write::get(iss); + unsigned idx = (unsigned)Iss::Register::get(iss); uint64_t ipa = ((uint64_t)state.hpfar_el2 << 8) + (state.far_el2 & ((1 << 12) - 1)); - uint64_t width = 1 << Iss::Access_size::get(state.esr_el2); + uint64_t width = 1 << Iss::Access_size::get(iss); try { Address_range bus_range(ipa, width); Mmio_device & dev = get(bus_range); - Address_range dev_range(ipa - dev.start,width); + Address_range dev_range(ipa - dev.start(), width); if (wr) { dev.write(dev_range, cpu, state.reg(idx)); } else { - state.reg(idx, dev.read(dev_range, cpu)); + /* on 32-bit ARM we do not support 64-bit data access */ + state.reg(idx, (addr_t)dev.read(dev_range, cpu)); } } catch(Exception & e) { Genode::warning(e); diff --git a/repos/os/src/server/vmm/mmio.h b/repos/os/src/server/vmm/mmio.h index e26d4969bc..4187d392fe 100644 --- a/repos/os/src/server/vmm/mmio.h +++ b/repos/os/src/server/vmm/mmio.h @@ -30,23 +30,28 @@ class Vmm::Mmio_register : public Vmm::Address_range enum Type { RO, WO, RW }; - using Name = Genode::String<64>; - using Register = Genode::uint64_t; + using Name = String<64>; + using Register = uint64_t; + using Space = Address_space; virtual Register read(Address_range & access, Cpu&); virtual void write(Address_range & access, Cpu&, Register value); virtual void set(Register value); virtual Register value() const; - Mmio_register(Name name, - Type type, - Genode::uint64_t start, - Genode::uint64_t size, - Register reset_value = 0) + Mmio_register(Name name, + Type type, + uint64_t start, + uint64_t size, + Space & device, + Register reset_value = 0) : Address_range(start, size), _name(name), _type(type), - _value(reset_value) { } + _value(reset_value) + { + device.add(*this); + } protected: @@ -62,23 +67,32 @@ class Vmm::Mmio_device : public Vmm::Address_range { public: - using Name = Genode::String<64>; - using Register = Genode::uint64_t; + using Name = String<64>; + using Register = uint64_t; + using Space = Address_space; + + private: + + Name const _name; + Address_space _registers {}; + + public: + + Space & registers() { return _registers; } virtual Register read(Address_range & access, Cpu&); virtual void write(Address_range & access, Cpu&, Register value); void add(Mmio_register & reg); - Mmio_device(Name name, - Genode::uint64_t start, - Genode::uint64_t size) - : Address_range(start, size), _name(name) { } - - private: - - Name const _name; - Address_space _registers; + Mmio_device(Name name, + uint64_t start, + uint64_t size, + Space & bus) + : Address_range(start, size), _name(name) + { + bus.add(*this); + } }; diff --git a/repos/os/src/server/vmm/pl011.cc b/repos/os/src/server/vmm/pl011.cc index 68defd9f5c..abcc196048 100644 --- a/repos/os/src/server/vmm/pl011.cc +++ b/repos/os/src/server/vmm/pl011.cc @@ -54,7 +54,7 @@ Register Pl011::Uartmis::read(Address_range&, Cpu&) } -void Pl011::Uarticr::write(Address_range & ar, Cpu &, Register value) +void Pl011::Uarticr::write(Address_range &, Cpu &, Register value) { ris.set(ris.value() & ~value); } @@ -80,23 +80,12 @@ Pl011::Pl011(const char * const name, const Genode::uint64_t size, unsigned irq, Cpu & cpu, - Mmio_bus & bus, + Space & bus, Genode::Env & env) -: Mmio_device(name, addr, size), +: Mmio_device(name, addr, size, bus), _terminal(env, "earlycon"), _handler(cpu, env.ep(), *this, &Pl011::_read), _irq(cpu.gic().irq(irq)) { - for (unsigned i = 0; i < (sizeof(Dummy::regs) / sizeof(Mmio_register)); i++) - add(_reg_container.regs[i]); - add(_uart_ris); - add(_uart_dr); - add(_uart_fr); - add(_uart_imsc); - add(_uart_mis); - add(_uart_icr); - _terminal.read_avail_sigh(_handler); - - bus.add(*this); } diff --git a/repos/os/src/server/vmm/pl011.h b/repos/os/src/server/vmm/pl011.h index abd1f9b50c..3caa15b1c4 100644 --- a/repos/os/src/server/vmm/pl011.h +++ b/repos/os/src/server/vmm/pl011.h @@ -40,9 +40,9 @@ class Vmm::Pl011 : public Vmm::Mmio_device Terminal::Connection _terminal; Cpu::Signal_handler _handler; Gic::Irq & _irq; - Ring_buffer _rx_buf; + Ring_buffer _rx_buf {}; Mmio_register _uart_ris { "UARTRIS", Mmio_register::RO, - 0x3c, 2 }; + 0x3c, 2, registers() }; /** * Dummy container for holding array of noncopyable objects @@ -51,19 +51,19 @@ class Vmm::Pl011 : public Vmm::Mmio_device struct Dummy { Mmio_register regs[13]; } _reg_container { .regs = { - { "UARTIBRD", Mmio_register::RW, 0x24, 2, 0 }, - { "UARTFBRD", Mmio_register::RW, 0x28, 2, 0 }, - { "UARTLCR_H", Mmio_register::RW, 0x2c, 2, 0 }, - { "UARTCR", Mmio_register::RW, 0x30, 2, 0x300 }, - { "UARTIFLS", Mmio_register::RW, 0x34, 2, 0x12 }, - { "UARTPERIPHID0", Mmio_register::RO, 0xfe0, 4, 0x11 }, - { "UARTPERIPHID1", Mmio_register::RO, 0xfe4, 4, 0x10 }, - { "UARTPERIPHID2", Mmio_register::RO, 0xfe8, 4, 0x14 }, - { "UARTPERIPHID3", Mmio_register::RO, 0xfec, 4, 0x0 }, - { "UARTPCELLID0", Mmio_register::RO, 0xff0, 4, 0xd }, - { "UARTPCELLID1", Mmio_register::RO, 0xff4, 4, 0xf0 }, - { "UARTPCELLID2", Mmio_register::RO, 0xff8, 4, 0x5 }, - { "UARTPCELLID3", Mmio_register::RO, 0xffc, 4, 0xb1 } + { "UARTIBRD", Mmio_register::RW, 0x24, 2, registers(), 0 }, + { "UARTFBRD", Mmio_register::RW, 0x28, 2, registers(), 0 }, + { "UARTLCR_H", Mmio_register::RW, 0x2c, 2, registers(), 0 }, + { "UARTCR", Mmio_register::RW, 0x30, 2, registers(), 0x300 }, + { "UARTIFLS", Mmio_register::RW, 0x34, 2, registers(), 0x12 }, + { "UARTPERIPHID0", Mmio_register::RO, 0xfe0, 4, registers(), 0x11 }, + { "UARTPERIPHID1", Mmio_register::RO, 0xfe4, 4, registers(), 0x10 }, + { "UARTPERIPHID2", Mmio_register::RO, 0xfe8, 4, registers(), 0x14 }, + { "UARTPERIPHID3", Mmio_register::RO, 0xfec, 4, registers(), 0x0 }, + { "UARTPCELLID0", Mmio_register::RO, 0xff0, 4, registers(), 0xd }, + { "UARTPCELLID1", Mmio_register::RO, 0xff4, 4, registers(), 0xf0 }, + { "UARTPCELLID2", Mmio_register::RO, 0xff8, 4, registers(), 0x5 }, + { "UARTPCELLID3", Mmio_register::RO, 0xffc, 4, registers(), 0xb1 } }}; struct Uartdr : Mmio_register @@ -75,25 +75,31 @@ class Vmm::Pl011 : public Vmm::Mmio_device Register read(Address_range&, Cpu&) override; void write(Address_range&, Cpu&, Register) override; - Uartdr(Terminal::Connection & terminal, + Uartdr(Space & device, + Terminal::Connection & terminal, Ring_buffer & rx, Mmio_register & ris) - : Mmio_register("UARTDR", Mmio_register::RW, 0x0, 2), - terminal(terminal), rx(rx), ris(ris) {} - } _uart_dr { _terminal, _rx_buf, _uart_ris }; + : + Mmio_register("UARTDR", Mmio_register::RW, 0x0, 2, device), + terminal(terminal), rx(rx), ris(ris) {} + } _uart_dr { registers(), _terminal, _rx_buf, _uart_ris }; - struct Uartfr : Mmio_register, Genode::Register<32> + class Uartfr : public Mmio_register, protected Genode::Register<32> { - struct Rx_empty : Bitfield<4, 1> {}; - struct Rx_full : Bitfield<6, 1> {}; + public: - Ring_buffer & rx; + struct Rx_empty : Bitfield<4, 1> {}; + struct Rx_full : Bitfield<6, 1> {}; - Mmio_register::Register read(Address_range&, Cpu&) override; + Ring_buffer & rx; - Uartfr(Ring_buffer & rx) - : Mmio_register("UARTFR", Mmio_register::RO, 0x18, 4), rx(rx) {} - } _uart_fr { _rx_buf }; + Mmio_register::Register read(Address_range&, Cpu&) override; + + Uartfr(Space & device, Ring_buffer & rx) + : + Mmio_register("UARTFR", Mmio_register::RO, 0x18, 4, device), + rx(rx) {} + } _uart_fr { registers(), _rx_buf }; struct Uartimsc : Mmio_register { @@ -102,10 +108,12 @@ class Vmm::Pl011 : public Vmm::Mmio_device void write(Address_range&, Cpu&, Register) override; - Uartimsc(Gic::Irq & irq, Mmio_register & ris) - : Mmio_register("UARTIMSC", Mmio_register::RW, 0x38, 2, 0xf), - irq(irq), ris(ris) {} - } _uart_imsc { _irq, _uart_ris }; + Uartimsc(Space & device, Gic::Irq & irq, Mmio_register & ris) + : + Mmio_register("UARTIMSC", Mmio_register::RW, 0x38, 2, + device, 0xf), + irq(irq), ris(ris) {} + } _uart_imsc { registers(), _irq, _uart_ris }; struct Uartmis : Mmio_register { @@ -114,10 +122,11 @@ class Vmm::Pl011 : public Vmm::Mmio_device Register read(Address_range&, Cpu&) override; - Uartmis(Mmio_register & ris, Uartimsc & imsc) - : Mmio_register("UARTMIS", Mmio_register::RO, 0x40, 2), - ris(ris), imsc(imsc) {} - } _uart_mis { _uart_ris, _uart_imsc }; + Uartmis(Space & device, Mmio_register & ris, Uartimsc & imsc) + : + Mmio_register("UARTMIS", Mmio_register::RO, 0x40, 2, device), + ris(ris), imsc(imsc) {} + } _uart_mis { registers(), _uart_ris, _uart_imsc }; struct Uarticr : Mmio_register { @@ -125,9 +134,11 @@ class Vmm::Pl011 : public Vmm::Mmio_device void write(Address_range&, Cpu&, Register) override; - Uarticr(Mmio_register & ris) - : Mmio_register("UARTICR", Mmio_register::WO, 0x44, 2), ris(ris) {} - } _uart_icr { _uart_ris }; + Uarticr(Space & device, Mmio_register & ris) + : + Mmio_register("UARTICR", Mmio_register::WO, 0x44, 2, device), + ris(ris) {} + } _uart_icr { registers(), _uart_ris }; void _read(); @@ -138,7 +149,7 @@ class Vmm::Pl011 : public Vmm::Mmio_device const Genode::uint64_t size, unsigned irq, Cpu & cpu, - Mmio_bus & bus, + Space & bus, Genode::Env & env); }; diff --git a/repos/os/src/server/vmm/spec/arm_v7/cpu.cc b/repos/os/src/server/vmm/spec/arm_v7/cpu.cc index d280583e3c..b46da70b18 100644 --- a/repos/os/src/server/vmm/spec/arm_v7/cpu.cc +++ b/repos/os/src/server/vmm/spec/arm_v7/cpu.cc @@ -17,29 +17,30 @@ using Vmm::Cpu_base; using Vmm::Cpu; using Vmm::Gic; +using namespace Genode; -Genode::uint64_t Cpu_base::State::reg(unsigned idx) const +addr_t Cpu_base::State::reg(addr_t idx) const { if (idx > 15) return 0; - Genode::uint32_t * r = (Genode::uint32_t*)this; + addr_t * r = (addr_t*)this; r += idx; return *r; } -void Cpu_base::State::reg(unsigned idx, Genode::uint64_t v) +void Cpu_base::State::reg(addr_t idx, addr_t v) { if (idx > 15) return; - Genode::uint32_t * r = (Genode::uint32_t*)this; + addr_t * r = (addr_t*)this; r += idx; *r = v; } Cpu_base::System_register::Iss::access_t -Cpu_base::System_register::Iss::value(unsigned op0, unsigned crn, unsigned op1, +Cpu_base::System_register::Iss::value(unsigned, unsigned crn, unsigned op1, unsigned crm, unsigned op2) { access_t v = 0; @@ -63,7 +64,7 @@ Cpu_base::System_register::Iss::mask_encoding(access_t v) void Cpu_base::_handle_brk() { - Genode::error(__func__, " not implemented yet"); + error(__func__, " not implemented yet"); } @@ -85,8 +86,6 @@ void Cpu_base::handle_exception() void Cpu_base::dump() { - using namespace Genode; - auto lambda = [] (unsigned i) { switch (i) { case 0: return "und"; @@ -127,7 +126,7 @@ void Cpu_base::dump() } -void Cpu_base::initialize_boot(Genode::addr_t ip, Genode::addr_t dtb) +void Cpu_base::initialize_boot(addr_t ip, addr_t dtb) { state().reg(1, 0xffffffff); /* invalid machine type */ state().reg(2, dtb); @@ -135,9 +134,9 @@ void Cpu_base::initialize_boot(Genode::addr_t ip, Genode::addr_t dtb) } -Genode::addr_t Cpu::Ccsidr::read() const +addr_t Cpu::Ccsidr::read() const { - struct Csselr : Genode::Register<32> + struct Csselr : Register<32> { struct Level : Bitfield<1, 4> {}; }; @@ -147,7 +146,7 @@ Genode::addr_t Cpu::Ccsidr::read() const unsigned level = Csselr::Level::get(csselr.read()); if (level > 6) { - Genode::warning("Invalid Csselr value!"); + warning("Invalid Csselr value!"); return INVALID; } @@ -155,14 +154,14 @@ Genode::addr_t Cpu::Ccsidr::read() const } -Cpu::Cpu(Vm & vm, - Genode::Vm_connection & vm_session, - Mmio_bus & bus, - Gic & gic, - Genode::Env & env, - Genode::Heap & heap, - Genode::Entrypoint & ep, - short const id) +Cpu::Cpu(Vm & vm, + Vm_connection & vm_session, + Mmio_bus & bus, + Gic & gic, + Env & env, + Heap & heap, + Entrypoint & ep, + unsigned id) : Cpu_base(vm, vm_session, bus, gic, env, heap, ep, id), _sr_midr (0, 0, 0, 0, "MIDR", false, 0x412fc0f1, _reg_tree), _sr_mpidr (0, 0, 0, 5, "MPIDR", false, 1<<31|cpu_id(), _reg_tree), diff --git a/repos/os/src/server/vmm/spec/arm_v7/cpu.h b/repos/os/src/server/vmm/spec/arm_v7/cpu.h index 58a2d1abc4..19f348104c 100644 --- a/repos/os/src/server/vmm/spec/arm_v7/cpu.h +++ b/repos/os/src/server/vmm/spec/arm_v7/cpu.h @@ -29,7 +29,7 @@ class Vmm::Cpu : public Vmm::Cpu_base Genode::Env & env, Genode::Heap & heap, Genode::Entrypoint & ep, - short cpu_id); + unsigned cpu_id); enum Exception_type { NO_EXCEPTION, diff --git a/repos/os/src/server/vmm/spec/arm_v8/cpu.cc b/repos/os/src/server/vmm/spec/arm_v8/cpu.cc index 96d202de40..2c0e7ab7ab 100644 --- a/repos/os/src/server/vmm/spec/arm_v8/cpu.cc +++ b/repos/os/src/server/vmm/spec/arm_v8/cpu.cc @@ -17,15 +17,16 @@ using Vmm::Cpu_base; using Vmm::Cpu; using Vmm::Gic; +using namespace Genode; -Genode::uint64_t Cpu_base::State::reg(unsigned idx) const +addr_t Cpu_base::State::reg(addr_t idx) const { if (idx > 30) return 0; return r[idx]; } -void Cpu_base::State::reg(unsigned idx, Genode::uint64_t v) +void Cpu_base::State::reg(addr_t idx, addr_t v) { if (idx > 30) return; r[idx] = v; @@ -59,14 +60,16 @@ Cpu_base::System_register::Iss::mask_encoding(access_t v) void Cpu_base::_handle_brk() { - Genode::uint64_t offset = 0x0; + addr_t offset = 0x0; if (!(_state.pstate & 0b100)) { offset = 0x400; } else if (_state.pstate & 0b1) { offset = 0x200; } - _state.esr_el1 = _state.esr_el2; - _state.spsr_el1 = _state.pstate; + + /* only the below 32-bit of system register ESR_EL2 and PSTATE are used */ + _state.esr_el1 = (uint32_t)_state.esr_el2; + _state.spsr_el1 = (uint32_t)_state.pstate; _state.elr_el1 = _state.ip; _state.ip = _state.vbar_el1 + offset; _state.pstate = 0b1111000101; @@ -90,8 +93,6 @@ void Cpu_base::handle_exception() void Cpu_base::dump() { - using namespace Genode; - auto lambda = [] (addr_t exc) { switch (exc) { case Cpu::AARCH64_SYNC: return "aarch64 sync"; @@ -123,7 +124,7 @@ void Cpu_base::dump() } -Genode::addr_t Cpu::Ccsidr::read() const +addr_t Cpu::Ccsidr::read() const { struct Clidr : Genode::Register<32> { @@ -147,42 +148,42 @@ Genode::addr_t Cpu::Ccsidr::read() const enum { INVALID = 0xffffffff }; - unsigned level = Csselr::Level::get(csselr.read()); - bool instr = Csselr::Instr::get(csselr.read()); + unsigned level = Csselr::Level::get((Csselr::access_t)csselr.read()); + bool instr = Csselr::Instr::get((Csselr::access_t)csselr.read()); if (level > 6) { - Genode::warning("Invalid Csselr value!"); + warning("Invalid Csselr value!"); return INVALID; } - unsigned ce = Clidr::level(level, state.clidr_el1); + unsigned ce = Clidr::level(level, (Clidr::access_t)state.clidr_el1); if (ce == Clidr::NO_CACHE || (ce == Clidr::DATA_CACHE_ONLY && instr)) { - Genode::warning("Invalid Csselr value!"); + warning("Invalid Csselr value!"); return INVALID; } if (ce == Clidr::INSTRUCTION_CACHE_ONLY || (ce == Clidr::SEPARATE_CACHE && instr)) { - Genode::log("Return Ccsidr instr value ", state.ccsidr_inst_el1[level]); + log("Return Ccsidr instr value ", state.ccsidr_inst_el1[level]); return state.ccsidr_inst_el1[level]; } - Genode::log("Return Ccsidr value ", state.ccsidr_data_el1[level]); + log("Return Ccsidr value ", state.ccsidr_data_el1[level]); return state.ccsidr_data_el1[level]; } -Genode::addr_t Cpu::Ctr_el0::read() const +addr_t Cpu::Ctr_el0::read() const { - Genode::addr_t ret; + addr_t ret; asm volatile("mrs %0, ctr_el0" : "=r" (ret)); return ret; } -void Cpu::Icc_sgi1r_el1::write(Genode::addr_t v) +void Cpu::Icc_sgi1r_el1::write(addr_t v) { unsigned target_list = v & 0xffff; @@ -197,21 +198,21 @@ void Cpu::Icc_sgi1r_el1::write(Genode::addr_t v) }; -void Cpu_base::initialize_boot(Genode::addr_t ip, Genode::addr_t dtb) +void Cpu_base::initialize_boot(addr_t ip, addr_t dtb) { state().reg(0, dtb); state().ip = ip; } -Cpu::Cpu(Vm & vm, - Genode::Vm_connection & vm_session, - Mmio_bus & bus, - Gic & gic, - Genode::Env & env, - Genode::Heap & heap, - Genode::Entrypoint & ep, - short const id) +Cpu::Cpu(Vm & vm, + Vm_connection & vm_session, + Mmio_bus & bus, + Gic & gic, + Env & env, + Heap & heap, + Entrypoint & ep, + unsigned id) : Cpu_base(vm, vm_session, bus, gic, env, heap, ep, id), _sr_id_aa64afr0_el1 (3, 0, 0, 5, 4, "ID_AA64AFR0_EL1", false, 0x0, _reg_tree), _sr_id_aa64afr1_el1 (3, 0, 0, 5, 5, "ID_AA64AFR1_EL1", false, 0x0, _reg_tree), diff --git a/repos/os/src/server/vmm/spec/arm_v8/cpu.h b/repos/os/src/server/vmm/spec/arm_v8/cpu.h index 72ab1caaf1..626dac9e21 100644 --- a/repos/os/src/server/vmm/spec/arm_v8/cpu.h +++ b/repos/os/src/server/vmm/spec/arm_v8/cpu.h @@ -29,7 +29,7 @@ class Vmm::Cpu : public Vmm::Cpu_base Genode::Env & env, Genode::Heap & heap, Genode::Entrypoint & ep, - short cpu_id); + unsigned cpu_id); enum Exception_type { AARCH64_SYNC = 0x400, @@ -45,8 +45,8 @@ class Vmm::Cpu : public Vmm::Cpu_base private: - class Id_aa64pfr0 : public System_register, - public Genode::Register<64> + class Id_aa64pfr0 : public System_register, + protected Genode::Register<64> { private: diff --git a/repos/os/src/server/vmm/target.inc b/repos/os/src/server/vmm/target.inc index 78bd276483..48a8fc469a 100644 --- a/repos/os/src/server/vmm/target.inc +++ b/repos/os/src/server/vmm/target.inc @@ -15,5 +15,3 @@ SRC_CC += virtio_gpu.cc INC_DIR += $(PRG_DIR)/../.. $(PRG_DIR) vpath %.cc $(PRG_DIR)/../.. - -CC_CXX_WARN_STRICT := diff --git a/repos/os/src/server/vmm/virtio_block.h b/repos/os/src/server/vmm/virtio_block.h index d4c82cacf3..5fc67dff3d 100644 --- a/repos/os/src/server/vmm/virtio_block.h +++ b/repos/os/src/server/vmm/virtio_block.h @@ -33,7 +33,7 @@ class Vmm::Virtio_block_queue : public Virtio_split_queue { private: - Ring_index _used_idx; + Ring_index _used_idx {}; friend class Virtio_block_request; friend class Virtio_block_device; @@ -103,7 +103,7 @@ class Vmm::Virtio_block_request template T * _desc_addr(Descriptor const & desc) const { - return (T*) _ram.local_address(desc.address(), + return (T*) _ram.local_address((addr_t)desc.address(), desc.length()); } Index _request_idx; @@ -193,7 +193,7 @@ class Vmm::Virtio_block_device _block.update_jobs(*this); } - void _notify(unsigned idx) override + void _notify(unsigned) override { auto lambda = [&] (Index id, Descriptor_array & array, @@ -219,10 +219,10 @@ class Vmm::Virtio_block_device Register read(Address_range& range, Cpu&) override { - if (range.start == 0 && range.size == 4) + if (range.start() == 0 && range.size() == 4) return capacity & 0xffffffff; - if (range.start == 4 && range.size == 4) + if (range.start() == 4 && range.size() == 4) return capacity >> 32; throw Exception("Invalid read access of configuration area ", @@ -230,24 +230,27 @@ class Vmm::Virtio_block_device } Configuration_area(Virtio_block_device & device, uint64_t capacity) - : Mmio_register("Configuration_area", Mmio_register::RO, 0x100, 8), - capacity(capacity) { device.add(*this); } + : + Mmio_register("Configuration_area", Mmio_register::RO, + 0x100, 8, device.registers()), + capacity(capacity) { } } _config_area{ *this, _block_info.block_count * (_block_info.block_size / 512) }; public: - Virtio_block_device(const char * const name, - const uint64_t addr, - const uint64_t size, - unsigned irq, - Cpu & cpu, - Mmio_bus & bus, - Ram & ram, - Env & env, - Heap & heap) - : Virtio_device(name, addr, size, - irq, cpu, bus, ram, BLOCK), + Virtio_block_device(const char * const name, + const uint64_t addr, + const uint64_t size, + unsigned irq, + Cpu & cpu, + Mmio_bus & bus, + Ram & ram, + Virtio_device_list & list, + Env & env, + Heap & heap) + : Virtio_device(name, addr, size, irq, + cpu, bus, ram, list, BLOCK), _heap(heap), _block(env, &_block_alloc, BLOCK_BUFFER_SIZE), _handler(cpu, env.ep(), *this, &Virtio_block_device::_block_signal) { @@ -273,7 +276,7 @@ class Vmm::Virtio_block_device memcpy((char *)job.address() + offset, src, sz); } - void completed(Job &job, bool success) + void completed(Job &job, bool) { job.done(*_queue[REQUEST]); _assert_irq(); diff --git a/repos/os/src/server/vmm/virtio_console.h b/repos/os/src/server/vmm/virtio_console.h index dadb939aa0..6a034c6de7 100644 --- a/repos/os/src/server/vmm/virtio_console.h +++ b/repos/os/src/server/vmm/virtio_console.h @@ -68,14 +68,14 @@ class Vmm::Virtio_console : public Virtio_device { Register read(Address_range & range, Cpu&) override { - switch (range.start) { + switch (range.start()) { case 4: return 1; /* maximum ports */ default: ; } return 0; } - void write(Address_range & range, Cpu&, Register v) override {} + void write(Address_range &, Cpu &, Register) override {} Config_area(Virtio_console & console) : Reg(console, "ConfigArea", Mmio_register::RW, 0x100, 12) { } @@ -83,17 +83,18 @@ class Vmm::Virtio_console : public Virtio_device public: - Virtio_console(const char * const name, - const uint64_t addr, - const uint64_t size, - unsigned irq, - Cpu & cpu, - Mmio_bus & bus, - Ram & ram, - Genode::Env & env) + Virtio_console(const char * const name, + const uint64_t addr, + const uint64_t size, + unsigned irq, + Cpu & cpu, + Mmio_bus & bus, + Ram & ram, + Virtio_device_list & list, + Genode::Env & env) : - Virtio_device(name, addr, size, - irq, cpu, bus, ram, CONSOLE), + Virtio_device(name, addr, size, irq, + cpu, bus, ram, list, CONSOLE), _terminal(env, "console"), _handler(cpu, env.ep(), *this, &Virtio_console::_read) { diff --git a/repos/os/src/server/vmm/virtio_device.h b/repos/os/src/server/vmm/virtio_device.h index 533c678271..b1688aa849 100644 --- a/repos/os/src/server/vmm/virtio_device.h +++ b/repos/os/src/server/vmm/virtio_device.h @@ -26,9 +26,11 @@ namespace Vmm { class Virtio_split_queue; - class Virtio_device_base; + struct Virtio_device_base; template class Virtio_device; + using Virtio_device_list = List; + using namespace Genode; } @@ -45,7 +47,7 @@ class Vmm::Virtio_split_queue protected: - template + template class Index { private: @@ -56,12 +58,12 @@ class Vmm::Virtio_split_queue public: - Index(unsigned idx = 0) : _idx(idx % (1 << LOG2)) {} + Index(uint16_t idx = 0) : _idx(idx % (1 << LOG2)) {} void inc() { - _idx = ((_idx + 1) % (1 << LOG2)); } + _idx = ((_idx + 1U) % (1U << LOG2)); } - unsigned idx() const { return _idx; } + uint16_t idx() const { return _idx; } bool operator != (Index const & o) const { return _idx != o._idx; } @@ -73,9 +75,9 @@ class Vmm::Virtio_split_queue struct Queue_base : Mmio { - unsigned const max; + uint16_t const max; - Queue_base(addr_t base, unsigned max) + Queue_base(addr_t base, uint16_t max) : Mmio(base), max(max) {} struct Flags : Register<0x0, 16> { }; @@ -95,7 +97,7 @@ class Vmm::Virtio_split_queue Descriptor_index get(Ring_index id) { - unsigned v = read(id.idx() % max); + uint16_t v = read(id.idx() % max); if (v >= max) { throw Exception("Descriptor_index out of bounds"); } return Descriptor_index(v); @@ -170,14 +172,14 @@ class Vmm::Virtio_split_queue Ram & _ram; - Ring_index _cur_idx; + Ring_index _cur_idx {}; public: Virtio_split_queue(addr_t const descriptor_area, addr_t const device_area, addr_t const driver_area, - unsigned const queue_num, + uint16_t const queue_num, Ram & ram) : _avail(ram.local_address(driver_area, 6+2*queue_num), queue_num), @@ -203,7 +205,7 @@ class Vmm::Virtio_split_queue if (!address || !size) { break; } try { - addr_t data = _ram.local_address(address, size); + addr_t data = _ram.local_address((addr_t)address, size); size_t consumed = func(data, size); if (!consumed) { break; } _used.add(_cur_idx, id, consumed); @@ -221,23 +223,18 @@ class Vmm::Virtio_split_queue }; -class Vmm::Virtio_device_base : public List::Element -{ - public: - - virtual ~Virtio_device_base() {} -}; +struct Vmm::Virtio_device_base : public List::Element { }; template -class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base +class Vmm::Virtio_device : public Vmm::Mmio_device, private Virtio_device_base { protected: Gic::Irq & _irq; Ram & _ram; - Genode::Mutex _mutex; - Genode::Constructible _queue[NUM]; + Genode::Mutex _mutex {}; + Genode::Constructible _queue[NUM] {}; virtual void _notify(unsigned idx) = 0; @@ -259,8 +256,10 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base Mmio_register::Type type, Genode::uint64_t start, uint32_t value = 0) - : Mmio_register(name, type, start, 4, value), _dev(dev) { - _dev.add(*this); } + : + Mmio_register(name, type, start, 4, + dev.registers(), value), + _dev(dev) { } Virtio_device & device() { return _dev; } }; @@ -285,7 +284,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base Register read(Address_range &, Cpu &) override { return _regs[_selector.value()]; } - void write(Address_range & a, Cpu &, Register reg) override { + void write(Address_range &, Cpu &, Register reg) override { _regs[_selector.value()] = reg; } void set(Register value) override { @@ -358,12 +357,14 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base { Genode::Mutex::Guard guard(mutex()); - unsigned num = _queue_sel.value(); + unsigned num = (unsigned)_queue_sel.value(); - if (_queue[num].constructed()) { return; } + if (num >= NUM || _queue[num].constructed()) + return; - _queue[num].construct(_descriptor_area(), _device_area(), - _driver_area(), _queue_num.value(), _ram); + _queue[num].construct((addr_t)_descriptor_area(), (addr_t)_device_area(), + (addr_t)_driver_area(), (uint16_t)_queue_num.value(), + _ram); } struct Queue_ready : Reg @@ -392,7 +393,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base return; } - Reg::device()._notify(reg); + Reg::device()._notify((unsigned)reg); } Queue_notify(Virtio_device & device) @@ -402,7 +403,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base struct Interrupt_ack : Reg { - void write(Address_range&, Cpu&, Register reg) override + void write(Address_range&, Cpu&, Register) override { Genode::Mutex::Guard guard(Reg::device().mutex()); Reg::device()._deassert_irq(); @@ -418,12 +419,13 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base const Genode::uint64_t addr, const Genode::uint64_t size, unsigned irq, - Cpu &cpu, - Mmio_bus &bus, - Ram &ram, + Cpu & cpu, + Space & bus, + Ram & ram, + Virtio_device_list & dev_list, uint32_t dev_id) : - Mmio_device(name, addr, size), + Mmio_device(name, addr, size, bus), _irq(cpu.gic().irq(irq)), _ram(ram) { @@ -436,7 +438,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device, public Virtio_device_base _dev_feature.set(VIRTIO_F_VERSION_1); _dev_sel.set(0); /* set to 0...31 feature bits */ - bus.add(*this); + dev_list.insert(this); } Genode::Mutex & mutex() { return _mutex; } diff --git a/repos/os/src/server/vmm/virtio_gpu.cc b/repos/os/src/server/vmm/virtio_gpu.cc index 430b7d1971..a81c4cca0c 100644 --- a/repos/os/src/server/vmm/virtio_gpu.cc +++ b/repos/os/src/server/vmm/virtio_gpu.cc @@ -35,7 +35,7 @@ void Vmm::Virtio_gpu_queue::notify(Virtio_gpu_device & dev) if (!inform) return; - _used.write(_cur_idx.idx()); + _used.write((uint16_t)_cur_idx.idx()); memory_barrier(); if (_avail.inject_irq()) dev.assert_irq(); } @@ -128,7 +128,7 @@ void Vmm::Virtio_gpu_control_request::_resource_attach_backing() for (unsigned i = 0; i < nr; i++) { Entry entry(entry_base+i*Entry::SIZE); size_t sz = entry.read(); - addr_t off = _device._ram.local_address(entry.read(), sz) + addr_t off = _device._ram.local_address((addr_t)entry.read(), sz) - _device._ram.local(); res.attach(off, sz); } @@ -211,7 +211,7 @@ void Vmm::Virtio_gpu_control_request::_resource_flush() void * dst = (void*)((addr_t)_device._fb_ds->local_addr() + (_device._fb_mode.area.w() * y + x) * BYTES_PER_PIXEL); - size_t line = res.area.w() * BYTES_PER_PIXEL; + uint32_t line = res.area.w() * BYTES_PER_PIXEL; blit(src, line, dst, line, w*BYTES_PER_PIXEL, h); @@ -240,7 +240,7 @@ void Vmm::Virtio_gpu_control_request::_transfer_to_host_2d() uint32_t y = tth.read(); uint32_t w = tth.read(); uint32_t h = tth.read(); - addr_t off = tth.read(); + addr_t off = (addr_t)tth.read(); if (x + w > res.area.w() || y + h > res.area.h()) { response.write(Control_header::Type::ERR_INVALID_PARAMETER); @@ -250,7 +250,7 @@ void Vmm::Virtio_gpu_control_request::_transfer_to_host_2d() void * src = (void*)((addr_t)res.src_ds.local_addr() + off); void * dst = (void*)((addr_t)res.dst_ds.local_addr() + (y * res.area.w() + x) * BYTES_PER_PIXEL); - size_t line = res.area.w() * BYTES_PER_PIXEL; + uint32_t line = res.area.w() * BYTES_PER_PIXEL; blit(src, line, dst, line, w*BYTES_PER_PIXEL, h); diff --git a/repos/os/src/server/vmm/virtio_gpu.h b/repos/os/src/server/vmm/virtio_gpu.h index c85c8bf430..d7d5cdb930 100644 --- a/repos/os/src/server/vmm/virtio_gpu.h +++ b/repos/os/src/server/vmm/virtio_gpu.h @@ -34,7 +34,7 @@ class Vmm::Virtio_gpu_queue : public Virtio_split_queue { private: - Ring_index _used_idx; + Ring_index _used_idx {}; friend class Virtio_gpu_control_request; @@ -235,7 +235,8 @@ class Vmm::Virtio_gpu_control_request addr_t _desc_addr(unsigned i) { Descriptor d = _desc(i); - return _ram.local_address(d.address(), d.length()); + /* we only support 32-bit ram addresses by now */ + return _ram.local_address((addr_t)d.address(), d.length()); } Control_header _ctrl_hdr { _desc_addr(0) }; @@ -329,7 +330,8 @@ class Vmm::Virtio_gpu_device : public Virtio_device uint32_t w, uint32_t h) : Registry::Element(registry, *this), - Rect(Point((int)x,(int)y), Area((int)w,(int)h)) { } + Rect(Point((int)x,(int)y), Area((int)w,(int)h)), + id(id) { } using Rect::Rect; }; @@ -348,7 +350,7 @@ class Vmm::Virtio_gpu_device : public Virtio_device region_map.dataspace() }; Attached_ram_dataspace dst_ds { device._env.ram(), device._env.rm(), _size() }; - Registry scanouts; + Registry scanouts {}; Resource(Virtio_gpu_device & dev, uint32_t id, @@ -392,11 +394,11 @@ class Vmm::Virtio_gpu_device : public Virtio_device Register read(Address_range & range, Cpu&) override { - if (range.start == EVENTS_READ && range.size == 4) + if (range.start() == EVENTS_READ && range.size() == 4) return dev._mode_changed ? 1 : 0; /* we support no multi-head, just return 1 */ - if (range.start == SCANOUTS && range.size == 4) + if (range.start() == SCANOUTS && range.size() == 4) return 1; return 0; @@ -404,13 +406,15 @@ class Vmm::Virtio_gpu_device : public Virtio_device void write(Address_range & range, Cpu&, Register v) override { - if (range.start == EVENTS_CLEAR && range.size == 4 && v == 1) + if (range.start() == EVENTS_CLEAR && range.size() == 4 && v == 1) dev._mode_changed = false; } Configuration_area(Virtio_gpu_device & device) - : Mmio_register("GPU config area", Mmio_register::RO, 0x100, 16), - dev(device) { device.add(*this); } + : + Mmio_register("GPU config area", Mmio_register::RO, + 0x100, 16, device.registers()), + dev(device) { } } _config_area{ *this }; void _mode_change() @@ -448,15 +452,16 @@ class Vmm::Virtio_gpu_device : public Virtio_device const uint64_t size, unsigned irq, Cpu & cpu, - Mmio_bus & bus, + Space & bus, Ram & ram, + Virtio_device_list & list, Env & env, Heap & heap, Attached_ram_dataspace & ram_ds, Gui::Connection & gui) : Virtio_device(name, addr, size, - irq, cpu, bus, ram, GPU), + irq, cpu, bus, ram, list, GPU), _env(env), _heap(heap), _ram_ds(ram_ds), _gui(gui), _handler(cpu, env.ep(), *this, &Virtio_gpu_device::_mode_change) { diff --git a/repos/os/src/server/vmm/virtio_input.h b/repos/os/src/server/vmm/virtio_input.h index 5cb7ab3857..20d0e058aa 100644 --- a/repos/os/src/server/vmm/virtio_input.h +++ b/repos/os/src/server/vmm/virtio_input.h @@ -123,9 +123,9 @@ class Vmm::Virtio_input_device : public Virtio_device using namespace Linux_evdev; switch (_select) { - case ID_NAME: return _name.length() - 1; - case ID_SERIAL: return _serial.length() - 1; - case ID_DEVIDS: return _dev_id.length() - 1; + case ID_NAME: return (uint8_t)(_name.length() - 1); + case ID_SERIAL: return (uint8_t)(_serial.length() - 1); + case ID_DEVIDS: return (uint8_t)(_dev_id.length() - 1); case PROP_BITS: return 0; /* Unsupported */ case EV_BITS: switch (_sub_select) { @@ -143,7 +143,7 @@ class Vmm::Virtio_input_device : public Virtio_device return 0; } - Register _data(addr_t off) + Register _data(Register off) { using namespace Linux_evdev; @@ -179,32 +179,33 @@ class Vmm::Virtio_input_device : public Virtio_device Register read(Address_range & range, Cpu&) override { - if (range.start == SIZE) + if (range.start() == SIZE) return _size(); - if (range.start >= DATA && range.start < DATA_MAX) - return _data(range.start-DATA); + if (range.start() >= DATA && range.start() < DATA_MAX) + return _data(range.start()-DATA); error("Reading from virtio input config space ", - "at offset ", range.start, " is not allowed"); + "at offset ", range.start(), " is not allowed"); return 0; } void write(Address_range & range, Cpu&, Register v) override { - switch (range.start) { - case SELECT: _select = v; return; - case SUB_SELECT: _sub_select = v; return; + switch (range.start()) { + case SELECT: _select = (uint8_t)v; return; + case SUB_SELECT: _sub_select = (uint8_t)v; return; default: error("Writing to virtio input config space ", - "at offset ", range.start, " is not allowed"); + "at offset ", range.start(), " is not allowed"); } } Configuration_area(Virtio_input_device & device) - : Mmio_register("Input config area", - Mmio_register::RO, 0x100, 0xa4), - dev(device) { device.add(*this); } + : + Mmio_register("Input config area", Mmio_register::RO, + 0x100, 0xa4, device.registers()), + dev(device) { } } _config_area{ *this }; void _handle_input() @@ -285,6 +286,12 @@ class Vmm::Virtio_input_device : public Virtio_device enum Device_id { INPUT = 18 }; + /* + * Noncopyable + */ + Virtio_input_device(Virtio_input_device const &); + Virtio_input_device &operator = (Virtio_input_device const &); + public: Virtio_input_device(const char * const name, @@ -294,12 +301,13 @@ class Vmm::Virtio_input_device : public Virtio_device Cpu & cpu, Mmio_bus & bus, Ram & ram, + Virtio_device_list & list, Env & env, Heap & heap, Input::Session_client & input) : - Virtio_device(name, addr, size, - irq, cpu, bus, ram, INPUT), + Virtio_device(name, addr, size, irq, + cpu, bus, ram, list, INPUT), _env(env), _heap(heap), _input(input), _handler(cpu, env.ep(), *this, &Virtio_input_device::_handle_input) { diff --git a/repos/os/src/server/vmm/virtio_net.h b/repos/os/src/server/vmm/virtio_net.h index c2624d1c74..3b8405b63f 100644 --- a/repos/os/src/server/vmm/virtio_net.h +++ b/repos/os/src/server/vmm/virtio_net.h @@ -125,12 +125,12 @@ class Vmm::Virtio_net : public Virtio_device Register read(Address_range & range, Cpu&) override { - if (range.start > 5) return 0; + if (range.start() > 5) return 0; - return mac.addr[range.start]; + return mac.addr[range.start()]; } - void write(Address_range & range, Cpu&, Register v) override {} + void write(Address_range &, Cpu &, Register) override {} Config_area(Virtio_net & device, Nic::Mac_address & mac) : Reg(device, "ConfigArea", Mmio_register::RW, 0x100, 24), @@ -140,17 +140,18 @@ class Vmm::Virtio_net : public Virtio_device public: - Virtio_net(const char * const name, - const uint64_t addr, - const uint64_t size, - unsigned irq, - Cpu &cpu, - Mmio_bus &bus, - Ram &ram, - Genode::Env &env) + Virtio_net(const char * const name, + const uint64_t addr, + const uint64_t size, + unsigned irq, + Cpu & cpu, + Mmio_bus & bus, + Ram & ram, + Virtio_device_list & list, + Genode::Env & env) : - Virtio_device(name, addr, size, - irq, cpu, bus, ram, NIC), + Virtio_device(name, addr, size, irq, + cpu, bus, ram, list, NIC), _env(env), _handler(cpu, _env.ep(), *this, &Virtio_net::_handle) { diff --git a/repos/os/src/server/vmm/vm.cc b/repos/os/src/server/vmm/vm.cc index 11ad8a4c9b..e9ca4668df 100644 --- a/repos/os/src/server/vmm/vm.cc +++ b/repos/os/src/server/vmm/vm.cc @@ -118,36 +118,38 @@ Vm::Vm(Genode::Env & env, Heap & heap, Config & config) _config.for_each_virtio_device([&] (Config::Virtio_device const & dev) { switch (dev.type) { case Config::Virtio_device::CONSOLE: - _device_list.insert(new (_heap) + new (_heap) Virtio_console(dev.name.string(), (uint64_t)dev.mmio_start, dev.mmio_size, dev.irq, boot_cpu(), - _bus, _ram, env)); + _bus, _ram, _device_list, env); return; case Config::Virtio_device::NET: - _device_list.insert(new (_heap) + new (_heap) Virtio_net(dev.name.string(), (uint64_t)dev.mmio_start, dev.mmio_size, dev.irq, boot_cpu(), _bus, _ram, - env)); + _device_list, env); return; case Config::Virtio_device::BLOCK: - _device_list.insert(new (_heap) + new (_heap) Virtio_block_device(dev.name.string(), (uint64_t)dev.mmio_start, dev.mmio_size, dev.irq, boot_cpu(), - _bus, _ram, env, heap)); + _bus, _ram, _device_list, env, heap); return; case Config::Virtio_device::GPU: if (!_gui.constructed()) _gui.construct(env); - _device_list.insert(new (_heap) + new (_heap) Virtio_gpu_device(dev.name.string(), (uint64_t)dev.mmio_start, dev.mmio_size, dev.irq, boot_cpu(), - _bus, _ram, env, heap, _vm_ram, *_gui)); + _bus, _ram, _device_list, env, + heap, _vm_ram, *_gui); return; case Config::Virtio_device::INPUT: if (!_gui.constructed()) _gui.construct(env); - _device_list.insert(new (_heap) + new (_heap) Virtio_input_device(dev.name.string(), (uint64_t)dev.mmio_start, dev.mmio_size, dev.irq, boot_cpu(), - _bus, _ram, env, heap, *_gui->input())); + _bus, _ram, _device_list, env, + heap, *_gui->input()); default: return; }; diff --git a/repos/os/src/server/vmm/vm.h b/repos/os/src/server/vmm/vm.h index ea2a493a90..19e1f3965c 100644 --- a/repos/os/src/server/vmm/vm.h +++ b/repos/os/src/server/vmm/vm.h @@ -58,10 +58,10 @@ class Vmm::Vm _config.ram_size(), CACHED }; Ram _ram { RAM_START, _config.ram_size(), (addr_t)_vm_ram.local_addr()}; - Mmio_bus _bus; + Mmio_bus _bus {}; Gic _gic; - List _cpu_list; - List _device_list; + List _cpu_list {}; + List _device_list {}; Pl011 _uart; Constructible _initrd_rom {};