diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc
deleted file mode 100644
index 3da9f74d87..0000000000
--- a/repos/base/run/platform_drv.inc
+++ /dev/null
@@ -1,261 +0,0 @@
-proc have_platform_drv {} {
- return [expr [have_board pc]]
-}
-
-
-##
-# Return name of the USB driver binary
-#
-proc usb_host_drv_binary { } {
- if {[have_board rpi]} { return legacy_rpi_usb_host_drv }
- if {[have_board imx6q_sabrelite]} { return legacy_imx6q_sabrelite_usb_host_drv }
- if {[have_board pc]} { return pc_usb_host_drv }
- return no_usb_drv_available
-}
-
-
-##
-# Return name of the audio driver binary
-#
-proc audio_drv_binary { } {
- if {[have_board linux]} { return linux_audio_drv }
- if {[have_board pc]} { return pci_audio_drv }
- return no_audio_drv_available
-}
-
-##
-# Return attributes of the audio driver's node
-#
-proc audio_drv_start_attr { } {
- if {[have_board linux]} { return {ld="no"} }
- return ""
-}
-
-proc acpi_drv_name { } {
- global use_acpica_as_acpi_drv
- if {[info exists use_acpica_as_acpi_drv] && $use_acpica_as_acpi_drv} {
- return acpica }
-
- return acpi_drv
-}
-
-proc platform_drv_build_components {} {
- set drv_build_components ""
- if {[have_board pc]} {
- lappend drv_build_components drivers/platform/legacy/x86
- lappend drv_build_components server/report_rom
- if {[acpi_drv_name] eq "acpi_drv"} {
- lappend drv_build_components drivers/acpi
- }
- if {[acpi_drv_name] eq "acpica"} {
- lappend drv_build_components app/acpica
- }
- }
- return $drv_build_components
-}
-
-
-proc append_platform_drv_build_components {} {
- global build_components
- append build_components { } [platform_drv_build_components]
-}
-
-proc platform_drv_binary {} {
- if {[have_board pc]} { return legacy_pc_platform_drv }
- return no_platform_drv_available
-}
-
-proc platform_drv_boot_modules {} {
- set drv_boot_modules ""
- lappend_if [have_platform_drv] drv_boot_modules [platform_drv_binary]
-
- if {[have_board pc]} {
- lappend drv_boot_modules report_rom
- lappend drv_boot_modules [acpi_drv_name]
- }
-
- return $drv_boot_modules
-}
-
-proc append_platform_drv_boot_modules {} {
- global boot_modules
- append boot_modules { } [platform_drv_boot_modules]
-}
-
-
-proc platform_drv_policy {} {
-
- if {![have_board pc]} {
- return {}
- }
-
- set drv_policy ""
-
- if {[acpi_drv_name] eq "acpica"} {
- append drv_policy {
- }
- }
-
- append drv_policy {
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
- return $drv_policy
-}
-
-
-proc platform_drv_priority {} { return "" }
-proc platform_drv_add_routing {} {
-
- if {[acpi_drv_name] eq "acpica"} {
- return {
- }
- }
-
- return ""
-}
-
-
-proc platform_drv_config_config {} {
- if {[acpi_drv_name] eq "acpica"} {
- return {
- }
- }
-
- return {}
-}
-
-
-proc platform_drv_config {} {
- set drv_config ""
-
- if {[have_board pc]} {
-
- append drv_config {
-
- }
-
- if {[acpi_drv_name] eq "acpica"} {
- append drv_config {
-
- }
- } else {
- append drv_config {
- }
- }
-
- append drv_config {
-
-
-
-
-
-
- }
-
- append_if [expr {[acpi_drv_name] eq "acpica"}] drv_config {
-
-
-
-
- }
-
- append drv_config {
-
-
-
- }
-
- append drv_config "
- "
-
- append drv_config {
-
-
-
-
-
-
-
-
-
- }
-
- append_if [expr {[acpi_drv_name] eq "acpica"}] drv_config {
- }
-
- append drv_config {
-
-
-
-
-
-
-
- }
-
- }
-
- if {[have_platform_drv]} {
-
- append drv_config {
-
-
-
-
- }
-
- append_if [have_board pc] drv_config {
- }
-
- append_if [have_spec arm] drv_config {
- }
-
- append drv_config {
-
- }
-
- append drv_config "[platform_drv_add_routing]"
-
- append_if [have_board pc] drv_config {
- }
-
- append_if [expr [have_board pc]] drv_config {
- }
-
- append_if [expr [have_board rpi] || [have_board pc]] drv_config {
- }
-
- append drv_config {
-
- }
-
- append drv_config [platform_drv_config_config]
- append drv_config [platform_drv_policy]
-
- append drv_config {
-
- }
-
- }
-
- return $drv_config
-}
-
-
-proc append_platform_drv_config {} {
- global config
- append config [platform_drv_config]
- return $config
-}
diff --git a/repos/os/include/legacy/x86/platform_device/capability.h b/repos/os/include/legacy/x86/platform_device/capability.h
deleted file mode 100644
index 6fc9cd1d5c..0000000000
--- a/repos/os/include/legacy/x86/platform_device/capability.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * \brief Device capability type
- * \author Norman Feske
- * \date 2008-08-16
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#pragma once
-
-#include
-#include
-
-namespace Platform { typedef Genode::Capability Device_capability; }
diff --git a/repos/os/include/legacy/x86/platform_device/client.h b/repos/os/include/legacy/x86/platform_device/client.h
deleted file mode 100644
index 5883ec6913..0000000000
--- a/repos/os/include/legacy/x86/platform_device/client.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * \brief Client-side interface for PCI device
- * \author Norman Feske
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__CLIENT_H_
-#define _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__CLIENT_H_
-
-#include
-#include
-#include
-#include
-
-namespace Platform { struct Device_client; }
-
-
-struct Platform::Device_client : public Rpc_client
-{
- Device_client(Device_capability device)
- : Rpc_client(device) { }
-
- void bus_address(unsigned char *bus, unsigned char *dev, unsigned char *fn) override {
- call(bus, dev, fn); }
-
- unsigned short vendor_id() override {
- return call(); }
-
- unsigned short device_id() override {
- return call(); }
-
- unsigned class_code() override {
- return call(); }
-
- Resource resource(int resource_id) override {
- return call(resource_id); }
-
- unsigned config_read(unsigned char address, Access_size size) override {
- return call(address, size); }
-
- void config_write(unsigned char address, unsigned value, Access_size size) override {
- call(address, value, size); }
-
- Irq_session_capability irq(uint8_t id) override {
- return call(id); }
-
- Io_port_session_capability io_port(uint8_t id) override {
- return call(id); }
-
- Io_mem_session_capability io_mem(uint8_t id,
- Cache cache = Cache::UNCACHED,
- addr_t offset = 0,
- size_t size = ~0UL) override {
- return call(id, cache, offset, size); }
-};
-
-#endif /* _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__CLIENT_H_ */
diff --git a/repos/os/include/legacy/x86/platform_device/device.h b/repos/os/include/legacy/x86/platform_device/device.h
deleted file mode 100644
index 06f2657fd8..0000000000
--- a/repos/os/include/legacy/x86/platform_device/device.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * \brief Abstract platform device interface
- * \author Alexander Boettcher
- * \date 2015-03-15
- */
-
-/*
- * Copyright (C) 2015-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__DEVICE_H_
-#define _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__DEVICE_H_
-
-#include
-#include
-#include
-#include
-
-namespace Platform { class Abstract_device; }
-
-struct Platform::Abstract_device : Genode::Interface
-{
- /**
- * Get IRQ session capability
- */
- virtual Genode::Irq_session_capability irq(Genode::uint8_t) = 0;
-
- /**
- * Get IO mem session capability of specified resource id
- */
- virtual Genode::Io_mem_session_capability io_mem(Genode::uint8_t, Genode::Cache,
- Genode::addr_t, Genode::size_t) = 0;
-};
-
-#endif /* _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__DEVICE_H_ */
diff --git a/repos/os/include/legacy/x86/platform_device/platform_device.h b/repos/os/include/legacy/x86/platform_device/platform_device.h
deleted file mode 100644
index e628a5d689..0000000000
--- a/repos/os/include/legacy/x86/platform_device/platform_device.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * \brief PCI-device interface
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
-#define _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* os includes */
-#include
-
-namespace Platform {
-
- using namespace Genode;
-
- struct Device;
-}
-
-
-struct Platform::Device : Platform::Abstract_device
-{
- /*********************
- ** Exception types **
- *********************/
-
- class Resource
- {
- private:
-
- unsigned _bar = 0; /* content of base-address register */
- unsigned _size = 0; /* resource size */
-
- public:
-
- /**
- * Resource type, either port I/O resource or memory-mapped resource
- */
- enum Type { IO, MEMORY, INVALID };
-
- /**
- * Default constructor
- */
- Resource() { }
-
- /**
- * Constructor
- *
- * \param bar content of base-address register
- * \param size resource size
- *
- * This constructor is only used by the PCI bus driver
- * that implements the server-side of the the PCI session.
- * If bar is set to zero, the constructed resource description
- * represents an INVALID resource.
- */
- Resource(unsigned bar, unsigned size)
- : _bar(bar), _size(size) { }
-
- /**
- * Return base address of resource
- */
- unsigned base() const
- {
- /*
- * Mask out the resource-description bits of the base
- * address register. I/O resources use the lowest 2
- * bits, memory resources use the lowest 4 bits.
- */
- return _bar & ((type() == IO) ? ~3 : ~15);
- }
-
- /**
- * Return resource size in bytes
- */
- unsigned size() const { return _size; }
-
- /**
- * Return true if resource is prefetchable memory
- */
- bool prefetchable() const
- {
- return type() == MEMORY && (_bar & (1 << 3));
- }
-
- /**
- * Return resource type
- */
- Type type() const
- {
- if (_bar == 0)
- return INVALID;
-
- return (_bar & 1) ? IO : MEMORY;
- }
-
- /**
- * Return raw register content
- */
- unsigned bar() const { return _bar; }
- };
-
- enum { NUM_RESOURCES = 6 };
-
- virtual ~Device() { }
-
- /**
- * Return bus, device, and function number of the device
- */
- virtual void bus_address(unsigned char *bus, unsigned char *dev,
- unsigned char *fn) = 0;
-
- /**
- * Return vendor ID obtained from the PCI config space
- */
- virtual unsigned short vendor_id() = 0;
-
- /**
- * Return device ID obtained from the PCI config space
- */
- virtual unsigned short device_id() = 0;
-
- /**
- * Return device class code from the PCI config space
- */
- virtual unsigned class_code() = 0;
-
- /**
- * Query PCI-resource information
- *
- * \param resource_id index of according PCI resource of the device
- *
- * \return resource description
- * \retval INVALID the supplied resource ID is invalid
- */
- virtual Resource resource(int resource_id) = 0;
-
- /**
- * Access size for operations directly accessing the config space
- */
- enum Access_size { ACCESS_8BIT, ACCESS_16BIT, ACCESS_32BIT };
-
- /**
- * Read configuration space
- */
- virtual unsigned config_read(unsigned char address, Access_size size) = 0;
-
- /**
- * Write configuration space
- *
- * \throw Out_of_ram
- * \throw Out_of_caps
- */
- virtual void config_write(unsigned char address, unsigned value,
- Access_size size) = 0;
-
- /**
- * Query Io_port of specified bar
- *
- * \param id index of according PCI resource of the device
- *
- * \throw Out_of_ram
- * \throw Out_of_caps
- */
- virtual Io_port_session_capability io_port(uint8_t id) = 0;
-
- /*
- * The base classes are defined as follows:
- *
- * 0x00 | legacy device
- * 0x01 | mass-storage controller
- * 0x02 | network controller
- * 0x03 | display controller
- * 0x04 | multimedia device
- * 0x05 | memory controller
- * 0x06 | bridge device
- * 0x07 | simple-communication controller
- * 0x08 | base-system peripheral
- * 0x09 | input device
- * 0x0a | docking station
- * 0x0b | processor
- * 0x0c | serial bus controller
- * 0x0d | wireless controller
- * 0x0e | intelligent I/O controller
- * 0x0f | satellite-communications controller
- * 0x10 | encryption/decryption controller
- * 0x11 | data-acquisition and signal-processing controller
- * 0x12 | reserved
- * ... |
- * 0xff | device does not fit in any of the defined classes
- */
-
- unsigned base_class() { return class_code() >> 16; }
- unsigned sub_class() { return (class_code() >> 8) & 0xff; }
-
- /**
- * Convenience method to translate a PCI physical BAR id to a Genode
- * virtual one usable with the io_port and io_mem methods. The virtual id
- * is solely valid for the specific BAR type.
- */
- uint8_t phys_bar_to_virt(uint8_t phys_bar)
- {
- uint8_t virt_io_port = 0, virt_io_mem = 0;
-
- for (unsigned i = 0; i < phys_bar; i++) {
- Resource::Type type = resource(i).type();
- if (type == Resource::Type::IO)
- virt_io_port ++;
- else if (type == Resource::Type::MEMORY)
- virt_io_mem ++;
- }
-
- Resource::Type type = resource(phys_bar).type();
- return type == Resource::Type::IO ? virt_io_port : virt_io_mem;
- }
-
- /*********************
- ** RPC declaration **
- *********************/
-
- GENODE_RPC(Rpc_bus_address, void, bus_address,
- unsigned char *, unsigned char *, unsigned char *);
- GENODE_RPC(Rpc_vendor_id, unsigned short, vendor_id);
- GENODE_RPC(Rpc_device_id, unsigned short, device_id);
- GENODE_RPC(Rpc_class_code, unsigned, class_code);
- GENODE_RPC(Rpc_resource, Resource, resource, int);
- GENODE_RPC(Rpc_config_read, unsigned, config_read,
- unsigned char, Access_size);
- GENODE_RPC_THROW(Rpc_config_write, void, config_write,
- GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
- unsigned char, unsigned, Access_size);
- GENODE_RPC(Rpc_irq, Irq_session_capability, irq, uint8_t);
- GENODE_RPC_THROW(Rpc_io_port, Io_port_session_capability, io_port,
- GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
- uint8_t);
- GENODE_RPC_THROW(Rpc_io_mem, Io_mem_session_capability, io_mem,
- GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
- uint8_t, Cache, addr_t, size_t);
-
- GENODE_RPC_INTERFACE(Rpc_bus_address, Rpc_vendor_id, Rpc_device_id,
- Rpc_class_code, Rpc_resource, Rpc_config_read,
- Rpc_config_write, Rpc_irq, Rpc_io_port, Rpc_io_mem);
-};
-
-#endif /* _INCLUDE__LEGACY__X86__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ */
diff --git a/repos/os/include/legacy/x86/platform_session/capability.h b/repos/os/include/legacy/x86/platform_session/capability.h
deleted file mode 100644
index d6b128b020..0000000000
--- a/repos/os/include/legacy/x86/platform_session/capability.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * \brief Platform session capability type
- * \author Stefan Kalkowski
- * \date 2013-04-29
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__LEGACY__X86__PLATFORM_SESSION__CAPABILITY_H_
-#define _INCLUDE__LEGACY__X86__PLATFORM_SESSION__CAPABILITY_H_
-
-#include
-#include
-
-namespace Platform { typedef Genode::Capability Session_capability; }
-
-#endif /* _INCLUDE__LEGACY__X86__PLATFORM_SESSION__CAPABILITY_H_ */
diff --git a/repos/os/include/legacy/x86/platform_session/client.h b/repos/os/include/legacy/x86/platform_session/client.h
deleted file mode 100644
index e3ad1016cd..0000000000
--- a/repos/os/include/legacy/x86/platform_session/client.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * \brief Client-side PCI-session interface
- * \author Norman Feske
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__LEGACY__X86__PLATFORM_SESSION_H_
-#define _INCLUDE__LEGACY__X86__PLATFORM_SESSION_H_
-
-#include
-#include
-#include
-
-namespace Platform { struct Client; }
-
-
-struct Platform::Client : public Rpc_client
-{
- Client(Session_capability session) : Rpc_client(session) { }
-
- Device_capability first_device(unsigned device_class = 0,
- unsigned class_mask = 0) override {
- return call(device_class, class_mask); }
-
- Device_capability next_device(Device_capability prev_device,
- unsigned device_class = 0,
- unsigned class_mask = 0) override {
- return call(prev_device, device_class, class_mask); }
-
- void release_device(Device_capability device) override {
- call(device); }
-
- Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {
- return call(size, cache); }
-
- void free_dma_buffer(Ram_dataspace_capability cap) override {
- call(cap); }
-
- addr_t dma_addr(Ram_dataspace_capability cap) override {
- return call(cap); }
-
- Device_capability device(Device_name const &device) override {
- return call(device); }
-};
-
-#endif /* _INCLUDE__LEGACY__X86__PLATFORM_SESSION_H_ */
diff --git a/repos/os/include/legacy/x86/platform_session/connection.h b/repos/os/include/legacy/x86/platform_session/connection.h
deleted file mode 100644
index e0943e91c2..0000000000
--- a/repos/os/include/legacy/x86/platform_session/connection.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * \brief Connection to Platform service
- * \author Norman Feske
- * \date 2008-08-22
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__LEGACY__X86__PLATFORM_SESSION__CONNECTION_H_
-#define _INCLUDE__LEGACY__X86__PLATFORM_SESSION__CONNECTION_H_
-
-#include
-#include
-#include
-
-namespace Platform { struct Connection; }
-
-
-struct Platform::Connection : Genode::Connection, Client
-{
- /**
- * Constructor
- */
- Connection(Env &env)
- :
- Genode::Connection(env, session(env.parent(),
- "ram_quota=16K, cap_quota=%u",
- CAP_QUOTA)),
- Client(cap())
- { }
-
- template
- auto with_upgrade(FUNC func) -> decltype(func())
- {
- return retry(
- [&] () {
- return retry(
- [&] () { return func(); },
- [&] () { this->upgrade_caps(2); });
- },
- [&] () { this->upgrade_ram(4096); }
- );
- }
-};
-
-#endif /* _INCLUDE__LEGACY__X86__PLATFORM_SESSION__CONNECTION_H_ */
diff --git a/repos/os/include/legacy/x86/platform_session/platform_session.h b/repos/os/include/legacy/x86/platform_session/platform_session.h
deleted file mode 100644
index d8ba9a6028..0000000000
--- a/repos/os/include/legacy/x86/platform_session/platform_session.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * \brief Platform session interface
- * \author Norman Feske
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _INCLUDE__LEGACY__X86__PLATFORM_SESSION__PLATFORM_SESSION_H_
-#define _INCLUDE__LEGACY__X86__PLATFORM_SESSION__PLATFORM_SESSION_H_
-
-/* Genode includes */
-#include
-#include
-#include
-
-/* os includes */
-#include
-#include
-
-namespace Platform { struct Session; }
-
-
-struct Platform::Session : Genode::Session
-{
- /**
- * \noapi
- */
- static const char *service_name() { return "Platform"; }
-
- enum { RAM_QUOTA = 16 * 1024, CAP_QUOTA = 2 };
-
- virtual ~Session() { }
-
- /**
- * Find first accessible device
- */
- virtual Device_capability first_device(unsigned, unsigned) = 0;
-
- /**
- * Find next accessible device
- *
- * \param prev_device previous device
- *
- * The 'prev_device' argument is used to iterate through all
- * devices.
- */
- virtual Device_capability next_device(Device_capability prev_device,
- unsigned, unsigned) = 0;
-
- /**
- * Free server-internal data structures representing the device
- *
- * Use this method to relax the heap partition of your PCI session.
- */
- virtual void release_device(Device_capability device) = 0;
-
- typedef Rpc_in_buffer<8> Device_name;
-
- /**
- * Provide non-PCI device known by unique name
- */
- virtual Device_capability device(Device_name const &string) = 0;
-
- /**
- * Allocate memory suitable for DMA
- */
- virtual Ram_dataspace_capability alloc_dma_buffer(size_t, Cache) = 0;
-
- /**
- * Free previously allocated DMA memory
- */
- virtual void free_dma_buffer(Ram_dataspace_capability) = 0;
-
- /**
- * Return the bus address of the previously allocated DMA memory
- */
- virtual addr_t dma_addr(Ram_dataspace_capability) = 0;
-
- /*********************
- ** RPC declaration **
- *********************/
-
- GENODE_RPC_THROW(Rpc_first_device, Device_capability, first_device,
- GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
- unsigned, unsigned);
- GENODE_RPC_THROW(Rpc_next_device, Device_capability, next_device,
- GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
- Device_capability, unsigned, unsigned);
- GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
- GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability,
- alloc_dma_buffer,
- GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
- size_t, Cache);
- GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer,
- Ram_dataspace_capability);
- GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr, Ram_dataspace_capability);
- GENODE_RPC_THROW(Rpc_device, Device_capability, device,
- GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
- Device_name const &);
-
- GENODE_RPC_INTERFACE(Rpc_first_device, Rpc_next_device,
- Rpc_release_device, Rpc_alloc_dma_buffer,
- Rpc_free_dma_buffer, Rpc_dma_addr, Rpc_device);
-};
-
-#endif /* _INCLUDE__LEGACY__X86__PLATFORM_SESSION__PLATFORM_SESSION_H_ */
diff --git a/repos/os/recipes/api/platform_session/content.mk b/repos/os/recipes/api/platform_session/content.mk
index eab9147ce0..ea809d6d40 100644
--- a/repos/os/recipes/api/platform_session/content.mk
+++ b/repos/os/recipes/api/platform_session/content.mk
@@ -1,9 +1,3 @@
-INCLUDE_SUB_DIRS := platform_session \
- legacy/x86/platform_session \
- legacy/x86/platform_device
-
-INCLUDE_DIRS := $(addprefix include/,$(INCLUDE_SUB_DIRS))
-
-MIRRORED_FROM_REP_DIR := $(INCLUDE_DIRS)
+MIRRORED_FROM_REP_DIR := include/platform_session
include $(REP_DIR)/recipes/api/session.inc
diff --git a/repos/os/src/drivers/platform/legacy/x86/README b/repos/os/src/drivers/platform/legacy/x86/README
deleted file mode 100644
index 6391dc0346..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/README
+++ /dev/null
@@ -1,207 +0,0 @@
-This directory contains the implementation of Genode's x86 platform driver.
-
-Behavior
---------
-
-On startup the driver scans the PCI bus hierarchy and stores the found devices.
-Per client a policy must be configured that states which client can
-access certain devices to form a virtual pci bus per client. The client may
-iterate through the virtual pci bus using the 'first' and 'next' methods of
-the platform_session interface to discover all available devices of the virtual
-bus. Non PCI devices may be discovered by using 'device' of the
-platform_session interface. As a result of the discovery a client obtains a
-device capability.
-
-With the device capability the resources of the devices can be obtained, e.g.
-io_port, io_mem and irq of the platform_device interface.
-
-Policy usage
-------------
-
-A policy may contain several nodes describing several devices. The entries of
-a policy may describe PCI devices as non PCI devices. A PCI device is
-explicitly configured by the triple 'bus', 'device', 'function':
-
-!
-!
-! ...
-!
-!
-!
-!
-!
-!
-! ...
-
-or more fuzzy by a device class alias:
-
-!
-!
-! ...
-!
-!
-!
-!
-!
-! ...
-
-
-Non PCI devices, as the PS2 controller are named by a "device" node in the policy:
-
-!
-!
-!
-!
-!
-!
-!
-!
-! ...
-!
-!
-! ...
-
-The managing_system attribute is evaluated by init. If set to "yes" it
-permits a component, the platform driver, to restrict the allocation of memory to
-specific physical RAM ranges. The platform driver uses this feature to ensure that
-the allocation of DMA capable memory consider several restrictions. For
-example, some drivers, as the UHCI controller, requires a
-physical memory address below 4G. Another example is that on 32bit hosts
-physical to virtual identical mappings of DMA memory for the device_pd
-(required when IOMMU is used) must be below the kernel memory boundary (3G).
-On some systems, e.g., base-hw kernel on certain ARM platforms, it allows the
-platform driver to call system management firmware via kernel syscalls.
-
-The platform driver waits on startup on the first valid ACPI report, typically
-provided dynamically by the acpi driver.
-The report contains further information about the hardware the platform driver can
-not discover (e.g. IRQ re-routing information, PCI ECAM/MMCONF information).
-
-A specific route to a report_rom service named 'acpi_report_rom' looks as
-in the following:
-
-!
-! ...
-!
-!
-!
-!
-! ...
-!
-! ...
-
-Synchronize ACPI startup and platform driver
---------------------------------------------
-
-If the config attribute 'acpi_ready' is set to 'yes', the platform driver
-monitors a ROM in XML format named 'acpi_ready'.
-
-!
-!
-
-The platform driver will announce its service not as 'Platform', but instead
-as 'Acpi' first.
-
-An ACPI application like acpica can connect to the platform driver and may
-reconfigure hardware devices according to the ACPI table findings. If the
-system state changes to "acpi_ready in the XML ROM 'acpi_ready':
-
-!
-
-the platform driver will announce the platform session as 'Platform', so
-that drivers may start to operate with the platform driver.
-
-Supported PCI class aliases
----------------------------
-
-The following class names are supported which correspond to the
-specified PCI base class (B), sub class (S) and programming interface
-(P) combinations. ('-' matches all devices in the category)
-
-alias B S P
-
-ALL - - -
-AHCI 01 06 -
-AUDIO 04 01 -
-ETHERNET 02 00 -
-HDAUDIO 04 03 -
-ISABRIDGE 06 01 -
-NVME 01 08 02
-USB 0c 03 00 10 20 30
-USB4 0c 03 40
-VGA 03 00 00
-WIFI 02 80 -
-
-Fixups for insufficient PCI BAR configuration
----------------------------------------------
-
-If PCI devices happen to miss complete configuration after boot, the
-platform driver supports nodes for concrete devices
-(specified by bus-device-functions tuples). As depicted below, the
- node instructs the platform driver to remap BAR id 0 to address
-0x4017002000, which amends the BIOS configuration and is stringently
-required for BARs with address 0.
-
-!
-!
-!
-
-
-Supported non PCI devices
--------------------------
-
-The driver provides for the PS2 and PIT device the IO_PORT and IRQ resources.
-
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
-!
diff --git a/repos/os/src/drivers/platform/legacy/x86/acpi_devices.cc b/repos/os/src/drivers/platform/legacy/x86/acpi_devices.cc
deleted file mode 100644
index ae1cf74d85..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/acpi_devices.cc
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * \brief ACPI device information from config
- * \author Christian Helmuth
- * \date 2022-05-16
- */
-
-/*
- * Copyright (C) 2022 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include "acpi_devices.h"
-
-namespace Platform { namespace Acpi {
- struct Device_impl;
-
- typedef String<16> Str;
-}}
-
-
-void Platform::Acpi::Device::Resource::print(Output &o) const
-{
- using Genode::print;
- switch (type) {
- case Type::IRQ:
- print(o, "IRQ [", base);
- print(o, " ", irq == Irq::EDGE ? "edge" : irq == Irq::LEVEL_LOW ? "level-low" : "level-high");
- print(o, "]");
- break;
- case Type::IOMEM:
- print(o, "IOMEM ");
- print(o, "[", Hex(base, Hex::Prefix::OMIT_PREFIX, Hex::PAD));
- print(o, "-", Hex(base + (size - 1), Hex::Prefix::OMIT_PREFIX, Hex::PAD));
- print(o, "]");
- break;
- case Type::IOPORT:
- print(o, "IOPORT ");
- print(o, "[", Hex((unsigned short)base, Hex::Prefix::OMIT_PREFIX, Hex::PAD));
- print(o, "-", Hex((unsigned short)(base + (size - 1)), Hex::Prefix::OMIT_PREFIX, Hex::PAD));
- print(o, "]");
- break;
- }
-}
-
-
-class Platform::Acpi::Device_impl : private Registry::Element,
- public Platform::Acpi::Device
-{
- private:
-
- Hid _hid; /* ACPI Spec 6.1.5 Hardware ID */
-
- struct Resource_element : Registry::Element
- {
- unsigned id;
- Resource res;
-
- Resource_element(Registry ®istry,
- unsigned id,
- Resource res)
- :
- Registry::Element(registry, *this),
- id(id), res(res)
- { }
- };
-
- Registry _resource_registry { };
-
- Resource_result _lookup_resource(Resource::Type type, unsigned const id) const
- {
- Resource const *res = nullptr;
- _resource_registry.for_each([&] (Resource_element const &e) {
- if (e.res.type == type && e.id == id)
- res = &e.res;
- });
-
- if (res)
- return *res;
- else
- return Invalid_resource { };
- }
-
- unsigned _max_irq_id { 0 };
- unsigned _max_iomem_id { 0 };
- unsigned _max_ioport_id { 0 };
-
- public:
-
- Device_impl(Registry ®istry,
- Allocator &heap, Xml_node config)
- :
- Registry::Element(registry, *this),
- _hid(config.attribute_value("name", Hid("ACPI0000")))
- {
- config.for_each_sub_node("irq", [&] (Xml_node node) {
- auto irq = [&] (Str const &mode, Str const &polarity) {
- if (mode == "level") {
- if (polarity == "high")
- return Resource::Irq::LEVEL_HIGH;
- else
- return Resource::Irq::LEVEL_LOW;
- } else {
- return Resource::Irq::EDGE;
- }
- };
- new (heap)
- Resource_element {
- _resource_registry,
- _max_irq_id++,
- Resource {
- .type = Resource::Type::IRQ,
- .base = node.attribute_value("number", addr_t(0)),
- .irq = irq(node.attribute_value("mode", Str("unchanged")),
- node.attribute_value("polarity", Str("unchanged"))) } };
- });
- config.for_each_sub_node("io_mem", [&] (Xml_node node) {
- new (heap)
- Resource_element {
- _resource_registry,
- _max_iomem_id++,
- Resource {
- .type = Resource::Type::IOMEM,
- .base = node.attribute_value("address", addr_t(0)),
- .size = node.attribute_value("size", size_t(0)) } };
- });
- config.for_each_sub_node("io_port_range", [&] (Xml_node node) {
- new (heap)
- Resource_element {
- _resource_registry,
- _max_ioport_id++,
- Resource {
- .type = Resource::Type::IOPORT,
- .base = node.attribute_value("address", addr_t(0)),
- .size = node.attribute_value("size", size_t(0)) } };
- });
- }
-
- ~Device_impl() { error("unexpected call of ", __func__); }
-
- /* Platform::Acpi::Device interface */
-
- Hid hid() const override { return _hid; }
-
- Resource_result resource(unsigned idx) const override
- {
- /*
- * Index of all IOMEM and IOPORT resources - no IRQ!
- *
- * first _max_iomem_id IOMEM, then _max_ioport_id IOPORT
- */
- if (idx < _max_iomem_id)
- return iomem(idx);
- else if (idx < _max_iomem_id + _max_ioport_id)
- return ioport(idx - _max_iomem_id);
- else
- return Invalid_resource { };
- }
-
- Resource_result irq(unsigned id) const override
- {
- return _lookup_resource(Resource::Type::IRQ, id);
- }
-
- Resource_result iomem(unsigned id) const override
- {
- return _lookup_resource(Resource::Type::IOMEM, id);
- }
-
- Resource_result ioport(unsigned id) const override
- {
- return _lookup_resource(Resource::Type::IOPORT, id);
- }
-};
-
-
-Platform::Acpi::Device_registry::Lookup_result
-Platform::Acpi::Device_registry::lookup(Platform::Acpi::Device::Hid hid) const
-{
- Device const *found = nullptr;
-
- this->for_each([&] (Device const &device) {
- if (device.hid() == hid)
- found = &device;
- });
-
- if (found)
- return found;
- else
- return Lookup_failed { };
-}
-
-
-void Platform::Acpi::Device_registry::init_devices(Allocator &heap, Xml_node config)
-{
- /* init only once */
- if (_initialized)
- return;
-
- config.for_each_sub_node("device", [&] (Xml_node node) {
- if (node.attribute_value("type", Str()) == "acpi")
- new (heap) Device_impl(*this, heap, node);
- });
-
- _initialized = true;
-}
diff --git a/repos/os/src/drivers/platform/legacy/x86/acpi_devices.h b/repos/os/src/drivers/platform/legacy/x86/acpi_devices.h
deleted file mode 100644
index 89e7aa98e3..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/acpi_devices.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * \brief ACPI device information from config
- * \author Christian Helmuth
- * \date 2022-05-16
- */
-
-/*
- * Copyright (C) 2022 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include
-#include
-#include
-#include
-
-
-namespace Platform { namespace Acpi {
- using namespace Genode;
-
- class Device;
-
- class Device_registry;
-} }
-
-
-struct Platform::Acpi::Device : Interface
-{
- typedef String<10> Hid; /* ACPI Spec 6.1.5 Hardware ID */
-
- struct Resource
- {
- enum class Type { IRQ, IOMEM, IOPORT };
-
- enum class Irq { EDGE, LEVEL_LOW, LEVEL_HIGH };
-
- Type type;
- addr_t base;
-
- union {
- size_t size;
- Irq irq;
- };
-
- void print(Output &o) const;
- };
-
- enum struct Invalid_resource { };
- typedef Attempt Resource_result;
-
- virtual Hid hid() const = 0;
- virtual Resource_result resource(unsigned idx) const = 0;
- virtual Resource_result irq(unsigned id) const = 0;
- virtual Resource_result iomem(unsigned id) const = 0;
- virtual Resource_result ioport(unsigned id) const = 0;
-};
-
-
-struct Platform::Acpi::Device_registry : Genode::Registry
-{
- bool _initialized { false };
-
- void init_devices(Allocator &heap, Xml_node config);
-
- enum struct Lookup_failed { };
- typedef Attempt Lookup_result;
-
- Lookup_result lookup(Device::Hid name) const;
-};
diff --git a/repos/os/src/drivers/platform/legacy/x86/device_pd.cc b/repos/os/src/drivers/platform/legacy/x86/device_pd.cc
deleted file mode 100644
index 455a9f3342..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/device_pd.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * \brief Pci device protection domain service for platform driver
- * \author Alexander Boettcher
- * \date 2013-02-10
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include
-#include
-#include
-#include
-
-#include
-
-#include "device_pd.h"
-
-void Platform::Device_pd::attach_dma_mem(Dataspace_capability ds_cap,
- addr_t const dma_addr)
-{
- using namespace Genode;
-
- Dataspace_client ds_client(ds_cap);
-
- size_t const size = ds_client.size();
-
- addr_t page = ~0UL;
-
- using Attach_dma_error = Pd_session::Attach_dma_error;
-
- bool retry = false;
-
- do {
- _pd.attach_dma(ds_cap, dma_addr).with_result(
-
- [&] (Pd_session::Attach_dma_ok) {
-
- page = dma_addr;
-
- /* trigger eager mapping of memory */
- _pd.map(page, size);
- retry = false;
- },
- [&] (Attach_dma_error e) {
- switch (e) {
- case Attach_dma_error::OUT_OF_RAM:
- _address_space.upgrade_ram();
- retry = true;
- break;
- case Attach_dma_error::OUT_OF_CAPS:
- _address_space.upgrade_caps();
- retry = true;
- break;
- case Attach_dma_error::DENIED:
- warning("Pd_session::attach_dma denied");
- page = dma_addr;
- retry = false;
- break;
- }
- }
- );
- } while (retry);
-
- /* sanity check */
- if ((page == ~0UL) || (page != dma_addr)) {
- if (page != ~0UL)
- _address_space.detach(page);
-
- error(_label, ": attachment of DMA memory @ ",
- Hex(dma_addr), "+", Hex(size), " " "failed page=", Hex(page));
- return;
- }
-}
-
-void Platform::Device_pd::assign_pci(Io_mem_dataspace_capability const io_mem_cap,
- addr_t const offset, uint16_t const rid)
-{
- Dataspace_client ds_client(io_mem_cap);
-
- addr_t page = _address_space.attach(io_mem_cap, 0x1000, offset);
-
- /* sanity check */
- if (!page)
- throw Region_map::Region_conflict();
-
- /* trigger eager mapping of memory */
- _pd.map(page, 0x1000);
-
- /* utility to print rid value */
- struct Rid
- {
- uint16_t const v;
- explicit Rid(uint16_t rid) : v(rid) { }
- void print(Output &out) const
- {
- using Genode::print;
- print(out, Hex((uint8_t)(v >> 8), Hex::Prefix::OMIT_PREFIX, Hex::PAD), ":",
- Hex((uint8_t)((v >> 3) & 0x1f), Hex::Prefix::OMIT_PREFIX, Hex::PAD), ".",
- Hex(v & 0x7, Hex::Prefix::OMIT_PREFIX));
- }
- };
-
- /* try to assign pci device to this protection domain */
- if (!_pd.assign_pci(page, rid))
- error(_label, ": assignment of PCI device ", Rid(rid), " failed ",
- "virt=", Hex(page));
- else
- log(_label,": assignment of PCI device ", Rid(rid), " succeeded");
-
- /* we don't need the mapping anymore */
- _address_space.detach(page);
-}
diff --git a/repos/os/src/drivers/platform/legacy/x86/device_pd.h b/repos/os/src/drivers/platform/legacy/x86/device_pd.h
deleted file mode 100644
index 366aaac867..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/device_pd.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * \brief Device PD handling for the platform driver
- * \author Alexander Boettcher
- * \date 2015-11-05
- */
-
-/*
- * Copyright (C) 2015-2021 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _DEVICE_PD_H_
-#define _DEVICE_PD_H_
-
-/* base */
-#include
-#include
-#include
-#include
-#include
-
-/* os */
-#include
-
-namespace Platform { class Device_pd; }
-
-
-class Platform::Device_pd
-{
- private:
-
- Pd_connection _pd;
- Session_label const &_label;
-
- /**
- * Custom handling of PD-session depletion during attach operations
- *
- * The default implementation of 'env.rm()' automatically issues a resource
- * request if the PD session quota gets exhausted. For the device PD, we don't
- * want to issue resource requests but let the platform driver reflect this
- * condition to its client.
- */
- struct Expanding_region_map_client : Region_map_client
- {
- Env &_env;
- Pd_connection &_pd;
- Ram_quota_guard &_ram_guard;
- Cap_quota_guard &_cap_guard;
-
- Expanding_region_map_client(Env &env,
- Pd_connection &pd,
- Ram_quota_guard &ram_guard,
- Cap_quota_guard &cap_guard)
- :
- Region_map_client(pd.address_space()), _env(env), _pd(pd),
- _ram_guard(ram_guard), _cap_guard(cap_guard)
- { }
-
- Local_addr attach(Dataspace_capability ds,
- size_t size = 0, off_t offset = 0,
- bool use_local_addr = false,
- Local_addr local_addr = (void *)0,
- bool executable = false,
- bool writeable = true) override
- {
- return retry(
- [&] () {
- return retry(
- [&] () {
- return Region_map_client::attach(ds, size, offset,
- use_local_addr,
- local_addr,
- executable,
- writeable); },
- [&] () {
- upgrade_caps();
- }
- );
- },
- [&] () {
- upgrade_ram();
- }
- );
- }
-
- void upgrade_ram()
- {
- enum { UPGRADE_RAM_QUOTA = 4096 };
- Ram_quota const ram { UPGRADE_RAM_QUOTA };
- _ram_guard.withdraw(ram);
- _env.pd().transfer_quota(_pd.rpc_cap(), ram);
- }
-
- void upgrade_caps()
- {
- enum { UPGRADE_CAP_QUOTA = 2 };
- Cap_quota const caps { UPGRADE_CAP_QUOTA };
- _cap_guard.withdraw(caps);
- _env.pd().transfer_quota(_pd.rpc_cap(), caps);
- }
- } _address_space;
-
- public:
-
- Device_pd(Env &env,
- Session_label const &label,
- Ram_quota_guard &ram_guard,
- Cap_quota_guard &cap_guard)
- :
- _pd(env, Pd_connection::Device_pd()),
- _label(label),
- _address_space(env, _pd, ram_guard, cap_guard)
- {
- _pd.ref_account(env.pd_session_cap());
- }
-
- void attach_dma_mem(Dataspace_capability, addr_t dma_addr);
- void assign_pci(Io_mem_dataspace_capability const,
- addr_t const, uint16_t const);
-};
-
-#endif /* _DEVICE_PD_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/irq.cc b/repos/os/src/drivers/platform/legacy/x86/irq.cc
deleted file mode 100644
index 609142475d..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/irq.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * \brief Implementation of shared IRQs in platform driver
- * \author Alexander Boettcher
- * \date 2015-03-27
- */
-
-/*
- * Copyright (C) 2015-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-
-/* Platform driver include */
-#include "irq.h"
-#include "pci_session_component.h"
-
-
-namespace Platform {
- class Irq_component;
- class Irq_allocator;
-}
-
-
-/**
- * A simple allocator implementation used by the Irq_proxy
- */
-class Platform::Irq_allocator
-{
- private:
-
- /*
- * We partition the IRQ space (128 GSIs) into 40 legacy IRQs and 64 MSIs (and
- * hope the partitions will never overlap on any bizarre platform.)
- */
- enum { LEGACY = 40, MSI = 64, LEGACY_ARRAY = 64 };
-
- Bit_array _legacy { };
- Bit_allocator _msi { };
-
- public:
-
- Irq_allocator()
- {
- /* reserve the last 24 legacy IRQs - 40 IRQs remaining */
- _legacy.set(LEGACY, LEGACY_ARRAY - LEGACY);
- }
-
- unsigned alloc_msi()
- {
- try {
- return _msi.alloc();
- } catch (Bit_allocator::Out_of_indices) { return ~0U; }
- }
-
- void free_msi(unsigned msi) { _msi.free(msi); }
-
- bool alloc_irq(addr_t addr)
- {
- try {
- _legacy.set(addr, 1);
- return true;
- } catch (...) {
- return false;
- }
- }
-};
-
-
-/**
- * One allocator for managing in use IRQ numbers and one IRQ thread waiting
- * for Genode signals of all hardware IRQs.
- */
-static Platform::Irq_allocator irq_alloc;
-
-
-/**
- * Irq_proxy interface implementation
- */
-class Platform::Irq_component : public Platform::Irq_proxy
-{
- private:
-
- Irq_connection _irq;
- Signal_handler _irq_dispatcher;
-
- bool _associated;
-
- public:
-
- void _ack_irq() {
- /*
- * Associate handler only when required, because our partner may
- * also implement shared irq and would expect to get ack_irq()
- * form us even if we have no client ...
- */
- if (!_associated) {
- _associated = true;
- /* register signal handler on irq_session */
- _irq.sigh(_irq_dispatcher);
- }
-
- _irq.ack_irq();
- }
-
- virtual bool remove_sharer(Platform::Irq_sigh *s) override {
- if (!Irq_proxy::remove_sharer(s))
- return false;
-
- /* De-associate handler. */
- _associated = false;
- _irq.sigh(Signal_context_capability());
- return true;
- }
-
- public:
-
- Irq_component(Env &env, unsigned gsi,
- Irq_session::Trigger trigger,
- Irq_session::Polarity polarity)
- :
- Irq_proxy(gsi),
- _irq(env, gsi, trigger, polarity),
- _irq_dispatcher(env.ep(), *this, &Platform::Irq_proxy::notify_about_irq),
- _associated(false)
- { }
-
- static Irq_component *get_irq_proxy(unsigned irq_number,
- Irq_allocator *irq_alloc = nullptr,
- Irq_session::Trigger trigger = Irq_session::TRIGGER_UNCHANGED,
- Irq_session::Polarity polarity = Irq_session::POLARITY_UNCHANGED,
- Env *env = nullptr,
- Allocator *heap = nullptr)
- {
- static List proxies;
- static Mutex proxies_mutex;
-
- Mutex::Guard mutex_guard(proxies_mutex);
-
- /* lookup proxy in database */
- for (Irq_proxy *p = proxies.first(); p; p = p->next())
- if (p->irq_number() == irq_number)
- return static_cast(p);
-
- /* try to create proxy */
- if (!irq_alloc || !env || !heap || !irq_alloc->alloc_irq(irq_number))
- return 0;
-
- Irq_component *new_proxy = new (heap) Irq_component(*env, irq_number, trigger,
- polarity);
- proxies.insert(new_proxy);
- return new_proxy;
- }
-};
-
-
-
-/*******************************
- ** PCI IRQ session component **
- *******************************/
-
-void Platform::Irq_session_component::ack_irq()
-{
- if (msi()) {
- _msi_conn->ack_irq();
- return;
- }
-
- /* shared irq handling */
- Irq_component *irq_obj = Irq_component::get_irq_proxy(_gsi);
- if (!irq_obj) {
- error("expected to find IRQ proxy for IRQ ", Hex(_gsi));
- return;
- }
-
- if (irq_obj->ack_irq())
- irq_obj->_ack_irq();
-}
-
-
-Platform::Irq_session_component::Irq_session_component(unsigned irq,
- addr_t pci_config_space,
- Env &env,
- Allocator &heap,
- Irq_session::Trigger trigger,
- Irq_session::Polarity polarity)
-:
- _gsi(irq)
-{
- if (pci_config_space != ~0UL) {
- /* msi way */
- unsigned msi = irq_alloc.alloc_msi();
- if (msi != ~0U) {
- try {
- using namespace Genode;
-
- _msi_conn.construct(env, msi, Irq_session::TRIGGER_UNCHANGED,
- Irq_session::POLARITY_UNCHANGED,
- pci_config_space);
-
- _msi_info = _msi_conn->info();
- if (_msi_info.type == Irq_session::Info::Type::MSI) {
- _gsi = msi;
- return;
- }
- } catch (Service_denied) { }
-
- irq_alloc.free_msi(msi);
- }
- }
-
- /* invalid irq number for pci_devices */
- if (_gsi >= INVALID_IRQ)
- return;
-
- _gsi = Platform::Irq_override::irq_override(_gsi, trigger, polarity);
- if (_gsi != irq || trigger != Irq_session::TRIGGER_UNCHANGED ||
- polarity != POLARITY_UNCHANGED) {
-
- log("IRQ override ", irq, "->", _gsi, ", "
- "trigger mode: ", trigger, ", ", "polarity: ", polarity);
- }
-
- try {
- /* check if shared IRQ object was used before */
- if (Irq_component::get_irq_proxy(_gsi, &irq_alloc, trigger,
- polarity, &env, &heap))
- return;
- } catch (Service_denied) { }
-
- error("unavailable IRQ ", Hex(_gsi), " requested");
-}
-
-
-Platform::Irq_session_component::~Irq_session_component()
-{
- if (msi()) {
- _msi_conn->sigh(Signal_context_capability());
-
- irq_alloc.free_msi(_gsi);
- return;
- }
-
- /* shared irq handling */
- Irq_component *irq_obj = Irq_component::get_irq_proxy(_gsi);
- if (!irq_obj) return;
-
- if (_irq_sigh.valid())
- irq_obj->remove_sharer(&_irq_sigh);
-}
-
-
-void Platform::Irq_session_component::sigh(Signal_context_capability sigh)
-{
- if (_msi_conn.constructed()) {
- /* register signal handler for msi directly at parent */
- _msi_conn->sigh(sigh);
- return;
- }
-
- /* shared irq handling */
- Irq_component *irq_obj = Irq_component::get_irq_proxy(_gsi);
- if (!irq_obj) {
- error("signal handler got not registered - irq object unavailable");
- return;
- }
-
- Signal_context_capability old = _irq_sigh;
-
- if (old.valid() && !sigh.valid())
- irq_obj->remove_sharer(&_irq_sigh);
-
- _irq_sigh = sigh;
-
- if (!old.valid() && sigh.valid())
- irq_obj->add_sharer(&_irq_sigh);
-}
-
-
-unsigned short Platform::Irq_routing::rewrite(Pci::Bdf const bdf, unsigned char pin)
-{
- unsigned const bridge_bdf_bus = Platform::bridge_bdf(bdf.bus);
-
- for (Irq_routing *i = list()->first(); i; i = i->next()) {
- if ((bdf.device == i->_device) && (pin - 1 == i->_device_pin) &&
- (i->_bridge_bdf == bridge_bdf_bus))
- return i->_gsi;
- }
-
- return 0;
-}
diff --git a/repos/os/src/drivers/platform/legacy/x86/irq.h b/repos/os/src/drivers/platform/legacy/x86/irq.h
deleted file mode 100644
index 55c2402a96..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/irq.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * \brief IRQ session interface
- * \author Alexander Boettcher
- * \date 2015-03-25
- */
-
-/*
- * Copyright (C) 2015-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _X86__IRQ_H_
-#define _X86__IRQ_H_
-
-#include
-#include
-#include
-#include
-
-/* platform local includes */
-#include
-#include
-
-
-namespace Platform {
- class Irq_session_component;
- class Irq_override;
- class Irq_routing;
-}
-
-
-class Platform::Irq_session_component : public Rpc_object,
- private List::Element
-{
- private:
-
- friend class List;
-
- unsigned _gsi;
- Platform::Irq_sigh _irq_sigh { };
- Irq_session::Info _msi_info { };
-
- Constructible _msi_conn { };
-
- public:
-
- enum { INVALID_IRQ = 0xffU };
-
- Irq_session_component(unsigned, addr_t, Env &, Allocator &heap,
- Trigger trigger = TRIGGER_UNCHANGED,
- Polarity polarity = POLARITY_UNCHANGED);
-
- ~Irq_session_component();
-
- bool msi()
- {
- return _msi_conn.constructed() &&
- _msi_info.type == Irq_session::Info::Type::MSI;
- }
-
- unsigned gsi() { return _gsi; }
-
- unsigned long msi_address() const { return _msi_info.address; }
- unsigned long msi_data() const { return _msi_info.value; }
-
- /***************************
- ** Irq session interface **
- ***************************/
-
- void ack_irq() override;
- void sigh(Signal_context_capability) override;
-
- Info info() override
- {
- return { .type = Info::Type::INVALID, .address = 0, .value = 0 };
- }
-};
-
-
-/**
- * List that holds interrupt override information
- */
-class Platform::Irq_override : public List::Element
-{
- private:
-
- unsigned short const _irq; /* source IRQ */
- unsigned short const _gsi; /* target GSI */
- Irq_session::Trigger const _trigger; /* interrupt trigger mode */
- Irq_session::Polarity const _polarity; /* interrupt polarity */
-
- Irq_session::Trigger _mode2trigger(unsigned mode)
- {
- enum { EDGE = 0x4, LEVEL = 0xc };
-
- switch (mode & 0xc) {
- case EDGE:
- return Irq_session::TRIGGER_EDGE;
- case LEVEL:
- return Irq_session::TRIGGER_LEVEL;
- default:
- return Irq_session::TRIGGER_UNCHANGED;
- }
- }
-
- Irq_session::Polarity _mode2polarity(unsigned mode)
- {
- using namespace Genode;
- enum { HIGH = 0x1, LOW = 0x3 };
-
- switch (mode & 0x3) {
- case HIGH:
- return Irq_session::POLARITY_HIGH;
- case LOW:
- return Irq_session::POLARITY_LOW;
- default:
- return Irq_session::POLARITY_UNCHANGED;
- }
- }
-
- public:
-
- Irq_override(unsigned irq, unsigned gsi, unsigned mode)
- :
- _irq(irq), _gsi(gsi),
- _trigger(_mode2trigger(mode)), _polarity(_mode2polarity(mode))
- { }
-
- static List *list()
- {
- static List _list;
- return &_list;
- }
-
- unsigned short irq() const { return _irq; }
- unsigned short gsi() const { return _gsi; }
- Irq_session::Trigger trigger() const { return _trigger; }
- Irq_session::Polarity polarity() const { return _polarity; }
-
- static unsigned irq_override(unsigned irq,
- Irq_session::Trigger &trigger,
- Irq_session::Polarity &polarity)
- {
- for (Irq_override *i = list()->first(); i; i = i->next())
- if (i->irq() == irq) {
- trigger = i->trigger();
- polarity = i->polarity();
- return i->gsi();
- }
-
- /* trigger and polarity not touched in this case! */
- return irq;
- }
-};
-
-
-/**
- * List that holds interrupt rewrite information
- */
-class Platform::Irq_routing : public List::Element
-{
- private:
-
- unsigned short _gsi;
- unsigned short _bridge_bdf;
- unsigned short _device;
- unsigned char _device_pin;
-
- public:
-
- static List *list()
- {
- static List _list;
- return &_list;
- }
-
- Irq_routing(unsigned short gsi, unsigned short bridge_bdf,
- unsigned char device, unsigned char device_pin)
- :
- _gsi(gsi), _bridge_bdf(bridge_bdf), _device(device),
- _device_pin(device_pin)
- { }
-
- static unsigned short rewrite(Pci::Bdf, unsigned char pin);
-};
-
-#endif /* _X86__IRQ_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/irq_proxy.h b/repos/os/src/drivers/platform/legacy/x86/irq_proxy.h
deleted file mode 100644
index c4971e435f..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/irq_proxy.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * \brief Shared-interrupt support
- * \author Christian Helmuth
- * \author Sebastian Sumpf
- * \date 2009-12-15
- */
-
-/*
- * Copyright (C) 2009-2020 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _DRIVERS__PLATFORM__SPEC__X86__IRQ_PROXY_H_
-#define _DRIVERS__PLATFORM__SPEC__X86__IRQ_PROXY_H_
-
-#include
-
-namespace Platform {
- class Irq_sigh;
- class Irq_proxy;
-}
-
-
-class Platform::Irq_sigh : public Signal_context_capability,
- public List::Element
-{
- public:
-
- Irq_sigh & operator= (Signal_context_capability const &cap)
- {
- Signal_context_capability::operator=(cap);
- return *this;
- }
-
- Irq_sigh() { }
-
- void notify() { Signal_transmitter(*this).submit(1); }
-};
-
-
-/*
- * Proxy thread that associates to the interrupt and unblocks waiting irqctrl
- * threads.
- *
- * XXX resources are not accounted as the interrupt is shared
- */
-class Platform::Irq_proxy : private List::Element
-{
- private:
-
- friend class List;
-
- protected:
-
- unsigned const _irq_number;
-
- List _sigh_list { };
-
- Mutex _mutex { }; /* protects this object */
- int _num_sharers = 0; /* number of clients sharing this IRQ */
- int _num_acknowledgers = 0; /* number of currently blocked clients */
- bool _woken_up = false; /* client decided to wake me up -
- this prevents multiple wakeups
- to happen during initialization */
- public:
-
- using List::Element::next;
-
- Irq_proxy(unsigned irq_number) : _irq_number(irq_number) { }
-
- virtual ~Irq_proxy() { }
-
- /**
- * Acknowledgements of clients
- */
- virtual bool ack_irq()
- {
- Mutex::Guard mutex_guard(_mutex);
-
- _num_acknowledgers++;
-
- /*
- * The proxy thread has to be woken up if no client woke it up
- * before and this client is the last aspired acknowledger.
- */
- if (!_woken_up && _num_acknowledgers == _num_sharers) {
- _woken_up = true;
- }
-
- return _woken_up;
- }
-
- /**
- * Notify all clients about irq
- */
- void notify_about_irq()
- {
- Mutex::Guard mutex_guard(_mutex);
-
- /* reset acknowledger state */
- _num_acknowledgers = 0;
- _woken_up = false;
-
- /* inform blocked clients */
- for (Irq_sigh * s = _sigh_list.first(); s ; s = s->next())
- s->notify();
- }
-
- unsigned irq_number() const { return _irq_number; }
-
- virtual bool add_sharer(Irq_sigh *s)
- {
- Mutex::Guard mutex_guard(_mutex);
-
- ++_num_sharers;
- _sigh_list.insert(s);
-
- return true;
- }
-
- virtual bool remove_sharer(Irq_sigh *s)
- {
- Mutex::Guard mutex_guard(_mutex);
-
- _sigh_list.remove(s);
- --_num_sharers;
-
- if (_woken_up)
- return _num_sharers == 0;
-
- if (_num_acknowledgers == _num_sharers) {
- _woken_up = true;
- }
-
- return _num_sharers == 0;
- }
-};
-
-#endif /* _DRIVERS__PLATFORM__SPEC__X86__IRQ_PROXY_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/main.cc b/repos/os/src/drivers/platform/legacy/x86/main.cc
deleted file mode 100644
index 58c3e5e777..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/main.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * \brief Platform driver for x86
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include
-#include
-#include
-
-#include
-
-#include "pci_session_component.h"
-#include "pci_device_config.h"
-#include "device_pd.h"
-#include "acpi_devices.h"
-
-namespace Platform {
- struct Main;
-
- namespace Nonpci { void acpi_device_registry(Acpi::Device_registry &); }
-};
-
-struct Platform::Main
-{
- Env &_env;
-
- Heap _heap { _env.ram(), _env.rm() };
-
- Acpi::Device_registry _acpi_device_registry { };
-
- /*
- * Use sliced heap to allocate each session component at a separate
- * dataspace.
- */
- Sliced_heap sliced_heap { _env.ram(), _env.rm() };
-
- Attached_rom_dataspace _config { _env, "config" };
-
- Constructible acpi_rom { };
- Constructible root { };
-
- Constructible system_state { };
- Constructible acpi_ready { };
-
- Signal_handler _acpi_report { _env.ep(), *this,
- &Main::acpi_update };
- Signal_handler _system_report { _env.ep(), *this,
- &Main::system_update };
- Signal_handler _config_handler { _env.ep(), *this,
- &Main::config_update };
-
- Capability > root_cap { };
-
- bool _acpi_ready = false;
-
- void _attempt_acpi_reset();
-
- void acpi_update()
- {
- if (!root.constructed()) {
- acpi_rom->update();
-
- if (!acpi_rom->valid())
- return;
-
- bool msi_platform = false;
- bool acpi_platform = false;
-
- try {
- Attached_rom_dataspace info { _env, "platform_info" };
- info.xml().with_optional_sub_node("kernel", [&] (Xml_node const &node) {
- acpi_platform = node.attribute_value("acpi", acpi_platform);
- msi_platform = node.attribute_value("msi" , msi_platform);
- });
- } catch (...) { }
-
- root.construct(_env, _heap, sliced_heap, _config,
- acpi_rom->local_addr(), acpi_platform,
- msi_platform);
- }
-
- if (root_cap.valid())
- return;
-
- /* don't announce service if no policy entry is available */
- if (!root->config_with_policy())
- return;
-
- root_cap = _env.ep().manage(*root);
-
- if (_acpi_ready) {
- Parent::Service_name announce_for_acpi("Acpi");
- _env.parent().announce(announce_for_acpi, root_cap);
- } else
- _env.parent().announce(root_cap);
- }
-
- void system_update()
- {
- if (acpi_ready.constructed())
- acpi_ready->update();
-
- if (!root.constructed())
- return;
-
- if (acpi_ready.constructed() && acpi_ready->valid()) {
- Xml_node system(acpi_ready->local_addr(), acpi_ready->size());
-
- typedef String<16> Value;
- const Value state = system.attribute_value("state", Value("unknown"));
-
- if (state == "acpi_ready" && root_cap.valid()) {
- _env.parent().announce(root_cap);
- root_cap = Capability > ();
- }
- }
- }
-
- void config_update()
- {
- _config.update();
-
- if (!_config.valid())
- return;
-
- if (!root_cap.valid())
- acpi_update();
-
- bool const system_state_was_constructed = system_state.constructed();
-
- system_state.conditional(_config.xml().attribute_value("system", false),
- _env, "system");
-
- if (system_state.constructed() && !system_state_was_constructed)
- system_state->sigh(_config_handler);
-
- if (system_state.constructed()) {
- system_state->update();
- if (system_state->xml().attribute_value("state", String<16>()) == "reset")
- _attempt_acpi_reset();
- }
-
- if (root.constructed()) {
- root->generate_pci_report();
- root->config_update();
- }
-
- _acpi_device_registry.init_devices(_heap, _config.xml());
- }
-
- Main(Env &env) : _env(env)
- {
- _config.sigh(_config_handler);
-
- if (_config.valid())
- _acpi_ready = _config.xml().attribute_value("acpi_ready", false);
-
- if (_acpi_ready) {
- acpi_ready.construct(env, "acpi_ready");
- acpi_ready->sigh(_system_report);
- }
-
- /* wait for the first valid acpi report */
- acpi_rom.construct(env, "acpi");
- acpi_rom->sigh(_acpi_report);
-
- /* check if already valid */
- config_update();
- acpi_update();
- system_update();
-
- Nonpci::acpi_device_registry(_acpi_device_registry);
- }
-};
-
-
-void Platform::Main::_attempt_acpi_reset()
-{
- if (!acpi_rom.constructed())
- return;
-
- acpi_rom->xml().with_optional_sub_node("reset", [&] (Xml_node reset) {
-
- uint16_t const io_port = reset.attribute_value("io_port", (uint16_t)0);
- uint8_t const value = reset.attribute_value("value", (uint8_t)0);
-
- log("trigger reset by writing value ", value, " to I/O port ", Hex(io_port));
-
- try {
- Io_port_connection reset_port { _env, io_port, 1 };
- reset_port.outb(io_port, value);
- }
- catch (...) {
- error("unable to access reset I/O port ", Hex(io_port));
- }
- });
-}
-
-
-void Component::construct(Genode::Env &env)
-{
- /* XXX execute constructors of global statics */
- env.exec_static_constructors();
-
- static Platform::Main main(env);
-}
diff --git a/repos/os/src/drivers/platform/legacy/x86/nonpci_devices.cc b/repos/os/src/drivers/platform/legacy/x86/nonpci_devices.cc
deleted file mode 100644
index 550883b19b..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/nonpci_devices.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * \brief Non PCI devices, e.g. PS2
- * \author Alexander Boettcher
- * \author Christian Helmuth
- * \date 2015-04-17
- */
-
-/*
- * Copyright (C) 2015-2021 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include "pci_session_component.h"
-#include "irq.h"
-#include "acpi_devices.h"
-
-namespace Platform { namespace Nonpci { class Ps2; class Pit; } }
-
-
-class Platform::Nonpci::Ps2 : public Device_component
-{
- private:
-
- enum {
- IRQ_KEYBOARD = 1,
- IRQ_MOUSE = 12,
-
- ACCESS_WIDTH = 1,
- REG_DATA = 0x60,
- REG_STATUS = 0x64,
- };
-
- Rpc_entrypoint &_ep;
- Platform::Irq_session_component _irq_mouse;
- Io_port_connection _data;
- Io_port_connection _status;
-
- public:
-
- Ps2(Env &env,
- Attached_io_mem_dataspace &pciconf,
- Session_component &session,
- Allocator &heap_for_irq,
- Pci::Config::Delayer &delayer,
- Device_bars_pool &devices_bars)
- :
- Device_component(env, pciconf, session, IRQ_KEYBOARD,
- heap_for_irq, delayer, devices_bars),
- _ep(env.ep().rpc_ep()),
- _irq_mouse(IRQ_MOUSE, ~0UL, env, heap_for_irq),
- _data(env, REG_DATA, ACCESS_WIDTH),
- _status(env, REG_STATUS, ACCESS_WIDTH)
- {
- _ep.manage(&_irq_mouse);
- }
-
- ~Ps2() { _ep.dissolve(&_irq_mouse); }
-
- Irq_session_capability irq(uint8_t virt_irq) override
- {
- switch (virt_irq) {
- case 0:
- log("PS2 uses IRQ, vector ", Hex(IRQ_KEYBOARD));
- return Device_component::irq(virt_irq);
- case 1:
- log("PS2 uses IRQ, vector ", Hex(IRQ_MOUSE));
- return _irq_mouse.cap();
- default:
- return Irq_session_capability();
- }
- }
-
- Io_port_session_capability io_port(uint8_t io_port) override
- {
- if (io_port == 0)
- return _data.cap();
- if (io_port == 1)
- return _status.cap();
-
- return Io_port_session_capability();
- }
-
- Io_mem_session_capability io_mem(uint8_t, Cache, addr_t, size_t) override
- {
- return Io_mem_session_capability();
- }
-
- Device_name_string name() const override { return "PS2"; }
-};
-
-
-class Platform::Nonpci::Pit : public Device_component
-{
- private:
-
- enum {
- IRQ_PIT = 0,
-
- PIT_PORT = 0x40,
- PORTS_WIDTH = 4
- };
-
- Io_port_connection _ports;
-
- public:
-
- Pit(Env &env,
- Attached_io_mem_dataspace &pciconf,
- Session_component &session,
- Allocator &heap_for_irq,
- Pci::Config::Delayer &delayer,
- Device_bars_pool &devices_bars)
- :
- Device_component(env, pciconf, session, IRQ_PIT,
- heap_for_irq, delayer, devices_bars),
- _ports(env, PIT_PORT, PORTS_WIDTH)
- { }
-
- Io_port_session_capability io_port(uint8_t io_port) override
- {
- if (io_port == 0)
- return _ports.cap();
-
- return Io_port_session_capability();
- }
-
- Device_name_string name() const override { return "PIT"; }
-};
-
-
-namespace Platform { namespace Nonpci {
- class Acpi;
-
- void acpi_device_registry(Platform::Acpi::Device_registry &);
-} }
-
-
-static Platform::Acpi::Device_registry *_acpi_device_registry;
-
-void Platform::Nonpci::acpi_device_registry(Platform::Acpi::Device_registry ®istry)
-{
- _acpi_device_registry = ®istry;
-}
-
-
-class Platform::Nonpci::Acpi : public Device_component
-{
- private:
-
- Env &_env;
-
- Allocator &_session_heap;
-
- Platform::Acpi::Device const &_acpi_device;
-
- Irq_session_component *_irq0 = nullptr;
-
- /*
- * Noncopyable
- */
- Acpi(Acpi const &) = delete;
- Acpi &operator = (Acpi const &) = delete;
-
- public:
-
- Acpi(Platform::Acpi::Device const &acpi_device,
- Env &env,
- Attached_io_mem_dataspace &pciconf,
- Session_component &session,
- Allocator &session_heap,
- Allocator &global_heap,
- Pci::Config::Delayer &delayer,
- Device_bars_pool &devices_bars)
- :
- Device_component(env, pciconf, session, 0,
- global_heap, delayer, devices_bars),
- _env(env), _session_heap(session_heap), _acpi_device(acpi_device)
- { }
-
- Device_name_string name() const override { return _acpi_device.hid(); }
-
- /* Platform::Device interface */
-
- void bus_address(unsigned char *bus, unsigned char *dev,
- unsigned char *fn) override
- {
- *bus = 0; *dev = 0; *fn = 0;
- }
-
- unsigned short vendor_id() override { return ~0; }
-
- unsigned short device_id() override { return ~0; }
-
- unsigned class_code() override { return ~0; }
-
- Resource resource(int resource_id) override
- {
- using Acpi_device = Platform::Acpi::Device;
-
- return _acpi_device.resource(resource_id).convert(
- [&] (Acpi_device::Resource r) {
- /* craft artificial BAR values from resource info */
- switch (r.type) {
- case Acpi_device::Resource::Type::IOMEM:
- return Resource((r.base & 0xfffffff0) | 0b0000, r.size);
-
- case Acpi_device::Resource::Type::IOPORT:
- return Resource((r.base & 0xfffffffc) | 0b01, r.size);
-
- case Acpi_device::Resource::Type::IRQ:
- return Resource();
- }
- return Resource();
- },
- [&] (Acpi_device::Invalid_resource) { return Resource(); });
- }
-
- unsigned config_read(unsigned char, Access_size) override
- {
- warning("ignore config_read from ACPI device ", _acpi_device.hid());
- return 0;
- }
-
- void config_write(unsigned char, unsigned, Access_size) override
- {
- warning("ignore config_write to ACPI device ", _acpi_device.hid());
- }
-
- Irq_session_capability irq(uint8_t v_id) override
- {
- using Acpi_device = Platform::Acpi::Device;
-
- /* TODO more than one IRQ */
- if (v_id != 0) {
- warning("ACPI device with more than one IRQ not supported (requested id ", v_id, ")");
- return Irq_session_capability();
- }
- if (_irq0) return _irq0->cap();
-
- /* TODO needs try see pci_device.cc ::iomem() */
- return _acpi_device.irq(v_id).convert(
- [&] (Acpi_device::Resource r) {
- Platform::Irq_session_component &irq =
- *new(_session_heap)
- Platform::Irq_session_component(r.base, ~0UL, _env, _session_heap,
- Irq_session::TRIGGER_LEVEL,
- Irq_session::POLARITY_LOW);
- _env.ep().manage(irq);
- _irq0 = &irq;
- return irq.cap();
- },
- [&] (Acpi_device::Invalid_resource) { return Irq_session_capability(); });
- }
-
- Io_port_session_capability io_port(uint8_t v_id) override
- {
- using Acpi_device = Platform::Acpi::Device;
-
- /* TODO needs try see pci_device.cc ::iomem() */
-
- return _acpi_device.ioport(v_id).convert(
- [&] (Acpi_device::Resource r) {
- Io_port_connection &ioport =
- *new (_session_heap) Io_port_connection(_env, r.base, r.size);
- return ioport.cap();
- },
- [&] (Acpi_device::Invalid_resource) { return Io_port_session_capability(); });
- }
-
- Io_mem_session_capability io_mem(uint8_t v_id,
- Cache /* ignored */,
- addr_t /* ignored */,
- size_t /* ignored */) override
- {
- using Acpi_device = Platform::Acpi::Device;
-
- /* TODO needs try see pci_device.cc ::iomem() */
-
- return _acpi_device.iomem(v_id).convert(
- [&] (Acpi_device::Resource r) {
- Io_mem_connection &iomem =
- *new (_session_heap) Io_mem_connection(_env, r.base, r.size);
- return iomem.cap();
- },
- [&] (Acpi_device::Invalid_resource) { return Io_mem_session_capability(); });
- }
-};
-
-
-/**
- * Platform session component devices which are non PCI devices, e.g. PS2
- */
-Platform::Device_capability Platform::Session_component::device(Device_name const &name)
-{
- if (!name.valid_string())
- return Device_capability();
-
- Device_name_string const device_name { name.string() };
-
- enum class Type { UNKNOWN, PS2, PIT, ACPI } device_type { Type::UNKNOWN };
-
- Platform::Acpi::Device const *acpi_device = nullptr;
-
- if (device_name == "PS2")
- device_type = Type::PS2;
-
- else if (device_name == "PIT")
- device_type = Type::PIT;
-
- else if (_acpi_device_registry)
- device_type = _acpi_device_registry->lookup(device_name).convert(
- [&] (Acpi::Device const *device) {
- acpi_device = device;
- return Type::ACPI;
- },
- [&] (Acpi::Device_registry::Lookup_failed) { return Type::UNKNOWN; });
-
- bool const found = device_type != Type::UNKNOWN;
-
- if (!found) {
- error("unknown device name '", device_name, "'");
- return Device_capability();
- }
-
- if (!permit_device(device_name.string())) {
- error("denied access to device '", device_name, "' for "
- "session '", _label, "'");
- return Device_capability();
- }
-
- try {
- Device_component * dev = nullptr;
-
- switch (device_type) {
- case Type::PS2:
- dev = new (_md_alloc) Nonpci::Ps2(_env, _pciconf, *this,
- _global_heap, _delayer,
- _devices_bars);
- break;
- case Type::PIT:
- dev = new (_md_alloc) Nonpci::Pit(_env, _pciconf, *this,
- _global_heap, _delayer,
- _devices_bars);
- break;
- case Type::ACPI:
- dev = new (_md_alloc) Nonpci::Acpi(*acpi_device,
- _env, _pciconf, *this,
- _md_alloc,
- _global_heap, _delayer,
- _devices_bars);
- break;
- default:
- return Device_capability();
- }
-
- _device_list.insert(dev);
- return _env.ep().rpc_ep().manage(dev);
- }
- catch (Out_of_ram) { throw; }
- catch (Service_denied) { return Device_capability(); }
-}
diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_bridge.h b/repos/os/src/drivers/platform/legacy/x86/pci_bridge.h
deleted file mode 100644
index 92ba968e46..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/pci_bridge.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * \brief PCI bridge discovery
- * \author Sebastian Sumpf
- * \date 2012-02-25
- */
-
- /*
- * Copyright (C) 2009-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _PCI_BRIDGE_H_
-#define _PCI_BRIDGE_H_
-
-#include
-
-namespace Platform { class Bridge; }
-
-
-/**
- * List of PCI-bridge devices
- */
-class Platform::Bridge : public List::Element
-{
- private:
-
- /* PCI config space fields of bridge */
- unsigned char _bus;
- unsigned char _dev;
- unsigned char _fun;
-
- unsigned char _secondary_bus;
- unsigned char _subordinate_bus;
-
- public:
-
- Bridge(unsigned char bus, unsigned char dev, unsigned char fun,
- unsigned char secondary_bus, unsigned char subordinate_bus)
- :
- _bus(bus), _dev(dev), _fun(fun), _secondary_bus(secondary_bus),
- _subordinate_bus(subordinate_bus)
- { }
-
- bool part_of (unsigned char bus) const
- {
- return _secondary_bus <= bus && bus <= _subordinate_bus;
- }
-
- unsigned short bdf()
- {
- unsigned short bdf = _bus;
- bdf = (bdf << 8) | ((_dev & 0x1f) << 3) | (_fun & 0x7);
- return bdf;
- }
-
- enum { INVALID_ROOT_BRIDGE = 0x10000U };
- static unsigned root_bridge_bdf;
-};
-
-#endif /* _PCI_BRIDGE_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_config_access.h b/repos/os/src/drivers/platform/legacy/x86/pci_config_access.h
deleted file mode 100644
index ed22e1af0c..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/pci_config_access.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * \brief PCI configuration access for the platform driver
- * \author Norman Feske
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2021 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _X86_PCI_CONFIG_ACCESS_H_
-#define _X86_PCI_CONFIG_ACCESS_H_
-
-#include
-#include
-#include
-#include
-#include
-
-namespace Platform { namespace Pci { struct Bdf; struct Config; } }
-
-
-struct Platform::Pci::Bdf
-{
- unsigned bus, device, function;
-
- static Bdf from_value(uint16_t const bdf)
- {
- return Bdf { .bus = (bdf >> 8) & 0xffu,
- .device = (bdf >> 3) & 0x1fu,
- .function = bdf & 0x07u };
- }
-
- static Bdf from_xml(Xml_node node)
- {
- return Bdf { .bus = node.attribute_value("bus", 0U),
- .device = node.attribute_value("device", 0U),
- .function = node.attribute_value("function", 0U) };
- }
-
-
- uint16_t value() const {
- return ((bus & 0xff) << 8) | ((device & 0x1f) << 3) | (function & 7); }
-
- bool operator == (Bdf const &other) const {
- return value() == other.value(); }
-
- void print(Output &out) const
- {
- using Genode::print;
- print(out, Hex((uint8_t)bus, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
- ":", Hex((uint8_t)device, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
- ".", Hex(function, Hex::Prefix::OMIT_PREFIX));
- }
-};
-
-
-namespace Platform {
-
- class Config_access
- {
- private:
-
- Attached_io_mem_dataspace &_pciconf;
-
- size_t const _pciconf_size;
-
- /**
- * Calculate device offset from BDF
- *
- * \return device base address
- */
- unsigned _dev_base(Pci::Bdf const bdf)
- {
- return unsigned(bdf.value()) << 12;
- }
-
- Bit_array<256> _used { };
-
- void _use_register(unsigned char addr, unsigned short width)
- {
- for (unsigned i = 0; i < width; i++)
- if (!_used.get(addr + i, 1))
- _used.set(addr + i, 1);
- }
-
- public:
-
- class Invalid_mmio_access : Exception { };
-
- Config_access(Attached_io_mem_dataspace &pciconf)
- :
- _pciconf(pciconf),
- _pciconf_size(Dataspace_client(_pciconf.cap()).size())
- { }
-
- Config_access(Config_access &c)
- : _pciconf(c._pciconf), _pciconf_size(c._pciconf_size) { }
-
- /**
- * Read value from config space of specified device/function
- *
- * \param bdf target PCI bus, device & function ID
- * \param addr target byte within targeted PCI config space
- * \param size bit width of read access
- *
- * \return value read from specified config-space address
- *
- * There is no range check for the input values.
- */
- unsigned read(Pci::Bdf const bdf, unsigned char const addr,
- Device::Access_size const size, bool const track = true)
- {
- unsigned const offset = _dev_base(bdf) + addr;
- char const * const field_ptr = _pciconf.local_addr() + offset;
-
- if (offset >= _pciconf_size)
- throw Invalid_mmio_access();
-
- switch (size) {
-
- case Device::ACCESS_8BIT:
- if (track)
- _use_register(addr, 1);
- return *(uint8_t const *)field_ptr;
-
- case Device::ACCESS_16BIT:
- if (track)
- _use_register(addr, 2);
- return *(uint16_t const *)field_ptr;
-
- case Device::ACCESS_32BIT:
- if (track)
- _use_register(addr, 4);
- return *(uint32_t const *)field_ptr;
- }
- return ~0U;
- }
-
- /**
- * Write to config space of specified device/function
- *
- * \param bdf target PCI bus, device & function ID
- * \param addr target byte within targeted PCI config space
- * \param value value to be written
- * \param size bit width of write access
- *
- * There is no range check for the input values.
- */
- void write(Pci::Bdf const bdf, unsigned char const addr,
- unsigned const value, Device::Access_size const size,
- bool const track = true)
- {
- unsigned const offset = _dev_base(bdf) + addr;
- char * const field_ptr = _pciconf.local_addr() + offset;
-
- if (offset >= _pciconf_size)
- throw Invalid_mmio_access();
-
- /*
- * Write value to targeted address, see read() comment above
- * for an explanation of the assembly templates
- */
- switch (size) {
-
- case Device::ACCESS_8BIT:
- if (track)
- _use_register(addr, 1);
- *(uint8_t volatile *)field_ptr = value;
- break;
-
- case Device::ACCESS_16BIT:
- if (track)
- _use_register(addr, 2);
- *(uint16_t volatile *)field_ptr = value;
- break;
-
- case Device::ACCESS_32BIT:
- if (track)
- _use_register(addr, 4);
- *(uint32_t volatile *)field_ptr = value;
- break;
- }
- }
-
- bool reg_in_use(unsigned char addr, Device::Access_size size)
- {
- switch (size) {
- case Device::ACCESS_8BIT:
- return _used.get(addr, 1);
- case Device::ACCESS_16BIT:
- return _used.get(addr, 2);
- case Device::ACCESS_32BIT:
- return _used.get(addr, 4);
- default:
- return true;
- }
- }
- };
-}
-
-/**
- * Type-safe, fine-grained access to a PCI config space of a device
- *
- * It is similar to Genode::Mmio but uses Config_access as backend.
- */
-struct Platform::Pci::Config: Register_set
-{
- private:
-
- friend Register_set_plain_access;
-
- Config_access &_config;
- Pci::Bdf _bdf;
- uint16_t _cap;
-
- template
- inline ACCESS_T _read(off_t const &offset) const
- {
- addr_t const cap = _cap + offset;
-
- if (sizeof(ACCESS_T) == 1)
- return _config.read(_bdf, cap, Device::ACCESS_8BIT);
- if (sizeof(ACCESS_T) == 2)
- return _config.read(_bdf, cap, Device::ACCESS_16BIT);
- if (sizeof(ACCESS_T) == 4)
- return _config.read(_bdf, cap, Device::ACCESS_32BIT);
-
- warning("unsupported read ", sizeof(ACCESS_T));
- return 0;
- }
-
- template
- inline void _write(off_t const offset, ACCESS_T const value)
- {
- addr_t const cap = _cap + offset;
-
- switch (sizeof(ACCESS_T)) {
- case 1 :
- _config.write(_bdf, cap, value, Device::ACCESS_8BIT);
- break;
- case 2 :
- _config.write(_bdf, cap, value, Device::ACCESS_16BIT);
- break;
- case 4 :
- _config.write(_bdf, cap, value, Device::ACCESS_32BIT);
- break;
- default:
- warning("unsupported write ", sizeof(ACCESS_T));
- }
- }
-
- public:
-
- Config(Config_access &config, Pci::Bdf const &bdf, uint16_t cap)
- :
- Register_set(*this), _config(config), _bdf(bdf), _cap(cap)
- { }
-
-};
-
-#endif /* _X86_PCI_CONFIG_ACCESS_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_device.cc b/repos/os/src/drivers/platform/legacy/x86/pci_device.cc
deleted file mode 100644
index 30aa26399b..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/pci_device.cc
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * \brief PCI device component implementation
- * \author Alexander Boettcher
- * \author Christian Helmuth
- * \date 2022-06-24
- */
-
-/*
- * Copyright (C) 2015-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include "pci_session_component.h"
-#include "pci_device_component.h"
-
-
-Genode::Io_port_session_capability Platform::Device_component::io_port(uint8_t const v_id)
-{
- uint8_t const max = sizeof(_io_port_conn) / sizeof(_io_port_conn[0]);
- uint8_t r_id = 0;
-
- for (unsigned i = 0; i < max; ++i) {
- Pci::Resource res = _device_config.resource(i);
-
- if (!res.valid() || res.mem())
- continue;
-
- if (v_id != r_id) {
- ++r_id;
- continue;
- }
-
- if (_io_port_conn[v_id] != nullptr)
- return _io_port_conn[v_id]->cap();
-
- try {
- _io_port_conn[v_id] = new (_slab_ioport)
- Io_port_connection(_env, res.base(), res.size());
- return _io_port_conn[v_id]->cap();
- } catch (...) {
- return Io_port_session_capability();
- }
- }
-
- return Io_port_session_capability();
-}
-
-Genode::Io_mem_session_capability Platform::Device_component::io_mem(uint8_t const v_id,
- Cache const caching,
- addr_t const offset,
- size_t const size)
-{
- uint8_t max = sizeof(_io_mem) / sizeof(_io_mem[0]);
- uint8_t r_id = 0;
-
- for (unsigned i = 0; i < max; ++i) {
- Pci::Resource res = _device_config.resource(i);
-
- if (!res.valid() || !res.mem())
- continue;
-
- if (v_id != r_id) {
- ++r_id;
- continue;
- }
-
- /* limit IO_MEM session size to resource size */
- size_t const res_size = min(size, res.size());
-
- if (offset >= res.size() || offset > res.size() - res_size)
- return Io_mem_session_capability();
-
- /* error if MEM64 resource base address above 4G on 32-bit */
- if (res.base() > ~(addr_t)0) {
- error("request for MEM64 resource of ", _device_config,
- " at ", Hex(res.base()), " not supported on 32-bit system");
- return Io_mem_session_capability();
- }
-
- try {
- bool const wc = caching == Cache::WRITE_COMBINED;
- Io_mem * io_mem = new (_slab_iomem) Io_mem(_env,
- res.base() + offset,
- res_size, wc);
- _io_mem[i].insert(io_mem);
- return io_mem->cap();
- }
- catch (Out_of_caps) {
- warning("Out_of_caps in Device_component::io_mem");
- throw;
- }
- catch (Out_of_ram) {
- warning("Out_of_ram in Device_component::io_mem");
- throw;
- }
- catch (...) {
- warning("unhandled exception in 'Device_component::io_mem'");
- return Io_mem_session_capability();
- }
- }
-
- return Io_mem_session_capability();
-}
-
-
-unsigned Platform::Device_component::config_read(unsigned char address, Access_size size)
-{
- if (pci_device())
- return _device_config.read(_config_access, address, size,
- _device_config.DONT_TRACK_ACCESS);
-
- return ~0;
-}
-
-
-void Platform::Device_component::config_write(unsigned char address,
- unsigned value,
- Access_size size)
-{
- if (!pci_device())
- return;
-
- /* white list of ports which we permit to write */
- switch (address) {
- case 0x40 ... 0xff:
- /* allow access to device-specific registers if not used by us */
- if (!_device_config.reg_in_use(_config_access, address, size))
- break;
-
- error(_device_config, " write access to "
- "address=", Hex(address), " "
- "value=", Hex(value), " "
- "size=", Hex(size), " "
- "denied - it is used by the platform driver.");
- return;
- case Device_config::PCI_CMD_REG: /* COMMAND register - first byte */
- if (size == Access_size::ACCESS_16BIT)
- break;
- [[fallthrough]];
- case Device_config::PCI_CMD_REG + 1: /* COMMAND register - second byte */
- case 0xd: /* Latency timer */
- if (size == Access_size::ACCESS_8BIT)
- break;
- [[fallthrough]];
- default:
- warning(_device_config, " write access to "
- "address=", Hex(address), " "
- "value=", Hex(value), " "
- "size=", Hex(size), " "
- "got dropped");
- return;
- }
-
- /* assign device to device_pd */
- if (!_device_assigned &&
- address == Device_config::PCI_CMD_REG &&
- (value & Device_config::PCI_CMD_DMA)) {
-
- try { _session.assign_device(this); }
- catch (Out_of_ram) { throw; }
- catch (Out_of_caps) { throw; }
- catch (...) {
- error("assignment to device failed");
- }
- _device_assigned = true;
- _device_used = true;
- }
-
- _device_config.write(_config_access, address, value, size,
- _device_config.DONT_TRACK_ACCESS);
-}
-
-Genode::Irq_session_capability Platform::Device_component::irq(uint8_t id)
-{
- if (id != 0)
- return Irq_session_capability();
-
- if (_irq_session)
- return _irq_session->cap();
-
- if (!pci_device()) {
- /* Non PCI devices */
- _irq_session = construct_at(_mem_irq_component,
- _irq_line, ~0UL,
- _env,
- _global_heap);
-
- _env.ep().rpc_ep().manage(_irq_session);
- return _irq_session->cap();
- }
-
- uint16_t const msi_cap = _msi_cap();
- uint16_t const msix_cap = _msix_cap();
- bool const try_msi_msix = (_session.msi_usage() && msi_cap) ||
- (_session.msix_usage() && msix_cap);
- _irq_session = construct_at(_mem_irq_component,
- _configure_irq(_irq_line, msi_cap, msix_cap),
- try_msi_msix ? _config_space : ~0UL,
- _env, _global_heap);
- _env.ep().rpc_ep().manage(_irq_session);
-
- bool msix_used = false;
- bool msi_used = false;
-
- if (_irq_session->msi()) {
- if (_session.msix_usage() && msix_cap)
- msix_used = _setup_msix(msix_cap);
- if (!msix_used && msi_cap)
- msi_used = _setup_msi(msi_cap);
- }
-
- if (_irq_session->msi())
- log(_device_config, " uses ",
- msix_used ? "MSI-X " : "",
- (msix_used && msi_cap) ? "(supports MSI) " : "",
- msi_used ? "MSI ": "",
- (msi_used && msix_cap) ? "(supports MSI-X) " : "",
- (!msi_used && !msix_used) ? "no MSI/-X/IRQ " : "",
- "vector ", Hex(_irq_session->msi_data()), ", "
- "address ", Hex(_irq_session->msi_address()));
- else
- log(_device_config, " uses IRQ, vector ",
- Hex(_irq_line),
- (msi_cap || msix_cap) ? ", supports:" : "",
- msi_cap ? " MSI" : "",
- msix_cap ? " MSI-X" : "");
-
- return _irq_session->cap();
-}
-
-bool Platform::Device_component::_setup_msi(uint16_t const msi_cap)
-{
- try {
- addr_t const msi_address = _irq_session->msi_address();
- uint32_t const msi_value = _irq_session->msi_data();
-
- uint16_t msi = _read_config_16(msi_cap + 2);
-
- _write_config_32(msi_cap + 0x4, msi_address);
-
- if (msi & CAP_MSI_64) {
- uint32_t upper_address = sizeof(msi_address) > 4
- ? uint64_t(msi_address) >> 32
- : 0UL;
-
- _write_config_16(msi_cap + 0x8, upper_address);
- _write_config_16(msi_cap + 0xc, msi_value);
- } else
- _write_config_16(msi_cap + 0x8, msi_value);
-
- /* enable MSI */
- _device_config.write(_config_access, msi_cap + 2,
- msi ^ MSI_ENABLED,
- Platform::Device::ACCESS_8BIT);
-
- msi = _read_config_16(msi_cap + 2);
-
- return msi & MSI_ENABLED;
- } catch (...) { }
-
- return false;
-}
-
-bool Platform::Device_component::_setup_msix(uint16_t const msix_cap)
-{
- try {
- struct Table_pba : Register<32>
- {
- struct Bir : Bitfield<0, 3> { };
- struct Offset : Bitfield<3, 29> { };
- };
-
- addr_t const msi_address = _irq_session->msi_address();
- uint32_t const msi_value = _irq_session->msi_data();
-
- uint16_t ctrl = _read_config_16(msix_cap + 2);
-
- uint32_t const slots = Msix_ctrl::Slots::get(ctrl) + 1;
-
- uint32_t const table = _read_config_32(msix_cap + 4);
- uint8_t const table_bir = Table_pba::Bir::masked(table);
- uint32_t const table_off = Table_pba::Offset::masked(table);
-
- enum { SIZEOF_MSI_TABLE_ENTRY = 16, SIZE_IOMEM = 0x1000 };
-
- Pci::Resource res = _device_config.resource(table_bir);
- if (!slots || !res.valid() || res.size() < SIZE_IOMEM ||
- table_off > res.size() - SIZE_IOMEM)
- return false;
-
- if (slots * SIZEOF_MSI_TABLE_ENTRY > SIZE_IOMEM)
- return false;
-
- uint64_t const msix_table_phys = res.base() + table_off;
-
- apply_msix_table(res, msix_table_phys, SIZE_IOMEM,
- [&](addr_t const msix_table)
- {
- struct Msi_entry : public Mmio {
- Msi_entry(addr_t const base) : Mmio(base) { }
-
- struct Address_low : Register<0x0, 32> { };
- struct Address_high : Register<0x4, 32> { };
- struct Value : Register<0x8, 32> { };
- struct Vector : Register<0xc, 32> {
- struct Mask : Bitfield <0, 1> { };
- };
- } msi_entry_0 (msix_table);
-
- /* setup first msi-x table entry */
- msi_entry_0.write(msi_address & ~(0x3UL));
- msi_entry_0.write(sizeof(msi_address) == 4 ? 0 : msi_address >> 32);
- msi_entry_0.write(msi_value);
- msi_entry_0.write(0);
-
- /* disable all msi-x table entries beside the first one */
- for (unsigned i = 1; i < slots; i++) {
- struct Msi_entry unused (msix_table + SIZEOF_MSI_TABLE_ENTRY * i);
- unused.write(1);
- }
-
- /* enable MSI-X */
- Msix_ctrl::Fmask::set(ctrl, 0);
- Msix_ctrl::Enable::set(ctrl, 1);
- _write_config_16(msix_cap + 2, ctrl);
- });
-
- /* check back that MSI-X got enabled */
- ctrl = _read_config_16(msix_cap + 2);
-
- return Msix_ctrl::Enable::get(ctrl);
- } catch (Out_of_caps) {
- warning("Out_of_caps during MSI-X enablement"); }
- catch (Out_of_ram) {
- warning("Out_of_ram during MSI-X enablement"); }
- catch (...) { warning("MSI-X enablement failed"); }
-
- return false;
-}
diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_device_component.h b/repos/os/src/drivers/platform/legacy/x86/pci_device_component.h
deleted file mode 100644
index db3d92da36..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/pci_device_component.h
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * \brief platform device component
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _PCI_DEVICE_COMPONENT_H_
-#define _PCI_DEVICE_COMPONENT_H_
-
-/* base */
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* os */
-#include
-
-/* local */
-#include "pci_device_config.h"
-#include "irq.h"
-
-namespace Platform {
- class Device_component;
- class Session_component;
-
- typedef String<10> Device_name_string;
-
- typedef Registry > Device_bars_pool;
-}
-
-
-class Platform::Device_component : public Rpc_object,
- private List::Element
-{
- private:
-
- friend class List;
-
- /*
- * Noncopyable
- */
- Device_component(Device_component const &);
- Device_component &operator = (Device_component const &);
-
- Env &_env;
- Pci::Config::Delayer &_delayer;
- Device_bars_pool &_devices_bars;
- Device_config _device_config { };
- addr_t _config_space;
- Config_access _config_access;
- Platform::Session_component &_session;
- Irq_session_component *_irq_session = nullptr;
- unsigned short _irq_line;
- bool _device_used { false };
- bool _device_assigned { false };
- Allocator &_global_heap;
-
- class Io_mem : public Io_mem_connection,
- private List::Element
- {
- private:
-
- friend class List;
- friend class Platform::Device_component;
-
- public:
-
- addr_t const base;
- size_t const size;
-
- Io_mem(Env &env, addr_t base, size_t size, bool wc)
- :
- Io_mem_connection(env, base, size, wc),
- base(base), size(size)
- { }
- };
-
- enum {
- IO_BLOCK_SIZE = sizeof(Io_port_connection) *
- Device::NUM_RESOURCES + 32 + 8 * sizeof(void *),
- IO_MEM_SIZE = sizeof(Io_mem) *
- Device::NUM_RESOURCES + 32 + 8 * sizeof(void *),
- PCI_IRQ_LINE = 0x3c,
- PCI_IRQ_PIN = 0x3d,
-
- CAP_MSI_64 = 0x80,
- MSI_ENABLED = 0x1
- };
-
- struct Msix_ctrl : Register<16>
- {
- struct Slots : Bitfield< 0, 10> { };
- struct Fmask : Bitfield<14, 1> { };
- struct Enable : Bitfield<15, 1> { };
- };
-
- struct Pci_express : Pci::Config
- {
- Pci_express(Device_component &dev, uint16_t cap)
- : Pci::Config(dev._config_access, dev._device_config.bdf(), cap) { }
-
- struct Capabilities : Register<0x04, 32> {
- struct Reset : Bitfield< 28, 1> { }; };
- struct Control: Register<0x08, 16> {
- struct Reset : Bitfield< 15, 1> { }; };
- struct Status: Register<0x0a, 16> {
- struct Pending : Bitfield< 5, 1> { }; };
- struct Capabilities2 : Register<0x24, 32> {
- struct Readiness : Bitfield<31, 1> { }; };
- struct Status2 : Register<0x32, 16> {
- struct Readiness_status : Bitfield<15, 1> { }; };
- };
-
- struct Pci_power: Pci::Config
- {
- Pci_power(Device_component &dev, uint16_t cap)
- : Pci::Config(dev._config_access, dev._device_config.bdf(), cap) { }
-
- struct Capabilities : Register<0x02, 16>
- {
- struct Specific_init : Bitfield< 5, 1> { };
- };
- struct Control : Register<0x04, 16>
- {
- struct D0_3 : Bitfield< 0, 2> { };
- struct No_soft_reset : Bitfield< 3, 1> { };
- };
- };
-
-
- Tslab _slab_ioport;
- char _slab_ioport_block_data[IO_BLOCK_SIZE];
-
- Tslab _slab_iomem;
- char _slab_iomem_block_data[IO_MEM_SIZE];
-
- char _mem_irq_component[sizeof(Irq_session_component)];
-
- Io_port_connection *_io_port_conn[Device::NUM_RESOURCES];
-
- /* list of requested resource chunks per BAR */
- List _io_mem[Device::NUM_RESOURCES];
-
- struct Status : Register<8>
- {
- struct Capabilities : Bitfield<4,1> { };
-
- inline static access_t read(uint8_t t) { return t; }
- };
-
- /**
- * Convenience functions to increase readability of code
- */
- uint16_t _read_config_16(uint16_t const cap)
- {
- return _device_config.read(_config_access, cap,
- Platform::Device::ACCESS_16BIT);
- }
-
- void _write_config_16(uint16_t const cap, uint16_t const value)
- {
- _device_config.write(_config_access, cap, value,
- Platform::Device::ACCESS_16BIT);
- }
-
- uint32_t _read_config_32(uint16_t const cap)
- {
- return _device_config.read(_config_access, cap,
- Platform::Device::ACCESS_32BIT);
- }
-
- void _write_config_32(uint16_t const cap, uint32_t const value)
- {
- _device_config.write(_config_access, cap, value,
- Platform::Device::ACCESS_32BIT);
- }
-
- /**
- * Read out msi capabilities of the device.
- */
- uint16_t _msi_cap()
- {
- enum { CAP_MSI = 0x5 };
- return _lookup_cap(CAP_MSI);
- }
-
- uint16_t _msix_cap()
- {
- enum { CAP_MSI_X = 0x11 };
- return _lookup_cap(CAP_MSI_X);
- }
-
- uint16_t _power_cap()
- {
- enum { CAP_POWER = 0x1 };
- return _lookup_cap(CAP_POWER);
- }
-
- /* PCI express cap (not PCI express extended cap!) */
- uint16_t _pcie_cap()
- {
- enum { CAP_PCIE = 0x10 };
- return _lookup_cap(CAP_PCIE);
- }
-
- uint16_t _lookup_cap(uint16_t const target_cap)
- {
- enum { PCI_STATUS = 0x6, PCI_CAP_OFFSET = 0x34 };
-
- Status::access_t status = Status::read(_read_config_16(PCI_STATUS));
- if (!Status::Capabilities::get(status))
- return 0;
-
- uint8_t cap = _read_config_16(PCI_CAP_OFFSET);
-
- for (uint16_t val = 0; cap; cap = val >> 8) {
- val = _read_config_16(cap);
- if ((val & 0xff) != target_cap)
- continue;
-
- return cap;
- }
-
- return 0;
- }
-
-
- /**
- * Disable MSI/MSI-X if already enabled.
- */
- unsigned _configure_irq(unsigned irq, uint16_t const msi_cap,
- uint16_t const msix_cap)
- {
- uint8_t pin = _device_config.read(_config_access, PCI_IRQ_PIN,
- Platform::Device::ACCESS_8BIT);
- if (!pin)
- return Irq_session_component::INVALID_IRQ;
-
- /* lookup rewrite information as provided by acpi table */
- uint16_t irq_r = Irq_routing::rewrite(_device_config.bdf(), pin);
- if (irq_r) {
- log(_device_config, " adjust IRQ as reported by ACPI: ",
- irq, " -> ", irq_r);
-
- _irq_line = irq = irq_r;
- }
-
- if (msi_cap) {
- uint16_t msi = _read_config_16(msi_cap + 2);
-
- if (msi & MSI_ENABLED)
- /* disable MSI */
- _device_config.write(_config_access, msi_cap + 2,
- msi ^ MSI_ENABLED,
- Platform::Device::ACCESS_8BIT);
- }
-
- if (msix_cap) {
- uint16_t msix = _read_config_16(msix_cap + 2);
-
- if (Msix_ctrl::Enable::get(msix)) {
- Msix_ctrl::Enable::set(msix, 0);
-
- _write_config_16(msix_cap + 2, msix);
- }
- }
-
- return irq;
- }
-
-
- /**
- * Disable bus master dma if already enabled.
- */
- void _disable_bus_master_dma()
- {
- /*
- * Disabling a bridge may make the devices behind non-functional,
- * as we have no driver which will switch it on again
- */
- if (_device_config.pci_bridge() ||
- _device_config.bdf() == Pci::Bdf::from_value(Platform::Bridge::root_bridge_bdf))
- return;
-
- _device_config.disable_bus_master_dma(_config_access);
- }
-
- bool _setup_msi(uint16_t);
- bool _setup_msix(uint16_t);
-
- template
- void apply_msix_table(Pci::Resource const &lookup,
- addr_t const msix_table_phys,
- size_t const msix_table_size,
- FUNC const &fn)
- {
- uint8_t max = sizeof(_io_mem) / sizeof(_io_mem[0]);
- for (unsigned i = 0; i < max; ++i) {
- Pci::Resource res = _device_config.resource(i);
-
- if (!res.valid() || !res.mem())
- continue;
-
- if (res.base() != lookup.base() || res.size() != lookup.size())
- continue;
-
- for (Io_mem * io_mem = _io_mem[i].first(); io_mem; io_mem = io_mem->next()) {
-
- if (!(io_mem->base <= msix_table_phys &&
- msix_table_phys + msix_table_size <= io_mem->base + io_mem->size))
- continue;
-
- size_t const offset = msix_table_phys - io_mem->base;
-
- Attached_dataspace mem_io(_env.rm(), io_mem->dataspace());
-
- fn(reinterpret_cast(mem_io.local_addr()) + offset);
-
- return;
- }
- }
-
- /* requested io_mem not allocated by Pci::Resource - try direct */
- Io_mem io_mem(_env, msix_table_phys, msix_table_size, false);
- Attached_dataspace mem_io(_env.rm(), io_mem.dataspace());
- addr_t const offset = msix_table_phys & 0xfffull;
- addr_t const msix_table = reinterpret_cast(mem_io.local_addr()) + offset;
-
- fn(msix_table);
- }
-
- void _device_reset()
- {
- uint16_t const cap = _pcie_cap();
- if (!cap)
- return;
-
- Pci_express pci_cap(*this, cap);
-
- if (!pci_cap.read())
- return;
-
- log(_device_config, " reset function");
-
- pci_cap.write(1);
-
- try {
- /* optional use FLR Time if available instead of heuristic */
- pci_cap.wait_for(Pci::Config::Attempts(100),
- Pci::Config::Microseconds(10000), _delayer,
- Pci_express::Status::Pending::Equal(0));
- } catch (Pci::Config::Polling_timeout) {
- warning(_device_config, " reset timeout raised");
- }
- }
-
- void _power_off()
- {
- /* don't touch unused device */
- if (!_device_used)
- return;
-
- uint16_t const cap = _power_cap();
- if (!cap) {
- _disable_bus_master_dma();
- return;
- }
-
- /*
- * PCI Power Management - 8.2.2 D3 State
- *
- * "If the device driver is not capable of fully reinitializing"
- * "a function, the operating system should not put the function"
- * "into D3"
- *
- * Actually, at this point we don't know about the capabilities of
- * the actual driver.
- */
- log(_device_config, " power off");
-
- /*
- * "When placing a function into D3, the operating system software"
- * "is required to disable I/O and memory space as well as bus"
- * "mastering via the PCI Command register.
- */
- Device_config::Pci_header header (_config_access, _device_config.bdf());
-
- auto command = header.read();
- Device_config::Pci_header::Command::Dma::set(command, 0);
- Device_config::Pci_header::Command::Memory::set(command, 0);
- Device_config::Pci_header::Command::Ioport::set(command, 0);
-
- header.write(command);
-
- /* power off */
- Pci_power pci_cap(*this, cap);
- pci_cap.write(3);
- }
-
- void _power_on()
- {
- uint16_t const cap = _power_cap();
- if (!cap)
- return;
-
- Pci_power pci_cap(*this, cap);
-
- if (pci_cap.read() == 0)
- return;
-
- /* since it was off before, it got used by powering it on */
- _device_used = true;
-
- log(_device_config, " power on",
- pci_cap.read() ? ", no_soft_reset" : "",
- pci_cap.read() ? ", specific_init_required" : "");
-
- /* power on */
- pci_cap.write(0);
-
- /*
- * PCI Express 4.3 - 5.3.1.4. D3 State
- *
- * "Unless Readiness Notifications mechanisms are used ..."
- * "a minimum recovery time following a D3 hot → D0 transition of"
- * "at least 10 ms ..."
- */
- _delayer.usleep(10'000);
-
- /*
- * PCI Power Management - 3.2.4 - PMCSR Power Management Control/Status
- *
- * "no additional operating system intervention is required ..."
- * "beyond writing the PowerState"
- */
- if (pci_cap.read())
- return;
-
- _device_reset();
-
- _devices_bars.for_each([&](auto const &bars) {
- if (!(bars.bdf == _device_config.bdf()))
- return;
-
- _device_config.restore_bars(_config_access, bars);
- });
-
- /* re-read the resources which set to valid ones after power on */
- _device_config = Device_config(_device_config.bdf(),
- &_config_access);
- }
-
- public:
-
- /**
- * Constructor for PCI devices
- */
- Device_component(Env &env,
- Device_config device_config, addr_t addr,
- Config_access &config_access,
- Platform::Session_component &session,
- Allocator &md_alloc,
- Allocator &global_heap,
- Pci::Config::Delayer &delayer,
- Device_bars_pool &devices_bars)
- :
- _env(env),
- _delayer(delayer),
- _devices_bars(devices_bars),
- _device_config(device_config), _config_space(addr),
- _config_access(config_access),
- _session(session),
- _irq_line(_device_config.read(_config_access, PCI_IRQ_LINE,
- Platform::Device::ACCESS_8BIT)),
- _global_heap(global_heap),
- _slab_ioport(&md_alloc, &_slab_ioport_block_data),
- _slab_iomem(&md_alloc, &_slab_iomem_block_data)
- {
- for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
- _io_port_conn[i] = nullptr;
- }
-
- _power_on();
- }
-
- /**
- * Constructor for non PCI devices
- */
- Device_component(Env &env,
- Attached_io_mem_dataspace &pciconf,
- Platform::Session_component &session, unsigned irq,
- Allocator &global_heap,
- Pci::Config::Delayer &delayer,
- Device_bars_pool &devices_bars)
- :
- _env(env),
- _delayer(delayer),
- _devices_bars(devices_bars),
- _config_space(~0UL),
- _config_access(pciconf),
- _session(session),
- _irq_line(irq),
- _global_heap(global_heap),
- _slab_ioport(nullptr, &_slab_ioport_block_data),
- _slab_iomem(nullptr, &_slab_iomem_block_data)
- {
- for (unsigned i = 0; i < Device::NUM_RESOURCES; i++)
- _io_port_conn[i] = nullptr;
- }
-
- /**
- * De-constructor
- */
- ~Device_component()
- {
- if (_irq_session) {
- _env.ep().rpc_ep().dissolve(_irq_session);
- _irq_session->~Irq_session_component();
- }
-
- for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
- if (_io_port_conn[i])
- destroy(_slab_ioport, _io_port_conn[i]);
-
- while (Io_mem * io_mem = _io_mem[i].first()) {
- _io_mem[i].remove(io_mem);
- destroy(_slab_iomem, io_mem);
- }
- }
-
- if (!pci_device())
- return;
-
- _power_off();
- }
-
- /* distinct non-PCI and PCI devices */
- bool pci_device() const { return _device_config.valid(); }
-
- /****************************************
- ** Methods used solely by pci session **
- ****************************************/
-
- Device_config device_config() const { return _device_config; }
- addr_t config_space() const { return _config_space; }
-
- virtual Device_name_string name() const { return "PCI"; }
-
- template
- void for_each_device(FUNC const &fn) const
- {
- fn(*this);
-
- for (auto *dev = this; dev; dev = dev->next()) {
- fn(*dev); }
- }
-
- /**************************
- ** PCI-device interface **
- **************************/
-
- void bus_address(unsigned char *bus, unsigned char *dev,
- unsigned char *fn) override
- {
- *bus = _device_config.bdf().bus;
- *dev = _device_config.bdf().device;
- *fn = _device_config.bdf().function;
- }
-
- unsigned short vendor_id() override { return _device_config.vendor_id(); }
-
- unsigned short device_id() override { return _device_config.device_id(); }
-
- unsigned class_code() override { return _device_config.class_code(); }
-
- Resource resource(int resource_id) override
- {
- if (pci_device())
- return _device_config.resource(resource_id).api_resource();
-
- /* return invalid resource if device is invalid */
- return Resource(0, 0);
- }
-
- unsigned config_read(unsigned char address, Access_size size) override;
-
- void config_write(unsigned char address, unsigned value,
- Access_size size) override;
-
- Irq_session_capability irq(uint8_t) override;
-
- Io_port_session_capability io_port(uint8_t) override;
-
- Io_mem_session_capability io_mem(uint8_t, Cache, addr_t, size_t) override;
-};
-
-#endif /* _PCI_DEVICE_COMPONENT_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_device_config.h b/repos/os/src/drivers/platform/legacy/x86/pci_device_config.h
deleted file mode 100644
index 0478bc988b..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/pci_device_config.h
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * \brief PCI device configuration
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2008-01-29
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _X86__PCI_DEVICE_CONFIG_H_
-#define _X86__PCI_DEVICE_CONFIG_H_
-
-#include
-#include
-#include
-#include "pci_config_access.h"
-
-
-namespace Platform { namespace Pci { struct Resource; } }
-
-
-class Platform::Pci::Resource
-{
- public:
-
- struct Bar : Register<32>
- {
- struct Space : Bitfield<0,1> { enum { MEM = 0, PORT = 1 }; };
-
- struct Mem_type : Bitfield<1,2> { enum { MEM32 = 0, MEM64 = 2 }; };
- struct Mem_prefetch : Bitfield<3,1> { };
- struct Mem_address_mask : Bitfield<4,28> { };
- struct Port_address_mask : Bitfield<2,14> { };
-
- static bool mem(access_t r) { return Space::get(r) == Space::MEM; }
- static bool mem64(access_t r) { return mem(r)
- && Mem_type::get(r) == Mem_type::MEM64; }
- static uint64_t mem_address(access_t r0, uint64_t r1) { return (r1 << 32) | Mem_address_mask::masked(r0); }
- static uint64_t mem_size(access_t r0, uint64_t r1) { return ~mem_address(r0, r1) + 1; }
-
- static uint16_t port_address(access_t r) { return Port_address_mask::masked(r); }
- static uint16_t port_size(access_t r) { return ~port_address(r) + 1; }
- };
-
- private:
-
- uint32_t _bar[2] { 0, 0 }; /* contains two consecutive BARs for MEM64 */
- uint64_t _size { 0 };
-
- public:
-
- /* invalid resource */
- Resource() { }
-
- /* PORT or MEM32 resource */
- Resource(uint32_t bar, uint32_t size)
- :
- _bar{bar, 0}, _size(mem() ? Bar::mem_size(size, ~0) : Bar::port_size(size))
- { }
-
- /* MEM64 resource */
- Resource(uint32_t bar0, uint32_t size0, uint32_t bar1, uint32_t size1)
- : _bar{bar0, bar1}, _size(Bar::mem_size(size0, size1))
- { }
-
- bool valid() const { return !!_bar[0]; } /* no base address -> invalid */
- bool mem() const { return Bar::mem(_bar[0]); }
- bool mem64() const { return mem() && Bar::mem64(_bar[0]); }
- uint64_t base() const { return mem() ? Bar::mem_address(_bar[0], _bar[1])
- : Bar::port_address(_bar[0]); }
- uint64_t size() const { return _size; }
-
- Platform::Device::Resource api_resource()
- {
- /*
- * The API type limits to 32-bit currently (defined in
- * spec/x86/platform_device/platform_device.h)
- */
- return Device::Resource((unsigned)_bar[0], (unsigned)_size);
- }
-
- void print(Output &out) const
- {
- Genode::print(out, Hex_range(base(), size()));
- Genode::print(out, " (");
- Genode::print(out, valid() ? mem() ? Bar::mem64(_bar[0]) ? "MEM64" : "MEM" : "IO" : "invalid");
- Genode::print(out, ")");
- }
-};
-
-
-namespace Platform {
-
- class Device_config
- {
- private:
-
- Pci::Bdf _bdf;
-
- /*
- * Information provided by the PCI config space
- */
- unsigned _vendor_id = 0, _device_id = 0;
- unsigned _class_code = 0;
- unsigned _header_type = 0;
-
- /*
- * Header type definitions
- */
- enum {
- HEADER_FUNCTION = 0,
- HEADER_PCI_TO_PCI = 1,
- HEADER_CARD_BUS = 2
- };
-
- Platform::Pci::Resource _resource[Device::NUM_RESOURCES];
-
- bool _resource_id_is_valid(int resource_id) const
- {
- /*
- * The maximum number of PCI resources depends on the
- * header type of the device.
- */
- int max_num = _header_type == HEADER_FUNCTION ? Device::NUM_RESOURCES
- : _header_type == HEADER_PCI_TO_PCI ? 2
- : 0;
-
- return resource_id >= 0 && resource_id < max_num;
- }
-
- enum { INVALID_VENDOR = 0xffffU };
-
- public:
-
- enum { MAX_BUSES = 256, MAX_DEVICES = 32, MAX_FUNCTIONS = 8 };
-
- enum {
- PCI_CMD_REG = 0x4,
- PCI_CMD_MASK = 0x7, /* IOPORT (1), MEM(2), DMA(4) */
- PCI_CMD_DMA = 0x4,
- };
-
- struct Pci_header : Pci::Config
- {
- Pci_header(Config_access &access, Pci::Bdf const bdf)
- : Pci::Config(access, bdf, 0 /* from start */) { }
-
- struct Command : Register<0x04, 16>
- {
- struct Ioport : Bitfield< 0, 1> { };
- struct Memory : Bitfield< 1, 1> { };
- struct Dma : Bitfield< 2, 1> { };
- };
- };
-
- struct Device_bars
- {
- Pci::Bdf bdf;
-
- uint32_t bar_addr[Device::NUM_RESOURCES] { };
-
- bool all_invalid() const
- {
- for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
- if (bar_addr[i] != 0 && bar_addr[i] != ~0U)
- return false;
- }
- return true;
- }
-
- Device_bars(Pci::Bdf bdf) : bdf(bdf) { }
- virtual ~Device_bars() { };
- };
-
- /**
- * Constructor
- */
- Device_config() : _bdf({ .bus = 0, .device = 0, .function = 0 }) {
- _vendor_id = INVALID_VENDOR; }
-
- Device_config(Pci::Bdf bdf) : _bdf(bdf) { }
-
- Device_config(Pci::Bdf bdf, Config_access *pci_config) : _bdf(bdf)
- {
- _vendor_id = pci_config->read(bdf, 0, Device::ACCESS_16BIT);
-
- /* break here if device is invalid */
- if (_vendor_id == INVALID_VENDOR)
- return;
-
- _device_id = pci_config->read(bdf, 2, Device::ACCESS_16BIT);
- _class_code = pci_config->read(bdf, 8, Device::ACCESS_32BIT) >> 8;
- _class_code &= 0xffffff;
- _header_type = pci_config->read(bdf, 0xe, Device::ACCESS_8BIT);
- _header_type &= 0x7f;
-
- /*
- * We prevent scanning function 1-7 of non-multi-function
- * devices by checking bit 7 (mf bit) of function 0 of the
- * device. Note, the mf bit of function 1-7 is not significant
- * and may be set or unset.
- */
- if (bdf.function != 0) {
- Pci::Bdf const dev { .bus = bdf.bus, .device = bdf.device, .function = 0 };
- if (!(pci_config->read(dev, 0xe, Device::ACCESS_8BIT) & 0x80)) {
- _vendor_id = INVALID_VENDOR;
- return;
- }
- }
-
- /*
- * We iterate over all BARs but check for 64-bit memory
- * resources, which are stored in two consecutive BARs. The
- * MEM64 information is stored in the first resource entry and
- * the second resource is marked invalid.
- */
- int i = 0;
- while (_resource_id_is_valid(i)) {
-
- using Pci::Resource;
-
- /* index of base-address register in configuration space */
- unsigned const bar_idx = 0x10 + 4 * i;
-
- /* First, save initial base-address register value. */
- unsigned const bar_value = pci_config->read(bdf, bar_idx, Device::ACCESS_32BIT);
-
- /*
- * Second, determine resource size (and validity) by writing
- * a magic value (all bits set) to the base-address
- * register. In response, the device clears a number of
- * lowest-significant bits corresponding to the resource
- * size.
- */
- pci_config->write(bdf, bar_idx, ~0, Device::ACCESS_32BIT);
- unsigned const bar_size = pci_config->read(bdf, bar_idx, Device::ACCESS_32BIT);
-
- /* skip invalid resource BARs */
- if (bar_value == ~0U || bar_size == 0U) {
- _resource[i] = Resource();
- ++i;
- continue;
- }
-
- /*
- * Finally, we write back the bar-address value as assigned
- * by the BIOS.
- */
- pci_config->write(bdf, bar_idx, bar_value, Device::ACCESS_32BIT);
-
- if (!Resource::Bar::mem64(bar_value)) {
- _resource[i] = Resource(bar_value, bar_size);
- ++i;
- } else {
- /* also consume next BAR for MEM64 */
- unsigned const bar2_idx = bar_idx + 4;
- unsigned const bar2_value =
- pci_config->read(bdf, bar2_idx, Device::ACCESS_32BIT);
- pci_config->write(bdf, bar2_idx, ~0, Device::ACCESS_32BIT);
- unsigned const bar2_size =
- pci_config->read(bdf, bar2_idx, Device::ACCESS_32BIT);
- pci_config->write(bdf, bar2_idx, bar2_value, Device::ACCESS_32BIT);
-
- /* combine into first resource and mark second as invalid */
- _resource[i] = Resource(bar_value, bar_size,
- bar2_value, bar2_size);
- ++i;
- _resource[i] = Resource();
- ++i;
- }
- }
- }
-
- /**
- * Accessor function for device location
- */
- Pci::Bdf bdf() const { return _bdf; }
-
- void print(Output &out) const { Genode::print(out, bdf()); }
-
- /**
- * Accessor functions for device information
- */
- unsigned short device_id() { return _device_id; }
- unsigned short vendor_id() { return _vendor_id; }
- unsigned int class_code() { return _class_code; }
-
- /**
- * Return true if device is a PCI bridge
- */
- bool pci_bridge() const { return _header_type == HEADER_PCI_TO_PCI; }
-
- /**
- * Return true if device is valid
- */
- bool valid() const { return _vendor_id != INVALID_VENDOR; }
-
- /**
- * Return resource description by resource ID
- */
- Platform::Pci::Resource resource(int resource_id)
- {
- /* return invalid resource if sanity check fails */
- if (!_resource_id_is_valid(resource_id))
- return Platform::Pci::Resource();
-
- return _resource[resource_id];
- }
-
- void remap_resource(Config_access &config, int const id,
- uint64_t const base_address)
- {
- if (!_resource_id_is_valid(id))
- return;
-
- using Pci::Resource;
-
- Resource &res = _resource[id];
-
- log(*this, " remap BAR", id, " ", res, " to ", Hex(base_address));
-
- struct Resource_params { uint32_t bar; uint32_t size; };
-
- auto update_bar = [&] (int const id, uint32_t const address) {
- unsigned const off = 0x10 + 4 * id;
-
- config.write(_bdf, off, ~0U, Device::ACCESS_32BIT);
-
- uint32_t const size = config.read(_bdf, off, Device::ACCESS_32BIT);
-
- config.write(_bdf, off, address, Device::ACCESS_32BIT);
-
- return Resource_params {
- .bar = config.read(_bdf, off, Device::ACCESS_32BIT),
- .size = size
- };
- };
-
- Resource_params const bar0 = update_bar(id, base_address & 0xffffffff);
-
- if (!res.mem64()) {
- res = Resource(bar0.bar, bar0.size);
- return;
- }
-
- Resource_params const bar1 = update_bar(id + 1, (base_address >> 32) & 0xffffffff);
-
- res = Resource(bar0.bar, bar0.size, bar1.bar, bar1.size);
- }
-
- template void for_each_resource(FN const &fn) const
- {
- for (unsigned r = 0; r < Device::NUM_RESOURCES; r++) {
- if (!_resource_id_is_valid(r))
- break;
-
- if (_resource[r].valid())
- fn(r, _resource[r]);
- }
- }
-
- /**
- * Read configuration space
- */
- enum { DONT_TRACK_ACCESS = false };
- unsigned read(Config_access &pci_config, unsigned char address,
- Device::Access_size size, bool track = true)
- {
- return pci_config.read(_bdf, address, size, track);
- }
-
- /**
- * Write configuration space
- */
- void write(Config_access &pci_config, unsigned char address,
- unsigned long value, Device::Access_size size,
- bool track = true)
- {
- pci_config.write(_bdf, address, value, size, track);
- }
-
- bool reg_in_use(Config_access &pci_config, unsigned char address,
- Device::Access_size size) {
- return pci_config.reg_in_use(address, size); }
-
- void disable_bus_master_dma(Config_access &pci_config)
- {
- Pci_header header (pci_config, _bdf);
-
- if (header.read())
- header.write(0);
- }
-
- Device_bars save_bars()
- {
- Device_bars bars (_bdf);
-
- for (unsigned r = 0; r < Device::NUM_RESOURCES; r++) {
- if (!_resource_id_is_valid(r))
- break;
-
- bars.bar_addr[r] = _resource[r].base();
- }
-
- return bars;
- };
-
- void restore_bars(Config_access &config, Device_bars const &bars)
- {
- for (unsigned r = 0; r < Device::NUM_RESOURCES; r++) {
- if (!_resource_id_is_valid(r))
- break;
-
- /* index of base-address register in configuration space */
- unsigned const bar_idx = 0x10 + 4 * r;
-
- /* PCI protocol to write address after requesting size */
- config.write(_bdf, bar_idx, ~0U, Device::ACCESS_32BIT);
- config.read (_bdf, bar_idx, Device::ACCESS_32BIT);
- config.write(_bdf, bar_idx, bars.bar_addr[r],
- Device::ACCESS_32BIT);
- }
- }
- };
-
- class Config_space : private List::Element
- {
- private:
-
- friend class List;
-
- uint32_t _bdf_start;
- uint32_t _func_count;
- addr_t _base;
-
- public:
-
- using List::Element::next;
-
- Config_space(uint32_t bdf_start, uint32_t func_count, addr_t base)
- :
- _bdf_start(bdf_start), _func_count(func_count), _base(base) {}
-
- addr_t lookup_config_space(Pci::Bdf const bdf)
- {
- if ((_bdf_start <= bdf.value()) && (bdf.value() <= _bdf_start + _func_count - 1))
- return _base + (unsigned(bdf.value()) << 12);
- return 0;
- }
- };
-}
-
-#endif /* _X86__PCI_DEVICE_CONFIG_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/pci_session_component.h b/repos/os/src/drivers/platform/legacy/x86/pci_session_component.h
deleted file mode 100644
index ddf2828faa..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/pci_session_component.h
+++ /dev/null
@@ -1,1224 +0,0 @@
-/*
- * \brief Platform session component
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _PCI_SESSION_COMPONENT_H_
-#define _PCI_SESSION_COMPONENT_H_
-
-/* base */
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-/* os */
-#include
-#include
-#include
-#include
-
-/* local */
-#include "device_pd.h"
-#include "pci_bridge.h"
-#include "pci_config_access.h"
-#include "pci_device_component.h"
-
-namespace Platform {
-
- unsigned short bridge_bdf(unsigned char bus);
-
- class Pci_buses;
- class Ram_dataspace;
- class Rmrr;
- class Root;
- class Session_component;
-}
-
-
-class Platform::Ram_dataspace : public List::Element
-{
- private:
-
- Ram_dataspace_capability const _cap;
-
- public:
-
- Ram_dataspace(Ram_dataspace_capability c) : _cap(c) { }
-
- bool match(const Ram_dataspace_capability &cap) const {
- return cap.local_name() == _cap.local_name(); }
-
- Ram_dataspace_capability cap() const { return _cap; }
-};
-
-
-class Platform::Rmrr : public List::Element
-{
- public:
-
- class Bdf : public List::Element
- {
- private:
-
- uint8_t _bus, _dev, _func;
-
- public:
-
- Bdf(uint8_t bus, uint8_t dev, uint8_t func)
- : _bus(bus), _dev(dev), _func(func) { }
-
- bool match(Pci::Bdf const bdf)
- {
- return bdf.bus == _bus && bdf.device == _dev &&
- bdf.function == _func;
- }
- };
-
- private:
-
- uint64_t const _start, _end;
-
- Io_mem_dataspace_capability _cap { };
-
- List _bdf_list { };
-
- Constructible _io_mem { };
-
- public:
-
- Rmrr(uint64_t start, uint64_t end) : _start(start), _end(end) { }
-
- Io_mem_dataspace_capability match(Env &env, Device_config config)
- {
- for (Bdf *bdf = _bdf_list.first(); bdf; bdf = bdf->next()) {
- if (!bdf->match(config.bdf()))
- continue;
-
- if (_cap.valid())
- return _cap;
-
- _io_mem.construct(env, _start, _end - _start + 1);
- _cap = _io_mem->dataspace();
- return _cap;
- }
- return Io_mem_dataspace_capability();
- }
-
- addr_t start() const { return _start; }
-
- void add(Bdf * bdf) { _bdf_list.insert(bdf); }
-
- static List *list()
- {
- static List _list;
- return &_list;
- }
-};
-
-
-class Platform::Pci_buses
-{
- private:
-
- Bit_array _valid { };
-
- void _scan_bus(Config_access &, Allocator &, Device_bars_pool &,
- unsigned char bus, Xml_node const &config);
-
- bool _bus_valid(int bus)
- {
- if (bus >= Device_config::MAX_BUSES)
- return false;
-
- return _valid.get(bus, 1);
- }
-
- public:
-
- Pci_buses(Allocator &heap,
- Attached_io_mem_dataspace &pciconf,
- Device_bars_pool &devices_bars,
- Xml_node const &config_node)
- {
- Config_access c(pciconf);
- _scan_bus(c, heap, devices_bars, 0 /* root bus */, config_node);
- }
-
- /**
- * Scan PCI buses for a device
- *
- * \param bus start scanning at bus number
- * \param device start scanning at device number
- * \param function start scanning at function number
- * \param out_device_config device config information of the
- * found device
- * \param config_access interface for accessing the PCI
- * configuration
- * space
- *
- * \retval true device was found
- * \retval false no device was found
- */
- bool find_next(unsigned bus, unsigned device, unsigned function,
- Device_config *out_device_config,
- Config_access *config_access)
- {
- for (; bus < Device_config::MAX_BUSES; bus++) {
- if (!_bus_valid(bus))
- continue;
-
- for (; device < Device_config::MAX_DEVICES; device++) {
- for (; function < Device_config::MAX_FUNCTIONS; function++) {
-
- /* read config space */
- Pci::Bdf const bdf { .bus = bus, .device = device, .function = function };
- Device_config config(bdf, config_access);
-
- if (config.valid()) {
- *out_device_config = config;
- return true;
- }
- }
- function = 0; /* init value for next device */
- }
- device = 0; /* init value for next bus */
- }
- return false;
- }
-};
-
-
-class Platform::Session_component : public Rpc_object
-{
- private:
-
- Env &_env;
- Attached_rom_dataspace &_config;
- Attached_io_mem_dataspace &_pciconf;
- addr_t const _pciconf_base;
- Ram_quota_guard _ram_guard;
- Cap_quota_guard _cap_guard;
- Constrained_ram_allocator _env_ram { _env.pd(), _ram_guard, _cap_guard };
- Heap _md_alloc;
- Session_label const _label;
- List _device_list { };
- Platform::Pci_buses &_pci_bus;
- Allocator &_global_heap;
- Pci::Config::Delayer &_delayer;
- Device_bars_pool &_devices_bars;
- bool const _iommu;
- bool const _msi_avail;
- bool _msi_usage { true };
- bool _msix_usage { true };
-
- /**
- * Registry of RAM dataspaces allocated by the session
- */
- List _ram_caps { };
-
- void _insert(Ram_dataspace_capability cap) {
- _ram_caps.insert(new (_md_alloc) Platform::Ram_dataspace(cap)); }
-
- bool _owned(Ram_dataspace_capability cap)
- {
- for (Ram_dataspace *ds = _ram_caps.first(); ds; ds = ds->next())
- if (ds->match(cap))
- return true;
-
- return false;
- }
-
- bool _remove(Ram_dataspace_capability cap)
- {
- for (Platform::Ram_dataspace *ds = _ram_caps.first(); ds;
- ds = ds->next()) {
-
- if (!ds->match(cap))
- continue;
-
- _ram_caps.remove(ds);
- destroy(_md_alloc, ds);
- return true;
- }
- return false;
- }
-
- Platform::Device_pd _device_pd { _env, _label, _ram_guard, _cap_guard };
-
- enum { MAX_PCI_DEVICES = Device_config::MAX_BUSES *
- Device_config::MAX_DEVICES *
- Device_config::MAX_FUNCTIONS };
-
- static Bit_array bdf_in_use;
-
- /**
- * List containing extended PCI config space information
- */
- static List &config_space_list()
- {
- static List config_space;
- return config_space;
- }
-
- /**
- * Find for a given PCI device described by the bus:dev:func triple
- * the corresponding extended 4K PCI config space address.
- * A io mem dataspace is created and returned.
- */
- addr_t lookup_config_space(Pci::Bdf const bdf)
- {
- addr_t config_space = ~0UL; /* invalid */
-
- Config_space *e = config_space_list().first();
- for (; e && (config_space == ~0UL); e = e->next())
- config_space = e->lookup_config_space(bdf);
-
- return config_space;
- }
-
- typedef String<32> Alias_name;
-
- /*
- * List of aliases for PCI base class, sub class, and
- * programming interface triples supported in XML config
- */
- bool valid_alias(Alias_name const &name, unsigned const class_code = ~0U)
- {
- /* wildcard 0xff matches all codes */
- auto wildcard = [] (uint8_t v) { return v == 0xff; };
-
- static struct Alias {
- const char *name;
- uint8_t b, s, p; /* base class, sub class, progif */
- } const aliases [] = {
- { "ALL" , 0xff, 0xff, 0xff},
- { "AHCI" , 0x01, 0x06, 0xff},
- { "AUDIO" , 0x04, 0x01, 0xff},
- { "ETHERNET" , 0x02, 0x00, 0xff},
- { "HDAUDIO" , 0x04, 0x03, 0xff},
- { "ISABRIDGE", 0x06, 0x01, 0xff},
- { "NVME" , 0x01, 0x08, 0x02},
- { "USB" , 0x0c, 0x03, 0x00}, /* UHCI */
- { "USB" , 0x0c, 0x03, 0x10}, /* OHCI */
- { "USB" , 0x0c, 0x03, 0x20}, /* EHCI */
- { "USB" , 0x0c, 0x03, 0x30}, /* XHCI */
- { "USB4" , 0x0c, 0x03, 0x40}, /* USB4 NHI/Thunderbolt */
- { "VGA" , 0x03, 0x00, 0x00},
- { "WIFI" , 0x02, 0x80, 0xff},
- };
-
- uint8_t const b = (class_code >> 16) & 0xff;
- uint8_t const s = (class_code >> 8) & 0xff;
- uint8_t const p = class_code & 0xff;
-
- for (Alias const &alias : aliases) {
- if (name != alias.name)
- continue;
-
- if ((wildcard(b) || wildcard(alias.b) || b == alias.b)
- && (wildcard(s) || wildcard(alias.s) || s == alias.s)
- && (wildcard(p) || wildcard(alias.p) || p == alias.p))
- return true;
- }
-
- return false;
- }
-
- /**
- * Check device usage according to session policy
- */
- bool permit_device(const char * name)
- {
- Session_policy const policy { _label, _config.xml() };
-
- try {
- policy.for_each_sub_node("device", [&] (Xml_node dev) {
-
- /* enforce restriction based on name */
- if (dev.attribute_value("name", Device_name_string()) == name)
- /* found identical match - permit access */
- throw true;
- });
- } catch (bool result) { return result; }
-
- return false;
- }
-
- static bool _bdf_exactly_specified(Xml_node node)
- {
- return node.has_attribute("bus")
- && node.has_attribute("device")
- && node.has_attribute("function");
- }
-
- static bool _bdf_attributes_in_valid_range(Xml_node const &node)
- {
- return _bdf_exactly_specified(node)
- && (node.attribute_value("bus", 0U) < Device_config::MAX_BUSES)
- && (node.attribute_value("device", 0U) < Device_config::MAX_DEVICES)
- && (node.attribute_value("function", 0U) < Device_config::MAX_FUNCTIONS);
- }
-
- static bool _bdf_matches(Xml_node const &node, Pci::Bdf const &bdf)
- {
- return Pci::Bdf::from_xml(node) == bdf;
- }
-
- /**
- * Check according session policy device usage
- */
- bool permit_device(Pci::Bdf const bdf, unsigned const class_code)
- {
- try {
- Session_policy const policy { _label, _config.xml() };
-
- policy.for_each_sub_node("pci", [&] (Xml_node node) {
-
- if (_bdf_exactly_specified(node)) {
- if (_bdf_matches(node, bdf))
- throw true;
- /* check also for class entry */
- }
-
- if (!node.has_attribute("class"))
- return;
-
- /* enforce restriction based upon classes */
- auto alias = node.attribute_value("class", Alias_name());
-
- if (!valid_alias(alias, class_code))
- return;
-
- /* if this bdf is used by some policy - deny */
- if (alias != "ALL" && find_dev_in_policy(bdf))
- return;
-
- throw true;
- });
- } catch (bool result) { return result; }
-
- return false;
- }
-
- /**
- * Lookup a given device name.
- */
- bool find_dev_in_policy(const char * dev_name, bool once = true)
- {
- try {
- _config.xml().for_each_sub_node("policy", [&] (Xml_node policy) {
- policy.for_each_sub_node("device", [&] (Xml_node device) {
-
- if (device.attribute_value("name", Device_name_string()) == dev_name) {
-
- if (once)
- throw true;
- once = true;
- }
- });
- });
- } catch (bool result) { return result; }
-
- return false;
- }
-
- /**
- * Lookup a given device name.
- */
- bool find_dev_in_policy(Pci::Bdf const bdf, bool once = true)
- {
- try {
- Xml_node xml = _config.xml();
- xml.for_each_sub_node("policy", [&] (Xml_node policy) {
- policy.for_each_sub_node("pci", [&] (Xml_node node) {
-
- if (_bdf_exactly_specified(node)) {
-
- if (_bdf_matches(node, bdf)) {
-
- if (once)
- throw true;
- once = true;
- }
- }
- });
- });
- } catch (bool result) { return result; }
-
- return false;
- }
-
- public:
-
- /**
- * Constructor
- */
- Session_component(Env &env,
- Attached_rom_dataspace &config,
- Attached_io_mem_dataspace &pciconf,
- addr_t pciconf_base,
- Platform::Pci_buses &buses,
- Allocator &global_heap,
- Pci::Config::Delayer &delayer,
- Device_bars_pool &devices_bars,
- char const *args,
- bool const iommu,
- bool const msi)
- :
- _env(env),
- _config(config),
- _pciconf(pciconf),
- _pciconf_base(pciconf_base),
- _ram_guard(ram_quota_from_args(args)),
- _cap_guard(cap_quota_from_args(args)),
- _md_alloc(_env_ram, env.rm()),
- _label(label_from_args(args)),
- _pci_bus(buses),
- _global_heap(global_heap),
- _delayer(delayer),
- _devices_bars(devices_bars),
- _iommu(iommu),
- _msi_avail(msi)
- {
- /* subtract the RPC session and session dataspace capabilities */
- _cap_guard.withdraw(Cap_quota{2});
-
- check_for_policy();
- }
-
- void check_for_policy()
- {
- Session_policy const policy { _label, _config.xml() };
-
- if (_msi_avail) {
- _msi_usage = policy.attribute_value("msi", _msi_usage);
- _msix_usage = _msi_usage &&
- policy.attribute_value("msix", _msix_usage);
- } else
- _msi_usage = _msix_usage = false;
-
- /* check policy for non-pci devices */
- policy.for_each_sub_node("device", [&] (Xml_node device_node) {
-
- if (!device_node.has_attribute("name")) {
- error("'", _label, "' - device node " "misses 'name' attribute");
- throw Service_denied();
- }
-
- Device_name_string const name =
- device_node.attribute_value("name", Device_name_string());
-
- enum { DOUBLET = false };
- if (find_dev_in_policy(name.string(), DOUBLET)) {
- error("'", _label, "' - device '", name, "' "
- "is part of more than one policy");
- throw Service_denied();
- }
- });
-
- /* pci devices */
- policy.for_each_sub_node("pci", [&] (Xml_node node) {
-
- enum { INVALID_CLASS = 0x1000000U };
-
- /**
- * Valid input is either a triple of 'bus', 'device',
- * 'function' attributes or a single 'class' attribute.
- * All other attribute names are traded as wrong.
- */
- if (node.has_attribute("class")) {
-
- Alias_name const alias = node.attribute_value("class", Alias_name());
-
- if (!valid_alias(alias)) {
- error("'", _label, "' - invalid 'class' ",
- "attribute '", alias, "'");
- throw Service_denied();
- }
-
- /* sanity check that 'class' is the only attribute */
- try {
- node.attribute(1);
- error("'", _label, "' - attributes beside 'class' detected");
- throw Service_denied();
- }
- catch (Xml_attribute::Nonexistent_attribute) { }
-
- /* we have a class and it is the only attribute */
- return;
- }
-
- /* no 'class' attribute - now check for valid bdf triple */
- try {
- node.attribute(3);
- error("'", _label, "' - " "invalid number of pci node attributes");
- throw Service_denied();
-
- } catch (Xml_attribute::Nonexistent_attribute) { }
-
- if (_bdf_exactly_specified(node)) {
-
- if (!_bdf_attributes_in_valid_range(node)) {
- error("'", _label, "' - "
- "invalid pci node attributes for bdf");
- throw Service_denied();
- }
-
- Pci::Bdf const bdf = Pci::Bdf::from_xml(node);
-
- enum { DOUBLET = false };
- if (find_dev_in_policy(bdf, DOUBLET)) {
- error("'", _label, "' - device '", bdf, "' "
- "is part of more than one policy");
- throw Service_denied();
- }
- }
- });
- }
-
- bool policy_valid()
- {
- try {
- /* check that policy is available */
- check_for_policy();
- } catch (...) {
- return false;
- }
-
- /* check that device entries in policy are still permitted */
- if (!_device_list.first())
- return true;
-
- bool result = true;
-
- _device_list.first()->for_each_device([&](auto const &dev) {
-
- /* Non PCI devices */
- if (!dev.pci_device()) {
- if (!permit_device(dev.name().string()))
- result = false;
-
- return;
- }
-
- /* PCI devices */
- if (!permit_device(dev.device_config().bdf(),
- dev.device_config().class_code()))
- result = false;
- });
-
- return result;
- }
-
- /**
- * Destructor
- */
- ~Session_component()
- {
- /* release all elements of the session's device list */
- while (_device_list.first())
- release_device(_device_list.first()->cap());
-
- while (Platform::Ram_dataspace *ds = _ram_caps.first()) {
- _ram_caps.remove(ds);
- _env_ram.free(ds->cap());
- destroy(_md_alloc, ds);
- }
- }
-
-
- void upgrade_resources(Session::Resources resources)
- {
- _ram_guard.upgrade(resources.ram_quota);
- _cap_guard.upgrade(resources.cap_quota);
- }
-
-
- static void add_config_space(uint32_t bdf_start,
- uint32_t func_count,
- addr_t base,
- Allocator &heap)
- {
- Config_space * space =
- new (heap) Config_space(bdf_start, func_count, base);
- config_space_list().insert(space);
- }
-
-
- /**
- * Check whether msi usage was explicitly switched off
- */
- bool msi_usage() const { return _msi_usage; }
-
-
- /**
- * Check whether msi-x usage was explicitly switched off
- */
- bool msix_usage() const { return _msix_usage; }
-
- /***************************
- ** PCI session interface **
- ***************************/
-
- Device_capability first_device(unsigned device_class,
- unsigned class_mask) override {
- return next_device(Device_capability(), device_class, class_mask); }
-
- Device_capability next_device(Device_capability prev_device,
- unsigned device_class,
- unsigned class_mask) override
- {
- /*
- * Create the interface to the PCI config space.
- */
- Config_access config_access(_pciconf);
-
- /* lookup device component for previous device */
- auto lambda = [&] (Device_component *prev)
- {
-
- /*
- * Start bus scanning after the previous device's location.
- * If no valid device was specified for 'prev_device',
- * start at the beginning.
- */
- int bus = 0, device = 0, function = -1;
-
- if (prev) {
- Device_config config = prev->device_config();
- bus = config.bdf().bus;
- device = config.bdf().device;
- function = config.bdf().function;
- }
-
- /*
- * Scan buses for devices.
- * If no device is found, return an invalid capability.
- */
- Device_config config;
-
- while (true) {
- function += 1;
- if (!_pci_bus.find_next(bus, device, function, &config,
- &config_access))
- return Device_capability();
-
- /* get new bdf values */
- bus = config.bdf().bus;
- device = config.bdf().device;
- function = config.bdf().function;
-
- /* if filter of driver don't match skip and continue */
- if ((config.class_code() ^ device_class) & class_mask)
- continue;
-
- /* check that policy permit access to the matched device */
- if (permit_device(Pci::Bdf { (unsigned)bus,
- (unsigned)device,
- (unsigned)function },
- config.class_code()))
- break;
- }
-
- /* lookup if we have a extended pci config space */
- addr_t config_space = lookup_config_space(config.bdf());
-
- /*
- * A device was found. Create a new device component for the
- * device and return its capability.
- */
- Device_component * dev = new (_md_alloc)
- Device_component(_env, config, config_space, config_access,
- *this, _md_alloc, _global_heap, _delayer,
- _devices_bars);
-
- _device_list.insert(dev);
-
- try {
- /* if more than one driver uses the device - warn about */
- if (bdf_in_use.get(config.bdf().value(), 1))
- error("Device ", config, " is used by more than one driver - "
- "session '", _label, "'.");
- else
- bdf_in_use.set(config.bdf().value(), 1);
-
- return _env.ep().rpc_ep().manage(dev);
- } catch (...) {
- _device_list.remove(dev);
- destroy(_md_alloc, dev);
- throw;
- }
- };
- return _env.ep().rpc_ep().apply(prev_device, lambda);
- }
-
- void release_device(Device_capability device_cap) override
- {
- Device_component * device = nullptr;
- auto lambda = [&] (Device_component *d)
- {
- device = d;
- if (!device)
- return;
-
- if (device->pci_device()) {
- if (bdf_in_use.get(device->device_config().bdf().value(), 1))
- bdf_in_use.clear(device->device_config().bdf().value(), 1);
- }
-
- _device_list.remove(device);
- _env.ep().rpc_ep().dissolve(device);
- };
-
- /* lookup device component */
- _env.ep().rpc_ep().apply(device_cap, lambda);
-
- if (device)
- destroy(_md_alloc, device);
- }
-
- void assign_device(Device_component * device)
- {
- if (!device || device->config_space() == ~0UL || !_iommu)
- return;
-
- try {
- addr_t const base_ecam = _pciconf_base;
- addr_t const base_offset = 0x1000UL * device->device_config().bdf().value();
-
- if (base_ecam + base_offset != device->config_space())
- throw 1;
-
- for (Rmrr *r = Rmrr::list()->first(); r; r = r->next()) {
- Io_mem_dataspace_capability rmrr_cap = r->match(_env, device->device_config());
- if (rmrr_cap.valid())
- _device_pd.attach_dma_mem(rmrr_cap, r->start());
- }
-
- _device_pd.assign_pci(_pciconf.cap(), base_offset,
- device->device_config().bdf().value());
-
- } catch (...) {
- error("assignment to device pd or of RMRR region failed");
- }
- }
-
- /**
- * De-/Allocation of dma capable dataspaces
- */
-
- Ram_dataspace_capability alloc_dma_buffer(size_t const size, Cache cache) override
- {
- /*
- * Check available quota beforehand and reflect the state back
- * to the client because the 'Expanding_pd_session_client' will
- * ask its parent otherwise.
- */
- enum { WATERMARK_CAP_QUOTA = 8, };
- if (_env.pd().avail_caps().value < WATERMARK_CAP_QUOTA)
- throw Out_of_caps();
-
- enum { WATERMARK_RAM_QUOTA = 4096, };
- if (_env.pd().avail_ram().value < WATERMARK_RAM_QUOTA)
- throw Out_of_ram();
-
- if (!size)
- return {};
-
- Ram_dataspace_capability ram_cap = _env_ram.alloc(size, cache);
- addr_t const dma_addr = _env.pd().dma_addr(ram_cap);
-
- if (!ram_cap.valid())
- return ram_cap;
-
- try {
- _device_pd.attach_dma_mem(ram_cap, dma_addr);
- _insert(ram_cap);
- } catch (Out_of_ram) {
- _env_ram.free(ram_cap);
- throw Out_of_ram();
- } catch (Out_of_caps) {
- _env_ram.free(ram_cap);
- throw Out_of_caps();
- }
-
- return ram_cap;
- }
-
- void free_dma_buffer(Ram_dataspace_capability ram_cap) override
- {
- if (!ram_cap.valid() || !_remove(ram_cap))
- return;
-
- _env_ram.free(ram_cap);
- }
-
- addr_t dma_addr(Ram_dataspace_capability ram_cap) override
- {
- if (!ram_cap.valid() || !_owned(ram_cap))
- return 0;
-
- return _env.pd().dma_addr(ram_cap);
- }
-
- /* non-PCI devices */
- Device_capability device(Device_name const &name) override;
-};
-
-
-class Platform::Root : public Root_component
-{
- private:
-
- Env &_env;
- Allocator &_heap;
- Attached_rom_dataspace &_config;
-
- Constructible _pci_confspace { };
- addr_t _pci_confspace_base = 0;
- Constructible _pci_reporter { };
-
- Device_bars_pool _devices_bars { };
-
- Constructible _buses { };
-
- bool _iommu { false };
- bool _pci_reported { false };
- bool _msi_platform;
-
- struct Timer_delayer : Pci::Config::Delayer, Timer::Connection
- {
- Timer_delayer(Env &env) : Timer::Connection(env) { }
-
- void usleep(uint64_t us) override { Timer::Connection::usleep(us); }
- } _delayer { _env };
-
- Registry > _sessions { };
-
- void _parse_report_rom(Env &env, const char * acpi_rom,
- bool acpi_platform)
- {
- Xml_node xml_acpi(acpi_rom);
- if (!xml_acpi.has_type("acpi"))
- throw 1;
-
- xml_acpi.for_each_sub_node("bdf", [&] (Xml_node &node) {
-
- uint32_t const bdf_start = node.attribute_value("start", 0U);
- uint32_t const func_count = node.attribute_value("count", 0U);
- addr_t const base = node.attribute_value("base", 0UL);
-
- Session_component::add_config_space(bdf_start, func_count,
- base, _heap);
-
- Device_config const bdf_first(Pci::Bdf::from_value(bdf_start));
- Device_config const bdf_last(Pci::Bdf::from_value(bdf_start +
- func_count - 1));
-
- addr_t const memory_size = 0x1000UL * func_count;
-
- /* Simplification: Only consider first config space and
- * check if it is for domain 0 */
- if (bdf_start || _pci_confspace.constructed()) {
- warning("ECAM/MMCONF range ",
- bdf_first, "-", bdf_last, " - addr ",
- Hex_range(base, memory_size), " ignored");
- return;
- }
-
- log("ECAM/MMCONF range ", bdf_first, "-", bdf_last, " - addr ",
- Hex_range(base, memory_size));
-
- _pci_confspace_base = base;
- _pci_confspace.construct(env, base, memory_size);
- });
-
- if (!_pci_confspace.constructed())
- throw 2;
-
- Config_access config_access(*_pci_confspace);
-
- for (unsigned i = 0; i < xml_acpi.num_sub_nodes(); i++) {
- Xml_node node = xml_acpi.sub_node(i);
-
- if (node.has_type("bdf") || node.has_type("reset"))
- continue;
-
- if (node.has_type("irq_override")) {
- unsigned const irq = node.attribute_value("irq", 0xffU);
- unsigned const gsi = node.attribute_value("gsi", 0xffU);
- unsigned const flags = node.attribute_value("flags", 0xffU);
-
- if (!acpi_platform) {
- warning("MADT IRQ ", irq, "-> GSI ", gsi, " flags ",
- flags, " ignored");
- continue;
- }
-
- using Platform::Irq_override;
- Irq_override * o = new (_heap) Irq_override(irq, gsi,
- flags);
- Irq_override::list()->insert(o);
- continue;
- }
-
- if (node.has_type("drhd") || node.has_type("ivdb")) {
- _iommu = true;
- continue;
- }
-
- if (node.has_type("rmrr")) {
- uint64_t const
- mem_start = node.attribute_value("start", (uint64_t)0),
- mem_end = node.attribute_value("end", (uint64_t)0);
-
- if (node.num_sub_nodes() == 0)
- throw 3;
-
- Rmrr * rmrr = new (_heap) Rmrr(mem_start, mem_end);
- Rmrr::list()->insert(rmrr);
-
- for (unsigned s = 0; s < node.num_sub_nodes(); s++) {
- Xml_node scope = node.sub_node(s);
- if (!scope.num_sub_nodes() || !scope.has_type("scope"))
- throw 4;
-
- unsigned bus = 0, dev = 0, func = 0;
- scope.attribute("bus_start").value(bus);
-
- for (unsigned p = 0; p < scope.num_sub_nodes(); p++) {
- Xml_node path = scope.sub_node(p);
- if (!path.has_type("path"))
- throw 5;
-
- path.attribute("dev") .value(dev);
- path.attribute("func").value(func);
-
- Pci::Bdf const bdf = { .bus = bus, .device = dev,
- .function = func };
-
- Device_config bridge(bdf, &config_access);
- if (bridge.pci_bridge())
- /* PCI bridge spec 3.2.5.3, 3.2.5.4 */
- bus = bridge.read(config_access, 0x19,
- Device::ACCESS_8BIT);
- }
-
- rmrr->add(new (_heap) Rmrr::Bdf(bus, dev, func));
- }
- continue;
- }
-
- if (node.has_type("root_bridge")) {
- node.attribute("bdf").value(Platform::Bridge::root_bridge_bdf);
- continue;
- }
-
- if (!node.has_type("routing")) {
- error ("unsupported node '", node.type(), "'");
- throw __LINE__;
- }
-
- unsigned const gsi = node.attribute_value("gsi", 0U),
- bridge_bdf = node.attribute_value("bridge_bdf", 0U),
- device = node.attribute_value("device", 0U),
- device_pin = node.attribute_value("device_pin", 0U);
-
- /* drop routing information on non ACPI platform */
- if (!acpi_platform)
- continue;
-
- Irq_routing * r = new (_heap) Irq_routing(gsi, bridge_bdf,
- device, device_pin);
- Irq_routing::list()->insert(r);
- }
- }
-
- void _construct_buses()
- {
- Dataspace_client ds_pci_mmio(_pci_confspace->cap());
-
- uint64_t const phys_addr = _pci_confspace_base;
- uint64_t const phys_size = ds_pci_mmio.size();
- uint64_t mmio_size = 0x10000000UL; /* max MMCONF memory */
-
- /* try surviving wrong ACPI ECAM/MMCONF table information */
- while (true) {
- try {
- _buses.construct(_heap, *_pci_confspace, _devices_bars, _config.xml());
- /* construction and scan succeeded */
- break;
- } catch (Platform::Config_access::Invalid_mmio_access) {
-
- error("ECAM/MMCONF MMIO access out of bounds - "
- "ACPI table information is wrong!");
-
- _pci_confspace.destruct();
-
- while (mmio_size > phys_size) {
- try {
- error(" adjust size from ", Hex(phys_size),
- "->", Hex(mmio_size));
- _pci_confspace.construct(_env, phys_addr, mmio_size);
- /* got memory - try again */
- break;
- } catch (Service_denied) {
- /* decrease by one bus memory size */
- mmio_size -= 0x1000UL * 32 * 8;
- }
- }
- if (mmio_size <= phys_size)
- /* broken machine - you're lost */
- throw;
- }
- }
- }
-
- protected:
-
- Session_component *_create_session(const char *args) override
- {
- try {
- return new (md_alloc())
- Registered(_sessions, _env, _config,
- *_pci_confspace,
- _pci_confspace_base,
- *_buses, _heap, _delayer,
- _devices_bars, args, _iommu,
- _msi_platform);
- }
- catch (Session_policy::No_policy_defined) {
- error("Invalid session request, no matching policy for ",
- "'", label_from_args(args).string(), "'");
- throw Service_denied();
- }
- }
-
- void _upgrade_session(Session_component *s, const char *args) override {
- s->upgrade_resources(session_resources_from_args(args)); }
-
- public:
-
- /**
- * Constructor
- *
- * \param ep entry point to be used for serving the PCI session
- * and PCI device interface
- * \param md_alloc meta-data allocator for allocating PCI-session
- * components and PCI-device components
- */
- Root(Env &env, Allocator &heap, Allocator &md_alloc, Attached_rom_dataspace &config,
- char const *acpi_rom, bool acpi_platform, bool msi_platform)
- :
- Root_component(&env.ep().rpc_ep(), &md_alloc),
- _env(env),
- _heap(heap),
- _config(config),
- _msi_platform(msi_platform)
- {
- try {
- _parse_report_rom(env, acpi_rom, acpi_platform);
- } catch (...) {
- error("ACPI report parsing error.");
- throw;
- }
-
- if (Platform::Bridge::root_bridge_bdf < Platform::Bridge::INVALID_ROOT_BRIDGE) {
- Device_config config(Pci::Bdf::from_value(Platform::Bridge::root_bridge_bdf));
- log("Root bridge: ", config);
- } else {
- warning("Root bridge: unknown");
- }
-
- _construct_buses();
-
- generate_pci_report();
- }
-
- void generate_pci_report()
- {
- if (!_pci_reported && _config.valid() &&
- _config.xml().has_sub_node("report") &&
- _config.xml().sub_node("report").attribute_value("pci", false)) {
-
- _pci_reported = true;
-
- _pci_reporter.construct(_env, "pci", "pci");
-
- Config_access config_access(*_pci_confspace);
- Device_config config;
-
- _pci_reporter->generate([&] (Reporter::Xml_generator &xml) {
- int bus = 0, device = 0, function = -1;
-
- /* iterate over pci devices */
- while (true) {
- function += 1;
- if (!(*_buses).find_next(bus, device, function, &config,
- &config_access))
- return;
-
- bus = config.bdf().bus;
- device = config.bdf().device;
- function = config.bdf().function;
-
- xml.node("device", [&] () {
- xml.attribute("bus" , String<5>(Hex(bus)));
- xml.attribute("device" , String<5>(Hex(device)));
- xml.attribute("function" , String<5>(Hex(function)));
- xml.attribute("vendor_id" , String<8>(Hex(config.vendor_id())));
- xml.attribute("device_id" , String<8>(Hex(config.device_id())));
- xml.attribute("class_code", String<12>(Hex(config.class_code())));
- xml.attribute("bridge" , config.pci_bridge() ? "yes" : "no");
-
- enum { PCI_STATUS = 0x6, PCI_CAP_OFFSET = 0x34 };
-
- try {
- config.read(config_access, PCI_STATUS, Platform::Device::ACCESS_16BIT);
-
- uint8_t cap = config.read(config_access,
- PCI_CAP_OFFSET,
- Platform::Device::ACCESS_8BIT);
-
- for (uint16_t val = 0; cap; cap = val >> 8) {
- val = config.read(config_access, cap, Platform::Device::ACCESS_16BIT);
- xml.attribute("cap", String<8>(Hex(val & 0xff)));
- }
- } catch (...) {
- xml.attribute("cap", "failed to read");
- }
- });
- }
- });
- }
- }
-
- bool config_with_policy() const {
- return _config.valid() && _config.xml().has_sub_node("policy"); }
-
- void config_update()
- {
- _sessions.for_each([&](auto &session) {
- if (!session.policy_valid())
- destroy(session);
- });
- }
-};
-
-#endif /* _PCI_SESSION_COMPONENT_H_ */
diff --git a/repos/os/src/drivers/platform/legacy/x86/session.cc b/repos/os/src/drivers/platform/legacy/x86/session.cc
deleted file mode 100644
index c08901dbbd..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/session.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * \brief platform session component
- * \author Norman Feske
- * \date 2008-01-28
- */
-
-/*
- * Copyright (C) 2008-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include "pci_session_component.h"
-#include "pci_bridge.h"
-
-
-/* set during ACPI ROM parsing to valid value */
-unsigned Platform::Bridge::root_bridge_bdf = INVALID_ROOT_BRIDGE;
-
-
-static Genode::List *bridges()
-{
- static Genode::List list;
- return &list;
-}
-
-
-unsigned short Platform::bridge_bdf(unsigned char bus)
-{
- for (Platform::Bridge *bridge = bridges()->first(); bridge;
- bridge = bridge->next())
- {
- if (bridge->part_of(bus))
- return bridge->bdf();
- }
- /* XXX Ideally, this case should never happen */
- return Platform::Bridge::root_bridge_bdf;
-}
-
-void Platform::Pci_buses::_scan_bus(Config_access &config_access,
- Allocator &heap,
- Device_bars_pool &devices_bars,
- unsigned char bus,
- Xml_node const &config_node)
-{
- for (unsigned dev = 0; dev < Device_config::MAX_DEVICES; ++dev) {
- for (unsigned fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
-
- Pci::Bdf const bdf { .bus = bus, .device = dev, .function = fun };
-
- /* read config space */
- Device_config config(bdf, &config_access);
-
- if (!config.valid())
- continue;
-
- /* apply fixups to BAR memory resources */
- config.for_each_resource([&] (int const id, Platform::Pci::Resource const res)
- {
- uint64_t remap_address = 0;
- config_node.for_each_sub_node("pci-fixup", [&] (Xml_node node) {
- if (!node.has_attribute("bus")
- || !node.has_attribute("device")
- || !node.has_attribute("function")
- || !(bdf == Pci::Bdf::from_xml(node)))
- return;
-
- node.for_each_sub_node("bar", [&] (Xml_node node) {
- if (node.attribute_value("id", (long)-1) == id)
- remap_address = node.attribute_value("address", (uint64_t)0);
- });
- });
-
- if (remap_address) {
- config.remap_resource(config_access, id, 0x4017002000);
- return;
- }
-
- if (!res.base() && res.mem())
- warning(bdf, " BAR", id, " ", res,
- " has invalid base address - consider ");
- });
-
- /* remember Device BARs required after power off and/or reset */
- Device_config::Device_bars bars = config.save_bars();
- if (!bars.all_invalid())
- new (heap) Registered(devices_bars, bars);
-
- /*
- * Switch off PCI bus master DMA for some classes of devices,
- * which caused trouble.
- * Some devices are enabled by BIOS/UEFI or/and bootloaders and
- * aren't switch off when handing over to the kernel and Genode.
- * By disabling bus master DMA they should stop to issue DMA
- * operations and IRQs. IRQs are problematic, if it is a shared
- * IRQ - e.g. Ethernet and graphic card share a GSI IRQ. If the
- * graphic card driver is started without a Ethernet driver,
- * the graphic card may ack all IRQs. We may end up in a endless
- * IRQ/ACK loop, since no Ethernet driver acknowledge/disable IRQ
- * generation on the Ethernet device.
- *
- * Switching off PCI bus master DMA in general is a bad idea,
- * since some device classes require a explicit handover protocol
- * between BIOS/UEFI and device, e.g. USB. Violating such protocols
- * lead to hard hangs on some machines.
- */
- if (config.class_code() >> 8) {
- uint16_t classcode = config.class_code() >> 16;
- uint16_t subclass = (config.class_code() >> 8) & 0xff;
-
- if ((classcode == 0x2 && subclass == 0x00) /* ETHERNET */) {
- config.disable_bus_master_dma(config_access);
- }
- }
-
- /*
- * There is at least one device on the current bus, so
- * we mark it as valid.
- */
- if (!_valid.get(bus, 1))
- _valid.set(bus, 1);
-
- /* scan behind bridge */
- if (config.pci_bridge()) {
- /* PCI bridge spec 3.2.5.3, 3.2.5.4 */
- unsigned char sec_bus = config.read(config_access, 0x19,
- Device::ACCESS_8BIT);
- unsigned char sub_bus = config.read(config_access, 0x20,
- Device::ACCESS_8BIT);
-
- bridges()->insert(new (heap) Bridge(bus, dev, fun, sec_bus,
- sub_bus));
-
- uint16_t cmd = config.read(config_access,
- Device_config::PCI_CMD_REG,
- Platform::Device::ACCESS_16BIT);
-
- const bool enabled = (cmd & Device_config::PCI_CMD_MASK)
- == Device_config::PCI_CMD_MASK;
-
- if (!enabled) {
- config.write(config_access, Device_config::PCI_CMD_REG,
- cmd | Device_config::PCI_CMD_MASK,
- Platform::Device::ACCESS_16BIT);
- }
-
- log(config, " - bridge ",
- Hex(sec_bus, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
- ":00.0", !enabled ? " enabled" : "");
-
- _scan_bus(config_access, heap, devices_bars, sec_bus, config_node);
- }
- }
- }
-}
-
-
-using Platform::Session_component;
-
-Genode::Bit_array Session_component::bdf_in_use;
diff --git a/repos/os/src/drivers/platform/legacy/x86/target.mk b/repos/os/src/drivers/platform/legacy/x86/target.mk
deleted file mode 100644
index d9ab3786c1..0000000000
--- a/repos/os/src/drivers/platform/legacy/x86/target.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-TARGET = legacy_pc_platform_drv
-REQUIRES = x86
-SRC_CC = main.cc irq.cc pci_device.cc nonpci_devices.cc session.cc
-SRC_CC += device_pd.cc acpi_devices.cc
-LIBS = base
-
-INC_DIR = $(PRG_DIR)
-
-CC_CXX_WARN_STRICT_CONVERSION =